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