]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/ceph/Pool.js
301a3f912c7dd2cdadfe5c5e1e8f03fc331f8d33
1 Ext
.define('PVE.CephPoolInputPanel', {
2 extend
: 'Proxmox.panel.InputPanel',
3 xtype
: 'pveCephPoolInputPanel',
4 mixins
: ['Proxmox.Mixin.CBind'],
7 onlineHelp
: 'pve_ceph_pools',
12 xtype
: 'pmxDisplayEditField',
13 fieldLabel
: gettext('Name'),
15 editable
: '{isCreate}',
22 xtype
: 'pmxDisplayEditField',
24 editable
: '{!isErasure}',
26 fieldLabel
: gettext('Size'),
29 xtype
: 'proxmoxintegerfield',
35 change: function(field
, val
) {
36 let size
= Math
.round(val
/ 2);
38 field
.up('inputpanel').down('field[name=min_size]').setValue(size
);
48 xtype
: 'proxmoxKVComboBox',
49 fieldLabel
: 'PG Autoscale Mode',
50 name
: 'pg_autoscale_mode',
56 value
: 'on', // FIXME: check ceph version and only default to on on octopus and newer
62 xtype
: 'proxmoxcheckbox',
63 fieldLabel
: gettext('Add as Storage'),
66 hidden
: '{!isCreate}',
72 'data-qtip': gettext('Add the new pool to the cluster storage configuration.'),
78 xtype
: 'proxmoxintegerfield',
79 fieldLabel
: gettext('Min. Size'),
83 minValue
: (get) => get('isCreate') ? 2 : 1,
88 change: function(field
, minSize
) {
89 let panel
= field
.up('inputpanel');
90 let size
= panel
.down('field[name=size]').getValue();
92 let showWarning
= minSize
< (size
/ 2) && minSize
!== size
;
94 let fieldLabel
= gettext('Min. Size');
96 fieldLabel
= gettext('Min. Size') + ' <i class="fa fa-exclamation-triangle warning"></i>';
98 panel
.down('field[name=min_size-warning]').setHidden(!showWarning
);
99 field
.setFieldLabel(fieldLabel
);
104 xtype
: 'displayfield',
105 name
: 'min_size-warning',
107 value
: gettext('min_size < size/2 can lead to data loss, incomplete PGs or unfound objects.'),
111 xtype
: 'pmxDisplayEditField',
113 editable
: '{!isErasure}',
114 nodename
: '{nodename}',
115 isCreate
: '{isCreate}',
117 fieldLabel
: 'Crush Rule', // do not localize
120 xtype
: 'pveCephRuleSelector',
125 xtype
: 'proxmoxintegerfield',
126 fieldLabel
: '# of PGs',
137 xtype
: 'numberfield',
138 fieldLabel
: gettext('Target Ratio'),
139 name
: 'target_size_ratio',
146 'data-qtip': gettext('The ratio of storage amount this pool will consume compared to other pools with ratios. Used for auto-scaling.'),
150 xtype
: 'pveSizeField',
152 fieldLabel
: gettext('Target Size'),
161 'data-qtip': gettext('The amount of data eventually stored in this pool. Used for auto-scaling.'),
165 xtype
: 'displayfield',
167 value
: Ext
.String
.format(gettext('{0} takes precedence.'), gettext('Target Ratio')), // FIXME: tooltip?
170 xtype
: 'proxmoxintegerfield',
171 fieldLabel
: 'Min. # of PGs',
179 onGetValues: function(values
) {
180 Object
.keys(values
|| {}).forEach(function(name
) {
181 if (values
[name
] === '') {
190 Ext
.define('PVE.Ceph.PoolEdit', {
191 extend
: 'Proxmox.window.Edit',
192 alias
: 'widget.pveCephPoolEdit',
193 mixins
: ['Proxmox.Mixin.CBind'],
197 isCreate
: (cfg
) => !cfg
.pool_name
,
201 autoLoad
: get => !get('isCreate'),
202 url
: get => get('isCreate')
203 ? `/nodes/${get('nodename')}/ceph/pool`
204 : `/nodes/${get('nodename')}/ceph/pool/${get('pool_name')}`,
205 loadUrl
: get => `/nodes/${get('nodename')}/ceph/pool/${get('pool_name')}/status`,
206 method
: get => get('isCreate') ? 'POST' : 'PUT',
211 subject
: gettext('Ceph Pool'),
214 xtype
: 'pveCephPoolInputPanel',
216 nodename
: '{nodename}',
217 pool_name
: '{pool_name}',
218 isErasure
: '{isErasure}',
219 isCreate
: '{isCreate}',
224 Ext
.define('PVE.node.Ceph.PoolList', {
225 extend
: 'Ext.grid.GridPanel',
226 alias
: 'widget.pveNodeCephPoolList',
228 onlineHelp
: 'chapter_pveceph',
231 stateId
: 'grid-ceph-pools',
232 bufferedRenderer
: false,
234 features
: [{ ftype
: 'summary' }],
238 text
: gettext('Name'),
242 dataIndex
: 'pool_name',
245 text
: gettext('Type'),
252 text
: gettext('Size') + '/min',
256 renderer
: (v
, meta
, rec
) => `${v}/${rec.data.min_size}`,
260 text
: '# of Placement Groups',
267 text
: gettext('Optimal # of PGs'),
271 dataIndex
: 'pg_num_final',
272 renderer: function(value
, metaData
) {
274 value
= '<i class="fa fa-info-circle faded"></i> n/a';
275 metaData
.tdAttr
= 'data-qtip="Needs pg_autoscaler module enabled."';
281 text
: gettext('Min. # of PGs'),
285 dataIndex
: 'pg_num_min',
289 text
: gettext('Target Ratio'),
293 dataIndex
: 'target_size_ratio',
294 renderer
: Ext
.util
.Format
.numberRenderer('0.0000'),
298 text
: gettext('Target Size'),
302 dataIndex
: 'target_size',
304 renderer: function(v
, metaData
, rec
) {
305 let value
= Proxmox
.Utils
.render_size(v
);
306 if (rec
.data
.target_size_ratio
> 0) {
307 value
= '<i class="fa fa-info-circle faded"></i> ' + value
;
308 metaData
.tdAttr
= 'data-qtip="Target Size Ratio takes precedence over Target Size."';
314 text
: gettext('Autoscale Mode'),
318 dataIndex
: 'pg_autoscale_mode',
321 text
: 'CRUSH Rule (ID)',
325 renderer
: (v
, meta
, rec
) => `${v} (${rec.data.crush_rule})`,
326 dataIndex
: 'crush_rule_name',
329 text
: gettext('Used') + ' (%)',
334 dataIndex
: 'bytes_used',
336 summaryRenderer
: Proxmox
.Utils
.render_size
,
337 renderer: function(v
, meta
, rec
) {
338 let percentage
= Ext
.util
.Format
.percent(rec
.data
.percent_used
, '0.00');
339 let used
= Proxmox
.Utils
.render_size(v
);
340 return `${used} (${percentage})`;
344 initComponent: function() {
347 var nodename
= me
.pveSelNode
.data
.node
;
349 throw "no node name specified";
352 var sm
= Ext
.create('Ext.selection.RowModel', {});
354 var rstore
= Ext
.create('Proxmox.data.UpdateStore', {
356 storeid
: 'ceph-pool-list' + nodename
,
357 model
: 'ceph-pool-list',
360 url
: `/api2/json/nodes/${nodename}/ceph/pool`,
363 let store
= Ext
.create('Proxmox.data.DiffStore', { rstore
: rstore
});
365 // manages the "install ceph?" overlay
366 PVE
.Utils
.monitor_ceph_installed(me
, rstore
, nodename
);
368 var run_editor = function() {
369 let rec
= sm
.getSelection()[0];
370 if (!rec
|| !rec
.data
.pool_name
) {
373 Ext
.create('PVE.Ceph.PoolEdit', {
374 title
: gettext('Edit') + ': Ceph Pool',
376 pool_name
: rec
.data
.pool_name
,
377 isErasure
: rec
.data
.type
=== 'erasure',
380 destroy
: () => rstore
.load(),
390 text
: gettext('Create'),
391 handler: function() {
392 Ext
.create('PVE.Ceph.PoolEdit', {
393 title
: gettext('Create') + ': Ceph Pool',
399 destroy
: () => rstore
.load(),
405 xtype
: 'proxmoxButton',
406 text
: gettext('Edit'),
412 xtype
: 'proxmoxButton',
413 text
: gettext('Destroy'),
416 handler: function() {
417 let rec
= sm
.getSelection()[0];
418 if (!rec
|| !rec
.data
.pool_name
) {
421 let poolName
= rec
.data
.pool_name
;
422 Ext
.create('Proxmox.window.SafeDestroy', {
424 url
: `/nodes/${nodename}/ceph/pool/${poolName}`,
432 taskName
: 'cephdestroypool',
435 destroy
: () => rstore
.load(),
442 activate
: () => rstore
.startUpdate(),
443 destroy
: () => rstore
.stopUpdate(),
444 itemdblclick
: run_editor
,
451 Ext
.define('ceph-pool-list', {
452 extend
: 'Ext.data.Model',
453 fields
: ['pool_name',
454 { name
: 'pool', type
: 'integer' },
455 { name
: 'size', type
: 'integer' },
456 { name
: 'min_size', type
: 'integer' },
457 { name
: 'pg_num', type
: 'integer' },
458 { name
: 'pg_num_min', type
: 'integer' },
459 { name
: 'bytes_used', type
: 'integer' },
460 { name
: 'percent_used', type
: 'number' },
461 { name
: 'crush_rule', type
: 'integer' },
462 { name
: 'crush_rule_name', type
: 'string' },
463 { name
: 'pg_autoscale_mode', type
: 'string' },
464 { name
: 'pg_num_final', type
: 'integer' },
465 { name
: 'target_size_ratio', type
: 'number' },
466 { name
: 'target_size', type
: 'integer' },
468 idProperty
: 'pool_name',
472 Ext
.define('PVE.form.CephRuleSelector', {
473 extend
: 'Ext.form.field.ComboBox',
474 alias
: 'widget.pveCephRuleSelector',
478 displayField
: 'name',
482 initComponent: function() {
486 throw "no nodename given";
489 me
.originalAllowBlank
= me
.allowBlank
;
490 me
.allowBlank
= true;
498 url
: `/api2/json/nodes/${me.nodename}/ceph/rules`,
501 callback
: (records
, op
, success
) => {
502 if (me
.isCreate
&& success
&& records
.length
> 0) {
503 me
.select(records
[0]);
506 me
.allowBlank
= me
.originalAllowBlank
;
507 delete me
.originalAllowBlank
;