From a962873a40816287f6582d1efe4b24d11eeeeb0a Mon Sep 17 00:00:00 2001 From: Avan Thakkar Date: Thu, 27 Jun 2024 15:36:42 +0530 Subject: [PATCH] mgr/dashboard: nfs export enhancement for CEPHFS Fixes: https://tracker.ceph.com/issues/66718 Signed-off-by: Avan Thakkar (cherry picked from commit 69a45db9c3cc9ed4ac36e7f2d6db78bd7940530b) --- .../mgr/dashboard/controllers/cephfs.py | 9 +++ .../ceph/nfs/nfs-form/nfs-form.component.html | 54 +++++++++++++++- .../nfs/nfs-form/nfs-form.component.spec.ts | 4 +- .../ceph/nfs/nfs-form/nfs-form.component.ts | 63 ++++++++++++++++--- 4 files changed, 121 insertions(+), 9 deletions(-) diff --git a/src/pybind/mgr/dashboard/controllers/cephfs.py b/src/pybind/mgr/dashboard/controllers/cephfs.py index fcd87833f85..7183808e19f 100644 --- a/src/pybind/mgr/dashboard/controllers/cephfs.py +++ b/src/pybind/mgr/dashboard/controllers/cephfs.py @@ -826,6 +826,15 @@ class CephFSSubvolumeGroups(RESTController): f'Failed to get info for subvolume group {group["name"]}: {err}' ) group['info'] = json.loads(out) + + error_code, out, err = mgr.remote('volumes', '_cmd_fs_subvolumegroup_getpath', + None, {'vol_name': vol_name, + 'group_name': group['name']}) + if error_code != 0: + raise DashboardException( + f'Failed to get path for subvolume group {group["name"]}: {err}' + ) + group['info']['path'] = out return subvolume_groups @RESTController.Resource('GET') diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html index ae427886f0e..01350b4def4 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html @@ -57,7 +57,7 @@ formControlName="fs_name" name="fs_name" id="fs_name" - (change)="pathChangeHandler()"> + (change)="volumeChangeHandler()"> @@ -112,6 +112,58 @@ +
+ +
+ +
+
+ +
+ +
+ +
+
+
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.spec.ts index e6fc6e8ddff..7f88c648684 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.spec.ts @@ -91,7 +91,7 @@ describe('NfsFormComponent', () => { access_type: 'RW', clients: [], cluster_id: 'mynfs', - fsal: { fs_name: 'a', name: 'CEPH' }, + fsal: { fs_name: '', name: 'CEPH' }, path: '/', protocolNfsv4: true, protocolNfsv3: true, @@ -99,6 +99,8 @@ describe('NfsFormComponent', () => { sec_label_xattr: 'security.selinux', security_label: false, squash: 'no_root_squash', + subvolume: '', + subvolume_group: '', transportTCP: true, transportUDP: true }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts index 98ef5c85914..f43067f231d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts @@ -29,6 +29,8 @@ import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service'; import { NfsFormClientComponent } from '../nfs-form-client/nfs-form-client.component'; import { getFsalFromRoute, getPathfromFsal } from '../utils'; +import { CephfsSubvolumeService } from '~/app/shared/api/cephfs-subvolume.service'; +import { CephfsSubvolumeGroupService } from '~/app/shared/api/cephfs-subvolume-group.service'; @Component({ selector: 'cd-nfs-form', @@ -63,6 +65,10 @@ export class NfsFormComponent extends CdForm implements OnInit { action: string; resource: string; + allsubvolgrps: any[] = []; + allsubvols: any[] = []; + fsPath: string = null; + pathDataSource = (text$: Observable) => { return text$.pipe( debounceTime(200), @@ -83,6 +89,8 @@ export class NfsFormComponent extends CdForm implements OnInit { constructor( private authStorageService: AuthStorageService, private nfsService: NfsService, + private subvolService: CephfsSubvolumeService, + private subvolgrpService: CephfsSubvolumeGroupService, private route: ActivatedRoute, private router: Router, private rgwBucketService: RgwBucketService, @@ -139,6 +147,49 @@ export class NfsFormComponent extends CdForm implements OnInit { }); } + volumeChangeHandler() { + this.pathChangeHandler(); + const fs_name = this.nfsForm.getValue('fsal').fs_name; + this.getSubVolGrp(fs_name); + } + + getSubVol() { + this.getPath(); + const fs_name = this.nfsForm.getValue('fsal').fs_name; + const subvolgrp = this.nfsForm.getValue('subvolume_group'); + return this.subvolService.get(fs_name, subvolgrp).subscribe((data: any) => { + this.allsubvols = data; + }); + } + + getSubVolGrp(fs_name: string) { + return this.subvolgrpService.get(fs_name).subscribe((data: any) => { + this.allsubvolgrps = data; + }); + } + + getFsPath(volList: any[], value: string) { + const match = volList.find((vol) => vol.name === value); + if (match) { + return match.info.path; + } + } + + getPath() { + const subvol = this.nfsForm.getValue('subvolume'); + if (subvol === '') { + const subvolGroup = this.nfsForm.getValue('subvolume_group'); + this.fsPath = this.getFsPath(this.allsubvolgrps, subvolGroup); + } else { + this.fsPath = this.getFsPath(this.allsubvols, subvol); + } + this.nfsForm.patchValue({ + path: this.fsPath + }); + + this.pathChangeHandler(); + } + createForm() { this.nfsForm = new CdFormGroup({ cluster_id: new UntypedFormControl('', { @@ -156,6 +207,8 @@ export class NfsFormComponent extends CdForm implements OnInit { ] }) }), + subvolume_group: new UntypedFormControl(''), + subvolume: new UntypedFormControl(''), path: new UntypedFormControl('/', { validators: [Validators.required] }), @@ -266,13 +319,6 @@ export class NfsFormComponent extends CdForm implements OnInit { resolveFilesystems(filesystems: any[]) { this.allFsNames = filesystems; - if (!this.isEdit && filesystems.length > 0) { - this.nfsForm.patchValue({ - fsal: { - fs_name: filesystems[0].name - } - }); - } } resolveRealms(realms: string[]) { @@ -439,6 +485,9 @@ export class NfsFormComponent extends CdForm implements OnInit { delete requestModel.fsal.fs_name; } + delete requestModel.subvolume; + delete requestModel.subvolume_group; + requestModel.protocols = []; if (requestModel.protocolNfsv3) { requestModel.protocols.push(3); -- 2.39.5