]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/ceph/Pool.js
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/pools`
204 : `/nodes/${get('nodename')}/ceph/pools/${get('pool_name')}`,
205 method
: get => get('isCreate') ? 'POST' : 'PUT',
210 subject
: gettext('Ceph Pool'),
213 xtype
: 'pveCephPoolInputPanel',
215 nodename
: '{nodename}',
216 pool_name
: '{pool_name}',
217 isErasure
: '{isErasure}',
218 isCreate
: '{isCreate}',
223 Ext
.define('PVE.node.Ceph.PoolList', {
224 extend
: 'Ext.grid.GridPanel',
225 alias
: 'widget.pveNodeCephPoolList',
227 onlineHelp
: 'chapter_pveceph',
230 stateId
: 'grid-ceph-pools',
231 bufferedRenderer
: false,
233 features
: [{ ftype
: 'summary' }],
237 text
: gettext('Name'),
241 dataIndex
: 'pool_name',
244 text
: gettext('Size') + '/min',
248 renderer
: (v
, meta
, rec
) => `${v}/${rec.data.min_size}`,
252 text
: '# of Placement Groups',
259 text
: gettext('Optimal # of PGs'),
263 dataIndex
: 'pg_num_final',
264 renderer: function(value
, metaData
) {
266 value
= '<i class="fa fa-info-circle faded"></i> n/a';
267 metaData
.tdAttr
= 'data-qtip="Needs pg_autoscaler module enabled."';
273 text
: gettext('Min. # of PGs'),
277 dataIndex
: 'pg_num_min',
281 text
: gettext('Target Ratio'),
285 dataIndex
: 'target_size_ratio',
286 renderer
: Ext
.util
.Format
.numberRenderer('0.0000'),
290 text
: gettext('Target Size'),
294 dataIndex
: 'target_size',
296 renderer: function(v
, metaData
, rec
) {
297 let value
= Proxmox
.Utils
.render_size(v
);
298 if (rec
.data
.target_size_ratio
> 0) {
299 value
= '<i class="fa fa-info-circle faded"></i> ' + value
;
300 metaData
.tdAttr
= 'data-qtip="Target Size Ratio takes precedence over Target Size."';
306 text
: gettext('Autoscale Mode'),
310 dataIndex
: 'pg_autoscale_mode',
313 text
: 'CRUSH Rule (ID)',
317 renderer
: (v
, meta
, rec
) => `${v} (${rec.data.crush_rule})`,
318 dataIndex
: 'crush_rule_name',
321 text
: gettext('Used') + ' (%)',
326 dataIndex
: 'bytes_used',
328 summaryRenderer
: Proxmox
.Utils
.render_size
,
329 renderer: function(v
, meta
, rec
) {
330 let percentage
= Ext
.util
.Format
.percent(rec
.data
.percent_used
, '0.00');
331 let used
= Proxmox
.Utils
.render_size(v
);
332 return `${used} (${percentage})`;
336 initComponent: function() {
339 var nodename
= me
.pveSelNode
.data
.node
;
341 throw "no node name specified";
344 var sm
= Ext
.create('Ext.selection.RowModel', {});
346 var rstore
= Ext
.create('Proxmox.data.UpdateStore', {
348 storeid
: 'ceph-pool-list' + nodename
,
349 model
: 'ceph-pool-list',
352 url
: `/api2/json/nodes/${nodename}/ceph/pools`,
355 let store
= Ext
.create('Proxmox.data.DiffStore', { rstore
: rstore
});
357 // manages the "install ceph?" overlay
358 PVE
.Utils
.monitor_ceph_installed(me
, rstore
, nodename
);
360 var run_editor = function() {
361 let rec
= sm
.getSelection()[0];
362 if (!rec
|| !rec
.data
.pool_name
) {
365 Ext
.create('PVE.Ceph.PoolEdit', {
366 title
: gettext('Edit') + ': Ceph Pool',
368 pool_name
: rec
.data
.pool_name
,
369 isErasure
: rec
.data
.type
=== 'erasure',
372 destroy
: () => rstore
.load(),
382 text
: gettext('Create'),
383 handler: function() {
384 Ext
.create('PVE.Ceph.PoolEdit', {
385 title
: gettext('Create') + ': Ceph Pool',
391 destroy
: () => rstore
.load(),
397 xtype
: 'proxmoxButton',
398 text
: gettext('Edit'),
404 xtype
: 'proxmoxButton',
405 text
: gettext('Destroy'),
408 handler: function() {
409 let rec
= sm
.getSelection()[0];
410 if (!rec
|| !rec
.data
.pool_name
) {
413 let poolName
= rec
.data
.pool_name
;
414 Ext
.create('Proxmox.window.SafeDestroy', {
416 url
: `/nodes/${nodename}/ceph/pools/${poolName}`,
424 taskName
: 'cephdestroypool',
427 destroy
: () => rstore
.load(),
434 activate
: () => rstore
.startUpdate(),
435 destroy
: () => rstore
.stopUpdate(),
436 itemdblclick
: run_editor
,
443 Ext
.define('ceph-pool-list', {
444 extend
: 'Ext.data.Model',
445 fields
: ['pool_name',
446 { name
: 'pool', type
: 'integer' },
447 { name
: 'size', type
: 'integer' },
448 { name
: 'min_size', type
: 'integer' },
449 { name
: 'pg_num', type
: 'integer' },
450 { name
: 'pg_num_min', type
: 'integer' },
451 { name
: 'bytes_used', type
: 'integer' },
452 { name
: 'percent_used', type
: 'number' },
453 { name
: 'crush_rule', type
: 'integer' },
454 { name
: 'crush_rule_name', type
: 'string' },
455 { name
: 'pg_autoscale_mode', type
: 'string' },
456 { name
: 'pg_num_final', type
: 'integer' },
457 { name
: 'target_size_ratio', type
: 'number' },
458 { name
: 'target_size', type
: 'integer' },
460 idProperty
: 'pool_name',
464 Ext
.define('PVE.form.CephRuleSelector', {
465 extend
: 'Ext.form.field.ComboBox',
466 alias
: 'widget.pveCephRuleSelector',
470 displayField
: 'name',
474 initComponent: function() {
478 throw "no nodename given";
486 url
: `/api2/json/nodes/${me.nodename}/ceph/rules`,
488 autoLoad
: me
.isCreate
? {
489 callback
: (records
, op
, success
) => {
490 if (success
&& records
.length
> 0) {
491 me
.select(records
[0]);