]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.html
import ceph quincy 17.2.6
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / ceph / block / rbd-form / rbd-form.component.html
CommitLineData
f67539c2
TL
1<div class="cd-col-form"
2 *cdFormLoading="loading">
11fdf7f2 3 <form name="rbdForm"
11fdf7f2
TL
4 #formDir="ngForm"
5 [formGroup]="rbdForm"
6 novalidate>
9f95a23c 7 <div class="card">
a4b75251 8 <div i18n="form title"
9f95a23c
TL
9 class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
10 <div class="card-body">
11fdf7f2
TL
11
12 <!-- Parent -->
9f95a23c 13 <div class="form-group row"
11fdf7f2
TL
14 *ngIf="rbdForm.getValue('parent')">
15 <label i18n
9f95a23c 16 class="cd-col-form-label"
11fdf7f2 17 for="name">{{ action | titlecase }} from</label>
9f95a23c 18 <div class="cd-col-form-input">
11fdf7f2
TL
19 <input class="form-control"
20 type="text"
21 id="parent"
22 name="parent"
23 formControlName="parent">
24 <hr>
25 </div>
26 </div>
27
28 <!-- Name -->
9f95a23c
TL
29 <div class="form-group row">
30 <label class="cd-col-form-label required"
31 for="name"
32 i18n>Name</label>
33 <div class="cd-col-form-input">
11fdf7f2
TL
34 <input class="form-control"
35 type="text"
36 placeholder="Name..."
37 id="name"
38 name="name"
39 formControlName="name"
40 autofocus>
9f95a23c 41 <span class="invalid-feedback"
11fdf7f2
TL
42 *ngIf="rbdForm.showError('name', formDir, 'required')">
43 <ng-container i18n>This field is required.</ng-container>
44 </span>
9f95a23c 45 <span class="invalid-feedback"
11fdf7f2
TL
46 *ngIf="rbdForm.showError('name', formDir, 'pattern')">
47 <ng-container i18n>'/' and '@' are not allowed.</ng-container>
48 </span>
49 </div>
50 </div>
51
52 <!-- Pool -->
9f95a23c 53 <div class="form-group row"
11fdf7f2 54 (change)="onPoolChange($event.target.value)">
9f95a23c
TL
55 <label class="cd-col-form-label"
56 [ngClass]="{'required': mode !== 'editing'}"
57 for="pool"
58 i18n>Pool</label>
59 <div class="cd-col-form-input">
11fdf7f2
TL
60 <input class="form-control"
61 type="text"
62 placeholder="Pool name..."
63 id="pool"
64 name="pool"
65 formControlName="pool"
66 *ngIf="mode === 'editing' || !poolPermission.read">
67 <select id="pool"
68 name="pool"
39ae355f 69 class="form-select"
11fdf7f2 70 formControlName="pool"
2a845540
TL
71 *ngIf="mode !== 'editing' && poolPermission.read"
72 (change)="setPoolMirrorMode()">
11fdf7f2
TL
73 <option *ngIf="pools === null"
74 [ngValue]="null"
75 i18n>Loading...</option>
76 <option *ngIf="pools !== null && pools.length === 0"
77 [ngValue]="null"
78 i18n>-- No rbd pools available --</option>
79 <option *ngIf="pools !== null && pools.length > 0"
80 [ngValue]="null"
81 i18n>-- Select a pool --</option>
82 <option *ngFor="let pool of pools"
83 [value]="pool.pool_name">{{ pool.pool_name }}</option>
84 </select>
85 <span *ngIf="rbdForm.showError('pool', formDir, 'required')"
9f95a23c 86 class="invalid-feedback"
11fdf7f2
TL
87 i18n>This field is required.</span>
88 </div>
89 </div>
90
9f95a23c
TL
91 <!-- Namespace -->
92 <div class="form-group row"
93 *ngIf="mode !== 'editing' && rbdForm.getValue('pool') && namespaces === null">
94 <div class="cd-col-form-offset">
95 <i [ngClass]="[icons.spinner, icons.spin]"></i>
96 </div>
97 </div>
98 <div class="form-group row"
99 *ngIf="(mode === 'editing' && rbdForm.getValue('namespace')) || mode !== 'editing' && (namespaces && namespaces.length > 0 || !poolPermission.read)">
100 <label class="cd-col-form-label"
101 for="pool">
102 Namespace
103 </label>
104 <div class="cd-col-form-input">
105 <input class="form-control"
106 type="text"
107 placeholder="Namespace..."
108 id="namespace"
109 name="namespace"
110 formControlName="namespace"
111 *ngIf="mode === 'editing' || !poolPermission.read">
112 <select id="namespace"
113 name="namespace"
39ae355f 114 class="form-select"
9f95a23c
TL
115 formControlName="namespace"
116 *ngIf="mode !== 'editing' && poolPermission.read">
117 <option *ngIf="pools === null"
118 [ngValue]="null"
119 i18n>Loading...</option>
120 <option *ngIf="pools !== null && pools.length === 0"
121 [ngValue]="null"
122 i18n>-- No namespaces available --</option>
123 <option *ngIf="pools !== null && pools.length > 0"
124 [ngValue]="null"
125 i18n>-- Select a namespace --</option>
126 <option *ngFor="let namespace of namespaces"
127 [value]="namespace">{{ namespace }}</option>
128 </select>
129 </div>
130 </div>
131
11fdf7f2 132 <!-- Use a dedicated pool -->
9f95a23c
TL
133 <div class="form-group row">
134 <div class="cd-col-form-offset">
135 <div class="custom-control custom-checkbox">
11fdf7f2 136 <input type="checkbox"
9f95a23c 137 class="custom-control-input"
11fdf7f2
TL
138 id="useDataPool"
139 name="useDataPool"
140 formControlName="useDataPool"
141 (change)="onUseDataPoolChange()">
9f95a23c
TL
142 <label class="custom-control-label"
143 for="useDataPool"
144 i18n>Use a dedicated data pool</label>
f67539c2
TL
145 <cd-helper *ngIf="allDataPools.length <= 1">
146 <span i18n>You need more than one pool with the rbd application label use to use a dedicated data pool.</span>
147 </cd-helper>
11fdf7f2
TL
148 </div>
149 </div>
150 </div>
151
152 <!-- Data Pool -->
9f95a23c 153 <div class="form-group row"
11fdf7f2 154 *ngIf="rbdForm.getValue('useDataPool')">
9f95a23c 155 <label class="cd-col-form-label"
11fdf7f2 156 for="dataPool">
9f95a23c
TL
157 <span [ngClass]="{'required': mode !== 'editing'}"
158 i18n>Data pool</span>
11fdf7f2
TL
159 <cd-helper i18n-html
160 html="Dedicated pool that stores the object-data of the RBD.">
161 </cd-helper>
162 </label>
9f95a23c 163 <div class="cd-col-form-input">
11fdf7f2
TL
164 <input class="form-control"
165 type="text"
166 placeholder="Data pool name..."
167 id="dataPool"
168 name="dataPool"
169 formControlName="dataPool"
170 *ngIf="mode === 'editing' || !poolPermission.read">
171 <select id="dataPool"
172 name="dataPool"
39ae355f 173 class="form-select"
11fdf7f2
TL
174 formControlName="dataPool"
175 (change)="onDataPoolChange($event.target.value)"
176 *ngIf="mode !== 'editing' && poolPermission.read">
177 <option *ngIf="dataPools === null"
178 [ngValue]="null"
179 i18n>Loading...</option>
180 <option *ngIf="dataPools !== null && dataPools.length === 0"
181 [ngValue]="null"
182 i18n>-- No data pools available --</option>
183 <option *ngIf="dataPools !== null && dataPools.length > 0"
184 [ngValue]="null">-- Select a data pool --
185 </option>
186 <option *ngFor="let dataPool of dataPools"
187 [value]="dataPool.pool_name">{{ dataPool.pool_name }}</option>
188 </select>
9f95a23c 189 <span class="invalid-feedback"
11fdf7f2
TL
190 *ngIf="rbdForm.showError('dataPool', formDir, 'required')"
191 i18n>This field is required.</span>
192 </div>
193 </div>
194
195 <!-- Size -->
9f95a23c
TL
196 <div class="form-group row">
197 <label class="cd-col-form-label required"
198 for="size"
199 i18n>Size</label>
200 <div class="cd-col-form-input">
11fdf7f2
TL
201 <input id="size"
202 name="size"
203 class="form-control"
204 type="text"
205 formControlName="size"
206 i18n-placeholder
207 placeholder="e.g., 10GiB"
208 defaultUnit="GiB"
209 cdDimlessBinary>
9f95a23c 210 <span class="invalid-feedback"
11fdf7f2
TL
211 *ngIf="rbdForm.showError('size', formDir, 'required')"
212 i18n>This field is required.</span>
9f95a23c 213 <span class="invalid-feedback"
11fdf7f2
TL
214 *ngIf="rbdForm.showError('size', formDir, 'invalidSizeObject')"
215 i18n>You have to increase the size.</span>
216 </div>
217 </div>
218
219 <!-- Features -->
9f95a23c 220 <div class="form-group row"
11fdf7f2
TL
221 formGroupName="features">
222 <label i18n
9f95a23c 223 class="cd-col-form-label"
11fdf7f2 224 for="features">Features</label>
9f95a23c
TL
225 <div class="cd-col-form-input">
226 <div class="custom-control custom-checkbox"
11fdf7f2
TL
227 *ngFor="let feature of featuresList">
228 <input type="checkbox"
9f95a23c 229 class="custom-control-input"
11fdf7f2
TL
230 id="{{ feature.key }}"
231 name="{{ feature.key }}"
232 formControlName="{{ feature.key }}">
9f95a23c
TL
233 <label class="custom-control-label"
234 for="{{ feature.key }}">{{ feature.desc }}</label>
11fdf7f2
TL
235 <cd-helper *ngIf="feature.helperHtml"
236 html="{{ feature.helperHtml }}">
237 </cd-helper>
238 </div>
239 </div>
240 </div>
241
2a845540
TL
242 <!-- Mirroring -->
243 <div class="form-group row">
244 <div class="cd-col-form-offset">
245 <div class="custom-control custom-checkbox">
246 <input type="checkbox"
247 class="custom-control-input"
248 id="mirroring"
249 name="mirroring"
250 (change)="setMirrorMode()"
251 formControlName="mirroring">
252 <label class="custom-control-label"
253 for="mirroring">Mirroring</label>
254 <cd-helper *ngIf="mirroring === false && this.currentPoolName">
255 <span i18n>You need to enable a <b>mirror mode</b> in the selected pool. Please <a [routerLink]="['/block/mirroring', {outlets: {modal: ['edit', currentPoolName]}}]">click here to select a mode and enable it in this pool.</a></span>
256 </cd-helper>
257 </div>
258 <div *ngIf="mirroring">
39ae355f 259 <div class="custom-control custom-radio ms-2"
2a845540
TL
260 *ngFor="let option of mirroringOptions">
261 <input type="radio"
39ae355f 262 class="form-check-input"
2a845540
TL
263 [id]="option"
264 [value]="option"
265 name="mirroringMode"
266 (change)="setExclusiveLock()"
267 formControlName="mirroringMode"
268 [attr.disabled]="(poolMirrorMode === 'pool' && option === 'snapshot') ? true : null">
39ae355f 269 <label class="form-check-label"
2a845540
TL
270 [for]="option">{{ option | titlecase }}</label>
271 <cd-helper *ngIf="poolMirrorMode === 'pool' && option === 'snapshot'">
272 <span i18n>You need to enable <b>image mirror mode</b> in the selected pool. Please <a [routerLink]="['/block/mirroring', {outlets: {modal: ['edit', currentPoolName]}}]">click here to select a mode and enable it in this pool.</a></span>
273 </cd-helper>
274 </div>
275 </div>
276 </div>
277 </div>
278
279 <div class="form-group row"
280 *ngIf="rbdForm.getValue('mirroringMode') === 'snapshot' && mirroring">
281 <label class="cd-col-form-label"
282 i18n>Schedule Interval
283 <cd-helper i18n-html
39ae355f 284 html="Create Mirror-Snapshots automatically on a periodic basis. The interval can be specified in days, hours, or minutes using d, h, m suffix respectively. To create mirror snapshots, you must import or create and have available peers to mirror">
2a845540
TL
285 </cd-helper></label>
286 <div class="cd-col-form-input">
287 <input id="schedule"
288 name="schedule"
289 class="form-control"
290 type="text"
291 formControlName="schedule"
292 i18n-placeholder
293 placeholder="e.g., 12h or 1d or 10m"
39ae355f 294 [attr.disabled]="(peerConfigured === false) ? true : null">
2a845540
TL
295 </div>
296 </div>
297
11fdf7f2
TL
298 <!-- Advanced -->
299 <div class="row">
300 <div class="col-sm-12">
39ae355f 301 <a class="float-end margin-right-md"
9f95a23c 302 (click)="advancedEnabled = true; false"
11fdf7f2 303 *ngIf="!advancedEnabled"
9f95a23c 304 href=""
11fdf7f2
TL
305 i18n>Advanced...</a>
306 </div>
307 </div>
9f95a23c 308
11fdf7f2
TL
309 <div [hidden]="!advancedEnabled">
310
9f95a23c
TL
311 <legend class="cd-header"
312 i18n>Advanced</legend>
11fdf7f2 313
9f95a23c 314 <div class="col-md-12">
f91f0fd5
TL
315 <h4 class="cd-header"
316 i18n>Striping</h4>
11fdf7f2
TL
317
318 <!-- Object Size -->
9f95a23c 319 <div class="form-group row">
11fdf7f2 320 <label i18n
9f95a23c 321 class="cd-col-form-label"
2a845540 322 for="size">Object size<cd-helper>Objects in the Ceph Storage Cluster have a maximum configurable size (e.g., 2MB, 4MB, etc.). The object size should be large enough to accommodate many stripe units, and should be a multiple of the stripe unit.</cd-helper></label>
9f95a23c 323 <div class="cd-col-form-input">
11fdf7f2
TL
324 <select id="obj_size"
325 name="obj_size"
39ae355f 326 class="form-select"
11fdf7f2
TL
327 formControlName="obj_size">
328 <option *ngFor="let objectSize of objectSizes"
329 [value]="objectSize">{{ objectSize }}</option>
330 </select>
331 </div>
332 </div>
333
9f95a23c
TL
334 <!-- stripingUnit -->
335 <div class="form-group row">
336 <label class="cd-col-form-label"
337 [ngClass]="{'required': rbdForm.getValue('stripingCount')}"
338 for="stripingUnit"
2a845540 339 i18n>Stripe unit<cd-helper>Stripes have a configurable unit size (e.g., 64kb). The Ceph Client divides the data it will write to objects into equally sized stripe units, except for the last stripe unit. A stripe width, should be a fraction of the Object Size so that an object may contain many stripe units.</cd-helper></label>
9f95a23c 340 <div class="cd-col-form-input">
11fdf7f2
TL
341 <select id="stripingUnit"
342 name="stripingUnit"
39ae355f 343 class="form-select"
11fdf7f2
TL
344 formControlName="stripingUnit">
345 <option i18n
346 [ngValue]="null">-- Select stripe unit --</option>
347 <option *ngFor="let objectSize of objectSizes"
348 [value]="objectSize">{{ objectSize }}</option>
349 </select>
9f95a23c 350 <span class="invalid-feedback"
11fdf7f2
TL
351 *ngIf="rbdForm.showError('stripingUnit', formDir, 'required')"
352 i18n>This field is required because stripe count is defined!</span>
9f95a23c 353 <span class="invalid-feedback"
11fdf7f2
TL
354 *ngIf="rbdForm.showError('stripingUnit', formDir, 'invalidStripingUnit')"
355 i18n>Stripe unit is greater than object size.</span>
356 </div>
357 </div>
358
359 <!-- Stripe Count -->
9f95a23c
TL
360 <div class="form-group row">
361 <label class="cd-col-form-label"
362 [ngClass]="{'required': rbdForm.getValue('stripingUnit')}"
363 for="stripingCount"
2a845540 364 i18n>Stripe count<cd-helper>The Ceph Client writes a sequence of stripe units over a series of objects determined by the stripe count. The series of objects is called an object set. After the Ceph Client writes to the last object in the object set, it returns to the first object in the object set.</cd-helper></label>
9f95a23c 365 <div class="cd-col-form-input">
11fdf7f2
TL
366 <input id="stripingCount"
367 name="stripingCount"
368 formControlName="stripingCount"
369 class="form-control"
370 type="number">
9f95a23c 371 <span class="invalid-feedback"
11fdf7f2
TL
372 *ngIf="rbdForm.showError('stripingCount', formDir, 'required')"
373 i18n>This field is required because stripe unit is defined!</span>
9f95a23c 374 <span class="invalid-feedback"
11fdf7f2
TL
375 *ngIf="rbdForm.showError('stripingCount', formDir, 'min')"
376 i18n>Stripe count must be greater than 0.</span>
377 </div>
378 </div>
379 </div>
380
9f95a23c
TL
381 <cd-rbd-configuration-form [form]="rbdForm"
382 [initializeData]="initializeConfigData"
383 (changes)="getDirtyConfigurationValues = $event"></cd-rbd-configuration-form>
11fdf7f2
TL
384 </div>
385
386 </div>
9f95a23c 387 <div class="card-footer">
f67539c2
TL
388 <cd-form-button-panel (submitActionEvent)="submit()"
389 [form]="formDir"
390 [submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
391 wrappingClass="text-right"></cd-form-button-panel>
11fdf7f2
TL
392 </div>
393 </div>
394 </form>
395</div>