1 <cd-loading-panel *
ngIf=
"!(info && ecProfiles)"
2 i18n
>Loading...
</cd-loading-panel>
4 <div class=
"cd-col-form">
6 *
ngIf=
"info && ecProfiles"
11 <div i18n=
"form title|Example: Create Pool@@formTitle"
12 class=
"card-header">{{ action | titlecase }} {{ resource | upperFirst }}
</div>
14 <div class=
"card-body">
16 <div class=
"form-group row">
17 <label class=
"cd-col-form-label required"
20 <div class=
"cd-col-form-input">
27 formControlName=
"name"
29 <span class=
"invalid-feedback"
30 *
ngIf=
"form.showError('name', formDir, 'required')"
31 i18n
>This field is required!
</span>
32 <span class=
"invalid-feedback"
33 *
ngIf=
"form.showError('name', formDir, 'uniqueName')"
34 i18n
>The chosen Ceph pool name is already in use.
</span>
35 <span *
ngIf=
"form.showError('name', formDir, 'rbdPool')"
36 class=
"invalid-feedback"
37 i18n
>It's not possible to create an RBD pool with '/' in the name.
38 Please change the name or remove 'rbd' from the applications list.
</span>
39 <span *
ngIf=
"form.showError('name', formDir, 'pattern')"
40 class=
"invalid-feedback"
41 i18n
>Pool name can only contain letters, numbers, '.', '-', '_' or '/'.
</span>
45 <!-- Pool type selection -->
46 <div class=
"form-group row">
47 <label class=
"cd-col-form-label required"
49 i18n
>Pool type
</label>
50 <div class=
"cd-col-form-input">
51 <select class=
"form-control custom-select"
53 formControlName=
"poolType"
56 i18n
>-- Select a pool type --
</option>
57 <option *
ngFor=
"let poolType of data.poolTypes"
62 <span class=
"invalid-feedback"
63 *
ngIf=
"form.showError('poolType', formDir, 'required')"
64 i18n
>This field is required!
</span>
68 <div *
ngIf=
"isReplicated || isErasure">
69 <!-- PG Autoscale Mode -->
70 <div class=
"form-group row">
72 class=
"cd-col-form-label"
73 for=
"pgAutoscaleMode">PG Autoscale
</label>
74 <div class=
"cd-col-form-input">
75 <select class=
"form-control custom-select"
77 name=
"pgAutoscaleMode"
78 formControlName=
"pgAutoscaleMode">
79 <option *
ngFor=
"let mode of pgAutoscaleModes"
88 <div class=
"form-group row"
89 *
ngIf=
"form.getValue('pgAutoscaleMode') !== 'on'">
90 <label class=
"cd-col-form-label required"
92 i18n
>Placement groups
</label>
93 <div class=
"cd-col-form-input">
94 <input class=
"form-control"
97 formControlName=
"pgNum"
100 (focus)=
"externalPgChange = false"
103 <span class=
"invalid-feedback"
104 *
ngIf=
"form.showError('pgNum', formDir, 'required')"
105 i18n
>This field is required!
</span>
106 <span class=
"invalid-feedback"
107 *
ngIf=
"form.showError('pgNum', formDir, 'min')"
108 i18n
>At least one placement group is needed!
</span>
109 <span class=
"invalid-feedback"
110 *
ngIf=
"form.showError('pgNum', formDir, '34')"
111 i18n
>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.
</span>
112 <span class=
"form-text text-muted">
115 href=
"http://ceph.com/pgcalc">Calculation help
</a>
117 <span class=
"form-text text-muted"
118 *
ngIf=
"externalPgChange"
119 i18n
>The current PGs settings were calculated for you, you
120 should make sure the values suit your needs before submit.
</span>
124 <!-- Replica Size -->
125 <div class=
"form-group row"
126 *
ngIf=
"isReplicated">
127 <label class=
"cd-col-form-label required"
129 i18n
>Replicated size
</label>
130 <div class=
"cd-col-form-input">
131 <input class=
"form-control"
137 formControlName=
"size">
138 <span class=
"invalid-feedback"
139 *
ngIf=
"form.showError('size', formDir)">
140 <ul class=
"list-inline">
141 <li i18n
>Minimum: {{ getMinSize() }}
</li>
142 <li i18n
>Maximum: {{ getMaxSize() }}
</li>
145 <span class=
"invalid-feedback"
146 *
ngIf=
"form.showError('size', formDir)"
147 i18n
>The size specified is out of range. A value from
148 {{ getMinSize() }} to {{ getMaxSize() }} is valid.
</span>
153 <div class=
"form-group row"
154 *
ngIf=
"info.is_all_bluestore && isErasure">
156 class=
"cd-col-form-label">Flags
</label>
157 <div class=
"cd-col-form-input">
158 <div class=
"custom-control custom-checkbox">
159 <input type=
"checkbox"
160 class=
"custom-control-input"
162 formControlName=
"ecOverwrites">
163 <label class=
"custom-control-label"
165 i18n
>EC Overwrites
</label>
171 <!-- Applications -->
172 <div class=
"form-group row">
174 class=
"cd-col-form-label"
175 for=
"applications">Applications
</label>
176 <div class=
"cd-col-form-input">
177 <cd-select-badges id=
"applications"
178 [customBadges]=
"true"
179 [customBadgeValidators]=
"data.applications.validators"
180 [messages]=
"data.applications.messages"
181 [data]=
"data.applications.selected"
182 [options]=
"data.applications.available"
184 (selection)=
"appSelection()">
190 <div *
ngIf=
"isErasure || isReplicated">
192 <legend i18n
>CRUSH
</legend>
194 <!-- Erasure Profile select -->
195 <div class=
"form-group row"
198 class=
"cd-col-form-label"
199 for=
"erasureProfile">Erasure code profile
</label>
200 <div class=
"cd-col-form-input">
201 <div class=
"input-group">
202 <select class=
"form-control custom-select"
204 name=
"erasureProfile"
205 formControlName=
"erasureProfile">
206 <option *
ngIf=
"!ecProfiles"
208 i18n
>Loading...
</option>
209 <option *
ngIf=
"ecProfiles && ecProfiles.length === 0"
211 i18n
>-- No erasure code profile available --
</option>
212 <option *
ngIf=
"ecProfiles && ecProfiles.length > 0"
214 i18n
>-- Select an erasure code profile --
</option>
215 <option *
ngFor=
"let ecp of ecProfiles"
220 <span class=
"input-group-append">
221 <button class=
"btn btn-light"
222 [ngClass]=
"{'active': data.erasureInfo}"
225 (click)=
"data.erasureInfo = !data.erasureInfo">
226 <i [ngClass]=
"[icons.questionCircle]"
227 aria-hidden=
"true"></i>
229 <button class=
"btn btn-light"
232 (click)=
"addErasureCodeProfile()">
233 <i [ngClass]=
"[icons.add]"
234 aria-hidden=
"true"></i>
236 <button class=
"btn btn-light"
239 (click)=
"deleteErasureCodeProfile()">
240 <i [ngClass]=
"[icons.trash]"
241 aria-hidden=
"true"></i>
245 <span class=
"form-text text-muted"
247 *
ngIf=
"data.erasureInfo && form.getValue('erasureProfile')">
248 <cd-table-key-value [renderObjects]=
"true"
249 [data]=
"form.getValue('erasureProfile')"
250 [autoReload]=
"false">
251 </cd-table-key-value>
256 <!-- Crush ruleset selection -->
257 <div class=
"form-group row"
258 *
ngIf=
"isErasure && !editing">
259 <label class=
"cd-col-form-label"
261 i18n
>Crush ruleset
</label>
262 <div class=
"cd-col-form-input">
263 <span class=
"form-text text-muted"
264 i18n
>A new crush ruleset will be implicitly created.
</span>
267 <div class=
"form-group row"
268 *
ngIf=
"isReplicated || editing">
269 <label class=
"cd-col-form-label"
271 i18n
>Crush ruleset
</label>
272 <div class=
"cd-col-form-input">
273 <ng-template #noRules
>
274 <span class=
"form-text text-muted">
275 <span i18n
>There are no rules.
</span>
278 <div *
ngIf=
"current.rules.length > 0; else noRules">
279 <div class=
"input-group">
280 <select class=
"form-control custom-select"
282 formControlName=
"crushRule"
284 <option [ngValue]=
"null"
285 i18n
>-- Select a crush rule --
</option>
286 <option *
ngFor=
"let rule of current.rules"
291 <span class=
"input-group-append">
292 <button class=
"btn btn-light"
293 [ngClass]=
"{'active': data.crushInfo}"
294 id=
"crush-info-button"
296 (click)=
"data.crushInfo = !data.crushInfo">
297 <i [ngClass]=
"[icons.questionCircle]"
298 aria-hidden=
"true"></i>
300 <button class=
"btn btn-light"
302 *
ngIf=
"isReplicated && !editing"
303 (click)=
"addCrushRule()">
304 <i [ngClass]=
"[icons.add]"
305 aria-hidden=
"true"></i>
307 <button class=
"btn btn-light"
308 *
ngIf=
"isReplicated && !editing"
310 tooltip=
"This rule can't be deleted as it is in use."
313 #
crushDeletionBtn=
"bs-tooltip"
314 (click)=
"deleteCrushRule()">
315 <i [ngClass]=
"[icons.trash]"
316 aria-hidden=
"true"></i>
320 <span class=
"form-text text-muted"
321 id=
"crush-info-block"
322 *
ngIf=
"data.crushInfo && form.getValue('crushRule')">
323 <tabset #crushInfoTabs
>
326 class=
"crush-rule-info">
327 <cd-table-key-value [renderObjects]=
"true"
328 [data]=
"form.getValue('crushRule')"
329 [autoReload]=
"false">
330 </cd-table-key-value>
333 heading=
"Crush steps"
334 class=
"crush-rule-steps">
336 <li *
ngFor=
"let step of form.get('crushRule').value.steps">
337 {{ describeCrushStep(step) }}
342 heading=
"Used by pools"
343 class=
"used-by-pools">
344 <ng-template #ruleIsNotUsed
>
345 <span i18n
>Rule is not in use.
</span>
347 <ul *
ngIf=
"crushUsage; else ruleIsNotUsed">
348 <li *
ngFor=
"let pool of crushUsage">
355 <span class=
"invalid-feedback"
356 *
ngIf=
"form.showError('crushRule', formDir, 'required')"
357 i18n
>This field is required!
</span>
358 <span class=
"invalid-feedback"
359 *
ngIf=
"form.showError('crushRule', formDir, 'tooFewOsds')"
360 i18n
>The rule can't be used in the current cluster as it has
361 too few OSDs to meet the minimum required OSD by this rule.
</span>
369 <div *
ngIf=
"info.is_all_bluestore"
370 formGroupName=
"compression">
371 <legend i18n
>Compression
</legend>
373 <!-- Compression Mode -->
374 <div class=
"form-group row">
376 class=
"cd-col-form-label"
377 for=
"mode">Mode
</label>
378 <div class=
"cd-col-form-input">
379 <select class=
"form-control custom-select"
382 formControlName=
"mode">
383 <option *
ngFor=
"let mode of info.compression_modes"
390 <div *
ngIf=
"hasCompressionEnabled()">
391 <!-- Compression algorithm selection -->
392 <div class=
"form-group row">
394 class=
"cd-col-form-label"
395 for=
"algorithm">Algorithm
</label>
396 <div class=
"cd-col-form-input">
397 <select class=
"form-control custom-select"
400 formControlName=
"algorithm">
401 <option *
ngIf=
"!info.compression_algorithms"
403 i18n
>Loading...
</option>
404 <option *
ngIf=
"info.compression_algorithms && info.compression_algorithms.length === 0"
406 ngValue=
"">-- No erasure compression algorithm available --
</option>
407 <option *
ngFor=
"let algorithm of info.compression_algorithms"
415 <!-- Compression min blob size -->
416 <div class=
"form-group row">
418 class=
"cd-col-form-label"
419 for=
"minBlobSize">Minimum blob size
</label>
420 <div class=
"cd-col-form-input">
421 <input id=
"minBlobSize"
423 formControlName=
"minBlobSize"
428 placeholder=
"e.g., 128KiB"
431 <span class=
"invalid-feedback"
432 *
ngIf=
"form.showError('minBlobSize', formDir, 'min')"
433 i18n
>Value should be greater than
0</span>
434 <span class=
"invalid-feedback"
435 *
ngIf=
"form.showError('minBlobSize', formDir, 'maximum')"
436 i18n
>Value should be less than the maximum blob size
</span>
440 <!-- Compression max blob size -->
441 <div class=
"form-group row">
443 class=
"cd-col-form-label"
444 for=
"maxBlobSize">Maximum blob size
</label>
445 <div class=
"cd-col-form-input">
446 <input id=
"maxBlobSize"
449 formControlName=
"maxBlobSize"
452 placeholder=
"e.g., 512KiB"
455 <span class=
"invalid-feedback"
456 *
ngIf=
"form.showError('maxBlobSize', formDir, 'min')"
457 i18n
>Value should be greater than
0</span>
458 <span class=
"invalid-feedback"
459 *
ngIf=
"form.showError('maxBlobSize', formDir, 'minimum')"
460 i18n
>Value should be greater than the minimum blob size
</span>
464 <!-- Compression ratio -->
465 <div class=
"form-group row">
467 class=
"cd-col-form-label"
468 for=
"ratio">Ratio
</label>
469 <div class=
"cd-col-form-input">
472 formControlName=
"ratio"
479 placeholder=
"Compression ratio">
480 <span class=
"invalid-feedback"
481 *
ngIf=
"form.showError('ratio', formDir, 'min') || form.showError('ratio', formDir, 'max')"
482 i18n
>Value should be between
0.0 and
1.0</span>
491 <legend i18n
>Quotas
</legend>
494 <div class=
"form-group row">
495 <label class=
"cd-col-form-label"
497 <ng-container i18n
>Max bytes
</ng-container>
499 <span i18n
>Leave it blank or specify
0 to disable this quota.
</span>
501 <span i18n
>A valid quota should be greater than
0.
</span>
504 <div class=
"cd-col-form-input">
505 <input class=
"form-control"
509 formControlName=
"max_bytes"
511 placeholder=
"e.g., 10GiB"
518 <div class=
"form-group row">
519 <label class=
"cd-col-form-label"
521 <ng-container i18n
>Max objects
</ng-container>
523 <span i18n
>Leave it blank or specify
0 to disable this quota.
</span>
525 <span i18n
>A valid quota should be greater than
0.
</span>
528 <div class=
"cd-col-form-input">
529 <input class=
"form-control"
534 formControlName=
"max_objects">
535 <span class=
"invalid-feedback"
536 *
ngIf=
"form.showError('max_objects', formDir, 'min')"
537 i18n
>The value should be greater or equal to
0</span>
542 <!-- Pool configuration -->
543 <div [hidden]=
"isErasure || data.applications.selected.indexOf('rbd') === -1">
544 <cd-rbd-configuration-form [form]=
"form"
545 [initializeData]=
"initializeConfigData"
546 (changes)=
"currentConfigurationValues = $event()">
547 </cd-rbd-configuration-form>
550 <div class=
"card-footer">
551 <div class=
"button-group text-right">
552 <cd-submit-button [form]=
"formDir"
553 i18n=
"form action button|Example: Create Pool@@formActionButton"
554 (submitAction)=
"submit()">{{ action | titlecase }} {{ resource | upperFirst }}
556 <cd-back-button></cd-back-button>