]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
5ffb29bdce80da76f913a1e4287d3308a01afbd9
[ceph.git] /
1 import { Component, OnInit } from '@angular/core';
2 import { FormControl, Validators } from '@angular/forms';
3 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
4 import { CephfsSubvolumeService } from '~/app/shared/api/cephfs-subvolume.service';
5 import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
6 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
7 import { FinishedTask } from '~/app/shared/models/finished-task';
8 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
9 import { Pool } from '../../pool/pool';
10 import { FormatterService } from '~/app/shared/services/formatter.service';
11 import { CdTableColumn } from '~/app/shared/models/cd-table-column';
12 import _ from 'lodash';
13 import { CdValidators } from '~/app/shared/forms/cd-validators';
14 import { CephfsSubvolumeInfo } from '~/app/shared/models/cephfs-subvolume.model';
15 import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
16 import { OctalToHumanReadablePipe } from '~/app/shared/pipes/octal-to-human-readable.pipe';
17 import { CdForm } from '~/app/shared/forms/cd-form';
18
19 @Component({
20   selector: 'cd-cephfs-subvolume-form',
21   templateUrl: './cephfs-subvolume-form.component.html',
22   styleUrls: ['./cephfs-subvolume-form.component.scss']
23 })
24 export class CephfsSubvolumeFormComponent extends CdForm implements OnInit {
25   fsName: string;
26   subVolumeName: string;
27   pools: Pool[];
28   isEdit = false;
29
30   subvolumeForm: CdFormGroup;
31
32   action: string;
33   resource: string;
34
35   dataPools: Pool[];
36
37   columns: CdTableColumn[];
38   scopePermissions: Array<any> = [];
39   initialMode = {
40     owner: ['read', 'write', 'execute'],
41     group: ['read', 'execute'],
42     others: ['read', 'execute']
43   };
44   scopes: string[] = ['owner', 'group', 'others'];
45
46   constructor(
47     public activeModal: NgbActiveModal,
48     private actionLabels: ActionLabelsI18n,
49     private taskWrapper: TaskWrapperService,
50     private cephFsSubvolumeService: CephfsSubvolumeService,
51     private formatter: FormatterService,
52     private dimlessBinary: DimlessBinaryPipe,
53     private octalToHumanReadable: OctalToHumanReadablePipe
54   ) {
55     super();
56     this.resource = $localize`Subvolume`;
57   }
58
59   ngOnInit(): void {
60     this.action = this.actionLabels.CREATE;
61     this.columns = [
62       {
63         prop: 'scope',
64         name: $localize`All`,
65         flexGrow: 0.5
66       },
67       {
68         prop: 'read',
69         name: $localize`Read`,
70         flexGrow: 0.5,
71         cellClass: 'text-center'
72       },
73       {
74         prop: 'write',
75         name: $localize`Write`,
76         flexGrow: 0.5,
77         cellClass: 'text-center'
78       },
79       {
80         prop: 'execute',
81         name: $localize`Execute`,
82         flexGrow: 0.5,
83         cellClass: 'text-center'
84       }
85     ];
86
87     this.dataPools = this.pools.filter((pool) => pool.type === 'data');
88     this.createForm();
89
90     this.isEdit ? this.populateForm() : this.loadingReady();
91   }
92
93   createForm() {
94     this.subvolumeForm = new CdFormGroup({
95       volumeName: new FormControl({ value: this.fsName, disabled: true }),
96       subvolumeName: new FormControl('', {
97         validators: [Validators.required],
98         asyncValidators: [
99           CdValidators.unique(
100             this.cephFsSubvolumeService.exists,
101             this.cephFsSubvolumeService,
102             null,
103             null,
104             this.fsName
105           )
106         ]
107       }),
108       pool: new FormControl(this.dataPools[0]?.pool, {
109         validators: [Validators.required]
110       }),
111       size: new FormControl(null, {
112         updateOn: 'blur'
113       }),
114       uid: new FormControl(null),
115       gid: new FormControl(null),
116       mode: new FormControl({}),
117       isolatedNamespace: new FormControl(false)
118     });
119   }
120
121   populateForm() {
122     this.action = this.actionLabels.EDIT;
123     this.cephFsSubvolumeService
124       .info(this.fsName, this.subVolumeName)
125       .subscribe((resp: CephfsSubvolumeInfo) => {
126         // Disabled these fields since its not editable
127         this.subvolumeForm.get('subvolumeName').disable();
128         this.subvolumeForm.get('pool').disable();
129         this.subvolumeForm.get('uid').disable();
130         this.subvolumeForm.get('gid').disable();
131
132         this.subvolumeForm.get('isolatedNamespace').disable();
133         this.subvolumeForm.get('subvolumeName').setValue(this.subVolumeName);
134         if (resp.bytes_quota !== 'infinite') {
135           this.subvolumeForm.get('size').setValue(this.dimlessBinary.transform(resp.bytes_quota));
136         }
137         this.subvolumeForm.get('uid').setValue(resp.uid);
138         this.subvolumeForm.get('gid').setValue(resp.gid);
139         this.subvolumeForm.get('isolatedNamespace').setValue(resp.pool_namespace);
140         this.initialMode = this.octalToHumanReadable.transform(resp.mode, true);
141
142         this.loadingReady();
143       });
144   }
145
146   submit() {
147     const subVolumeName = this.subvolumeForm.getValue('subvolumeName');
148     const pool = this.subvolumeForm.getValue('pool');
149     const size = this.formatter.toBytes(this.subvolumeForm.getValue('size')) || 0;
150     const uid = this.subvolumeForm.getValue('uid');
151     const gid = this.subvolumeForm.getValue('gid');
152     const mode = this.formatter.toOctalPermission(this.subvolumeForm.getValue('mode'));
153     const isolatedNamespace = this.subvolumeForm.getValue('isolatedNamespace');
154
155     if (this.isEdit) {
156       const editSize = size === 0 ? 'infinite' : size;
157       this.taskWrapper
158         .wrapTaskAroundCall({
159           task: new FinishedTask('cephfs/subvolume/' + URLVerbs.EDIT, {
160             subVolumeName: subVolumeName
161           }),
162           call: this.cephFsSubvolumeService.update(this.fsName, subVolumeName, String(editSize))
163         })
164         .subscribe({
165           error: () => {
166             this.subvolumeForm.setErrors({ cdSubmitButton: true });
167           },
168           complete: () => {
169             this.activeModal.close();
170           }
171         });
172     } else {
173       this.taskWrapper
174         .wrapTaskAroundCall({
175           task: new FinishedTask('cephfs/subvolume/' + URLVerbs.CREATE, {
176             subVolumeName: subVolumeName
177           }),
178           call: this.cephFsSubvolumeService.create(
179             this.fsName,
180             subVolumeName,
181             pool,
182             String(size),
183             uid,
184             gid,
185             mode,
186             isolatedNamespace
187           )
188         })
189         .subscribe({
190           error: () => {
191             this.subvolumeForm.setErrors({ cdSubmitButton: true });
192           },
193           complete: () => {
194             this.activeModal.close();
195           }
196         });
197     }
198   }
199 }