if error_code != 0:
raise DashboardException(
f'Failed to get info for subvolume group {group_name}: {err}'
+
)
- return json.loads(out)
+ group = 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['path'] = out
+ return group
def create(self, vol_name: str, group_name: str, **kwargs):
error_code, _, err = mgr.remote('volumes', '_cmd_fs_subvolumegroup_create', None, {
import { FinishedTask } from '~/app/shared/models/finished-task';
import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
import { CephfsSubvolumeGroup } from '~/app/shared/models/cephfs-subvolume-group.model';
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import _ from 'lodash';
@Component({
selector: 'cd-cephfs-subvolume-group',
subvolumeGroup$: Observable<CephfsSubvolumeGroup[]>;
subject = new BehaviorSubject<CephfsSubvolumeGroup[]>([]);
+ modalRef: NgbModalRef;
+
constructor(
private cephfsSubvolumeGroup: CephfsSubvolumeGroupService,
private actionLabels: ActionLabelsI18n,
icon: Icons.edit,
click: () => this.openModal(true)
},
+ {
+ name: this.actionLabels.NFS_EXPORT,
+ permission: 'create',
+ icon: Icons.nfsExport,
+ routerLink: () => ['/cephfs/nfs/create', this.fsName, this.selection?.first()?.name],
+ disable: () => !this.selection.hasSingleSelection
+ },
{
name: this.actionLabels.REMOVE,
permission: 'delete',
</div>
<div class="form-group row"
- *ngIf="storageBackend === 'CEPH'">
+ *ngIf="storageBackend === 'CEPH' && nfsForm.getValue('fsal').fs_name">
<label class="cd-col-form-label"
for="subvolume_group"
i18n>Subvolume Group</label>
i18n>-- Select the CephFS subvolume group --</option>
<option *ngFor="let subvol_grp of allsubvolgrps"
[value]="subvol_grp.name">{{ subvol_grp.name }}</option>
+ <option [value]="defaultSubVolGroup">{{ defaultSubVolGroup }}</option>
</select>
</div>
</div>
<div class="form-group row"
- *ngIf="storageBackend === 'CEPH'">
+ *ngIf="storageBackend === 'CEPH' && nfsForm.getValue('fsal').fs_name">
<label class="cd-col-form-label"
for="subvolume"
i18n>Subvolume</label>
formControlName="subvolume"
name="subvolume"
id="subvolume"
- (change)="getPath()">
+ (change)="setSubVolPath()">
<option *ngIf="allsubvols === null"
value=""
i18n>Loading...</option>
allsubvolgrps: any[] = [];
allsubvols: any[] = [];
- fsPath: string = null;
+
+ selectedFsName: string = '';
+ selectedSubvolGroup: string = '';
+ selectedSubvol: string = '';
+ defaultSubVolGroup = '_nogroup';
pathDataSource = (text$: Observable<string>) => {
return text$.pipe(
this.nfsForm.get('cluster_id').disable();
} else {
this.action = this.actionLabels.CREATE;
+ this.route.params.subscribe(
+ (params: { fs_name: string; subvolume_group: string; subvolume?: string }) => {
+ this.selectedFsName = params.fs_name;
+ this.selectedSubvolGroup = params.subvolume_group;
+ if (params.subvolume) this.selectedSubvol = params.subvolume;
+ }
+ );
+
this.getData(promises);
}
}
this.getSubVolGrp(fs_name);
}
- getSubVol() {
- this.getPath();
+ async getSubVol() {
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) => {
+ await this.setSubVolGrpPath();
+
+ (subvolgrp === this.defaultSubVolGroup
+ ? this.subvolService.get(fs_name)
+ : 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.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;
- }
+ setSubVolGrpPath(): Promise<void> {
+ return new Promise<void>((resolve, reject) => {
+ const subvolGroup = this.nfsForm.getValue('subvolume_group');
+ const fs_name = this.nfsForm.getValue('fsal').fs_name;
+
+ if (subvolGroup === this.defaultSubVolGroup) {
+ this.updatePath('/volumes/' + this.defaultSubVolGroup);
+ resolve();
+ } else {
+ this.subvolgrpService
+ .info(fs_name, subvolGroup)
+ .pipe(map((data) => data['path']))
+ .subscribe(
+ (path) => {
+ this.updatePath(path);
+ resolve();
+ },
+ (error) => reject(error)
+ );
+ }
+ });
}
- getPath() {
- const subvol = this.nfsForm.getValue('subvolume');
- if (subvol === '') {
+ setSubVolPath(): Promise<void> {
+ return new Promise<void>((resolve, reject) => {
+ const subvol = this.nfsForm.getValue('subvolume');
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
+ const fs_name = this.nfsForm.getValue('fsal').fs_name;
+
+ this.subvolService
+ .info(fs_name, subvol, subvolGroup === this.defaultSubVolGroup ? '' : subvolGroup)
+ .pipe(map((data) => data['path']))
+ .subscribe(
+ (path) => {
+ this.updatePath(path);
+ resolve();
+ },
+ (error) => reject(error)
+ );
});
+ }
+ updatePath(path: string) {
+ this.nfsForm.patchValue({ path: path });
this.pathChangeHandler();
}
}
}
+ resolveRouteParams() {
+ if (!_.isEmpty(this.selectedFsName)) {
+ this.nfsForm.patchValue({
+ fsal: {
+ fs_name: this.selectedFsName
+ }
+ });
+ this.volumeChangeHandler();
+ }
+ if (!_.isEmpty(this.selectedSubvolGroup)) {
+ this.nfsForm.patchValue({
+ subvolume_group: this.selectedSubvolGroup
+ });
+ this.getSubVol();
+ }
+ if (!_.isEmpty(this.selectedSubvol)) {
+ this.nfsForm.patchValue({
+ subvolume: this.selectedSubvol
+ });
+ this.setSubVolPath();
+ }
+ }
+
resolveFilesystems(filesystems: any[]) {
this.allFsNames = filesystems;
+ if (!this.isEdit) {
+ this.resolveRouteParams();
+ }
}
fsalChangeHandler() {