@@ -411,6 +411,21 @@ def _nfs_export_apply(self, cluster, exports, raise_on_error=False):
411411 stdin = json .dumps (exports ),
412412 stdout = StringIO (), stderr = StringIO ())
413413
414+ def update_export (self , cluster_id , path , pseudo , fs_name ):
415+ self .ctx .cluster .run (args = ['ceph' , 'nfs' , 'export' , 'apply' ,
416+ cluster_id , '-i' , '-' ],
417+ stdin = json .dumps ({
418+ "path" : path ,
419+ "pseudo" : pseudo ,
420+ "squash" : "none" ,
421+ "access_type" : "rw" ,
422+ "protocols" : [4 ],
423+ "fsal" : {
424+ "name" : "CEPH" ,
425+ "fs_name" : fs_name
426+ }
427+ }))
428+
414429 def test_create_and_delete_cluster (self ):
415430 '''
416431 Test successful creation and deletion of the nfs cluster.
@@ -1138,3 +1153,61 @@ def test_pseudo_path_in_json_response_when_updating_exports_failed(self):
11381153 finally :
11391154 self ._delete_cluster_with_fs (self .fs_name , mnt_pt )
11401155 self .ctx .cluster .run (args = ['rm' , '-rf' , f'{ mnt_pt } ' ])
1156+
1157+ def test_cephfs_export_update_with_nonexistent_dir (self ):
1158+ """
1159+ Test that invalid path is not allowed while updating a CephFS
1160+ export.
1161+ """
1162+ self ._create_cluster_with_fs (self .fs_name )
1163+ self ._create_export (export_id = 1 )
1164+
1165+ try :
1166+ self .update_export (self .cluster_id , "/not_existent_dir" ,
1167+ self .pseudo_path , self .fs_name )
1168+ except CommandFailedError as e :
1169+ if e .exitstatus != errno .ENOENT :
1170+ raise
1171+
1172+ self ._delete_export ()
1173+ self ._delete_cluster_with_fs (self .fs_name )
1174+
1175+ def test_cephfs_export_update_at_non_dir_path (self ):
1176+ """
1177+ Test that non-directory path are not allowed while updating a CephFS
1178+ export.
1179+ """
1180+ mnt_pt = '/mnt'
1181+ preserve_mode = self ._sys_cmd (['stat' , '-c' , '%a' , mnt_pt ])
1182+ self ._create_cluster_with_fs (self .fs_name , mnt_pt )
1183+ try :
1184+ self .ctx .cluster .run (args = ['touch' , f'{ mnt_pt } /testfile' ])
1185+ self ._create_export (export_id = 1 )
1186+
1187+ # test at a file path
1188+ try :
1189+ self .update_export (self .cluster_id , "/testfile" ,
1190+ self .pseudo_path , self .fs_name )
1191+ except CommandFailedError as e :
1192+ if e .exitstatus != errno .ENOTDIR :
1193+ raise
1194+
1195+ # test at a symlink path
1196+ self .ctx .cluster .run (args = ['mkdir' , f'{ mnt_pt } /testdir' ])
1197+ self .ctx .cluster .run (args = ['ln' , '-s' , f'{ mnt_pt } /testdir' ,
1198+ f'{ mnt_pt } /testdir_symlink' ])
1199+ try :
1200+ self .update_export (self .cluster_id , "/testdir_symlink" ,
1201+ self .pseudo_path , self .fs_name )
1202+ except CommandFailedError as e :
1203+ if e .exitstatus != errno .ENOTDIR :
1204+ raise
1205+
1206+ # verify the path wasn't changed
1207+ export = json .loads (self ._nfs_cmd ("export" , "ls" ,
1208+ self .cluster_id , "--detailed" ))
1209+ self .assertEqual (export [0 ]["pseudo" ], "/cephfs" )
1210+
1211+ finally :
1212+ self .ctx .cluster .run (args = ['rm' , '-rf' , f'{ mnt_pt } /*' ])
1213+ self ._delete_cluster_with_fs (self .fs_name , mnt_pt , preserve_mode )
0 commit comments