]>
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}',
17 disabled
: '{!isCreate}',
23 xtype
: 'proxmoxintegerfield',
24 fieldLabel
: gettext('Size'),
31 change: function(field
, val
) {
32 let size
= Math
.round((val
+ 1) / 2);
34 field
.up('inputpanel').down('field[name=min_size]').setValue(size
);
42 xtype
: 'proxmoxKVComboBox',
43 fieldLabel
: 'PG Autoscale Mode',
44 name
: 'pg_autoscale_mode',
56 xtype
: 'proxmoxcheckbox',
57 fieldLabel
: gettext('Add as Storage'),
60 hidden
: '{!isCreate}',
66 'data-qtip': gettext('Add the new pool to the cluster storage configuration.'),
72 xtype
: 'proxmoxintegerfield',
73 fieldLabel
: gettext('Min. Size'),
77 minValue
: (get) => get('isCreate') ? 2 : 1,
82 change: function(field
, minSize
) {
83 let panel
= field
.up('inputpanel');
84 let size
= panel
.down('field[name=size]').getValue();
86 let showWarning
= minSize
<= size
/ 2 && minSize
!== size
;
88 let fieldLabel
= gettext('Min. Size');
90 fieldLabel
= gettext('Min. Size') + ' <i class="fa fa-exclamation-triangle warning"></i>';
92 panel
.down('field[name=min_size-warning]').setHidden(!showWarning
);
93 field
.setFieldLabel(fieldLabel
);
98 xtype
: 'displayfield',
99 name
: 'min_size-warning',
101 value
: gettext('min_size <= size/2 can lead to data loss, incomplete PGs or unfound objects.'),
105 xtype
: 'pveCephRuleSelector',
106 fieldLabel
: 'Crush Rule', // do not localize
107 cbind
: { nodename
: '{nodename}' },
112 xtype
: 'proxmoxintegerfield',
113 fieldLabel
: '# of PGs',
124 xtype
: 'numberfield',
125 fieldLabel
: gettext('Target Ratio'),
126 name
: 'target_size_ratio',
133 'data-qtip': gettext('The ratio of storage amount this pool will consume compared to other pools with ratios. Used for auto-scaling.'),
137 xtype
: 'pveSizeField',
139 fieldLabel
: gettext('Target Size'),
146 'data-qtip': gettext('The amount of data eventually stored in this pool. Used for auto-scaling.'),
150 xtype
: 'displayfield',
152 value
: Ext
.String
.format(gettext('{0} takes precedence.'), gettext('Target Ratio')), // FIXME: tooltip?
155 xtype
: 'proxmoxintegerfield',
156 fieldLabel
: 'Min. # of PGs',
164 onGetValues: function(values
) {
165 Object
.keys(values
|| {}).forEach(function(name
) {
166 if (values
[name
] === '') {
175 Ext
.define('PVE.CephPoolEdit', {
176 extend
: 'Proxmox.window.Edit',
177 alias
: 'widget.pveCephPoolEdit',
178 xtype
: 'pveCephPoolEdit',
179 mixins
: ['Proxmox.Mixin.CBind'],
183 isCreate
: (cfg
) => !cfg
.pool_name
,
187 autoLoad
: get => !get('isCreate'),
188 url
: get => get('isCreate')
189 ? `/nodes/${get('nodename')}/ceph/pools`
190 : `/nodes/${get('nodename')}/ceph/pools/${get('pool_name')}`,
191 method
: get => get('isCreate') ? 'POST' : 'PUT',
196 subject
: gettext('Ceph Pool'),
199 xtype
: 'pveCephPoolInputPanel',
201 nodename
: '{nodename}',
202 pool_name
: '{pool_name}',
203 isCreate
: '{isCreate}',
208 Ext
.define('PVE.node.CephPoolList', {
209 extend
: 'Ext.grid.GridPanel',
210 alias
: 'widget.pveNodeCephPoolList',
212 onlineHelp
: 'chapter_pveceph',
215 stateId
: 'grid-ceph-pools',
216 bufferedRenderer
: false,
218 features
: [{ ftype
: 'summary' }],
222 text
: gettext('Name'),
226 dataIndex
: 'pool_name',
229 text
: gettext('Size') + '/min',
233 renderer: function(v
, meta
, rec
) {
234 return v
+ '/' + rec
.data
.min_size
;
239 text
: '# of Placement Groups',
246 text
: gettext('Optimal # of PGs'),
250 dataIndex
: 'pg_num_final',
251 renderer: function(value
, metaData
) {
253 value
= '<i class="fa fa-info-circle faded"></i> n/a';
254 metaData
.tdAttr
= 'data-qtip="Needs pg_autoscaler module enabled."';
260 text
: gettext('Min. # of PGs'),
264 dataIndex
: 'pg_num_min',
268 text
: gettext('Target Ratio'),
272 dataIndex
: 'target_size_ratio',
273 renderer
: Ext
.util
.Format
.numberRenderer('0.0000'),
277 text
: gettext('Target Size'),
281 dataIndex
: 'target_size',
283 renderer: function(v
, metaData
, rec
) {
284 let value
= PVE
.Utils
.render_size(v
);
285 if (rec
.data
.target_size_ratio
> 0) {
286 value
= '<i class="fa fa-info-circle faded"></i> ' + value
;
287 metaData
.tdAttr
= 'data-qtip="Target Size Ratio takes precedence over Target Size."';
293 text
: gettext('Autoscale Mode'),
297 dataIndex
: 'pg_autoscale_mode',
300 text
: 'CRUSH Rule (ID)',
304 renderer
: (v
, meta
, rec
) => `${v} (${rec.data.crush_rule})`,
305 dataIndex
: 'crush_rule_name',
308 text
: gettext('Used') + ' (%)',
313 dataIndex
: 'bytes_used',
315 summaryRenderer
: PVE
.Utils
.render_size
,
316 renderer: function(v
, meta
, rec
) {
317 let percentage
= Ext
.util
.Format
.percent(rec
.data
.percent_used
, '0.00');
318 let used
= PVE
.Utils
.render_size(v
);
319 return used
+ ' (' + percentage
+ ')';
323 initComponent: function() {
326 var nodename
= me
.pveSelNode
.data
.node
;
328 throw "no node name specified";
331 var sm
= Ext
.create('Ext.selection.RowModel', {});
333 var rstore
= Ext
.create('Proxmox.data.UpdateStore', {
335 storeid
: 'ceph-pool-list' + nodename
,
336 model
: 'ceph-pool-list',
339 url
: "/api2/json/nodes/" + nodename
+ "/ceph/pools",
342 let store
= Ext
.create('Proxmox.data.DiffStore', { rstore
: rstore
});
344 PVE
.Utils
.handleStoreErrorOrMask(
347 /not (installed|initialized)/i,
350 PVE
.Utils
.showCephInstallOrMask(me
, error
.statusText
, nodename
, win
=> {
351 me
.mon(win
, 'cephInstallWindowClosed', () => rstore
.startUpdate());
356 var run_editor = function() {
357 let rec
= sm
.getSelection()[0];
358 if (!rec
|| !rec
.data
.pool_name
) {
361 Ext
.create('PVE.CephPoolEdit', {
362 title
: gettext('Edit') + ': Ceph Pool',
364 pool_name
: rec
.data
.pool_name
,
367 destroy
: () => rstore
.load(),
377 text
: gettext('Create'),
378 handler: function() {
379 Ext
.create('PVE.CephPoolEdit', {
380 title
: gettext('Create') + ': Ceph Pool',
385 destroy
: () => rstore
.load(),
391 xtype
: 'proxmoxButton',
392 text
: gettext('Edit'),
398 xtype
: 'proxmoxButton',
399 text
: gettext('Destroy'),
402 handler: function() {
403 let rec
= sm
.getSelection()[0];
404 if (!rec
|| !rec
.data
.pool_name
) {
407 let poolName
= rec
.data
.pool_name
;
408 Ext
.create('PVE.window.SafeDestroy', {
410 url
: `/nodes/${nodename}/ceph/pools/${poolName}`,
420 destroy
: () => rstore
.load(),
427 activate
: () => rstore
.startUpdate(),
428 destroy
: () => rstore
.stopUpdate(),
429 itemdblclick
: run_editor
,
436 Ext
.define('ceph-pool-list', {
437 extend
: 'Ext.data.Model',
438 fields
: ['pool_name',
439 { name
: 'pool', type
: 'integer' },
440 { name
: 'size', type
: 'integer' },
441 { name
: 'min_size', type
: 'integer' },
442 { name
: 'pg_num', type
: 'integer' },
443 { name
: 'pg_num_min', type
: 'integer' },
444 { name
: 'bytes_used', type
: 'integer' },
445 { name
: 'percent_used', type
: 'number' },
446 { name
: 'crush_rule', type
: 'integer' },
447 { name
: 'crush_rule_name', type
: 'string' },
448 { name
: 'pg_autoscale_mode', type
: 'string' },
449 { name
: 'pg_num_final', type
: 'integer' },
450 { name
: 'target_size_ratio', type
: 'number' },
451 { name
: 'target_size', type
: 'integer' },
453 idProperty
: 'pool_name',
457 Ext
.define('PVE.form.CephRuleSelector', {
458 extend
: 'Ext.form.field.ComboBox',
459 alias
: 'widget.pveCephRuleSelector',
463 displayField
: 'name',
467 initComponent: function() {
471 throw "no nodename given";
474 var store
= Ext
.create('Ext.data.Store', {
479 url
: `/api2/json/nodes/${me.nodename}/ceph/rules`,
490 callback: function(rec
, op
, success
) {
491 if (success
&& rec
.length
> 0) {