]>
Commit | Line | Data |
---|---|---|
4ea09218 | 1 | Ext.define('PVE.CephCreateOsd', { |
9fccc702 | 2 | extend: 'Proxmox.window.Edit', |
4d3e918a | 3 | xtype: 'pveCephCreateOsd', |
4ea09218 DM |
4 | |
5 | subject: 'Ceph OSD', | |
6 | ||
7 | showProgress: true, | |
8 | ||
35085f4a TL |
9 | onlineHelp: 'pve_ceph_osds', |
10 | ||
4ea09218 | 11 | initComponent : function() { |
4ea09218 DM |
12 | var me = this; |
13 | ||
14 | if (!me.nodename) { | |
15 | throw "no node name specified"; | |
16 | } | |
17 | ||
d5e771ce | 18 | me.isCreate = true; |
c474314e | 19 | |
4ea09218 DM |
20 | Ext.applyIf(me, { |
21 | url: "/nodes/" + me.nodename + "/ceph/osd", | |
9ad28182 DC |
22 | method: 'POST', |
23 | items: [ | |
24 | { | |
4d3e918a | 25 | xtype: 'inputpanel', |
4c94e9de DC |
26 | onGetValues: function(values) { |
27 | Object.keys(values || {}).forEach(function(name) { | |
28 | if (values[name] === '') { | |
29 | delete values[name]; | |
30 | } | |
31 | }); | |
32 | ||
33 | return values; | |
34 | }, | |
4d3e918a DC |
35 | column1: [ |
36 | { | |
37 | xtype: 'pveDiskSelector', | |
38 | name: 'dev', | |
39 | nodename: me.nodename, | |
40 | diskType: 'unused', | |
41 | fieldLabel: gettext('Disk'), | |
42 | allowBlank: false | |
43 | } | |
44 | ], | |
45 | column2: [ | |
46 | { | |
47 | xtype: 'pveDiskSelector', | |
48 | name: 'db_dev', | |
49 | nodename: me.nodename, | |
50 | diskType: 'journal_disks', | |
51 | fieldLabel: gettext('DB Disk'), | |
52 | value: '', | |
53 | autoSelect: false, | |
54 | allowBlank: true, | |
55 | emptyText: 'use OSD disk', | |
56 | listeners: { | |
57 | change: function(field, val) { | |
58 | me.down('field[name=db_size]').setDisabled(!val); | |
59 | } | |
60 | } | |
61 | }, | |
62 | { | |
63 | xtype: 'numberfield', | |
64 | name: 'db_size', | |
65 | fieldLabel: gettext('DB size') + ' (GiB)', | |
66 | minValue: 1, | |
67 | maxValue: 128*1024, | |
68 | decimalPrecision: 2, | |
69 | allowBlank: true, | |
70 | disabled: true, | |
71 | emptyText: gettext('Automatic') | |
72 | } | |
73 | ], | |
74 | advancedColumn1: [ | |
6c311f2c DC |
75 | { |
76 | xtype: 'proxmoxcheckbox', | |
77 | name: 'encrypted', | |
78 | fieldLabel: gettext('Encrypt OSD') | |
79 | }, | |
80 | ], | |
81 | advancedColumn2: [ | |
4d3e918a DC |
82 | { |
83 | xtype: 'pveDiskSelector', | |
84 | name: 'wal_dev', | |
85 | nodename: me.nodename, | |
86 | diskType: 'journal_disks', | |
87 | fieldLabel: gettext('WAL Disk'), | |
88 | value: '', | |
89 | autoSelect: false, | |
90 | allowBlank: true, | |
91 | emptyText: 'use OSD/DB disk', | |
92 | listeners: { | |
93 | change: function(field, val) { | |
94 | me.down('field[name=wal_size]').setDisabled(!val); | |
95 | } | |
96 | } | |
97 | }, | |
98 | { | |
99 | xtype: 'numberfield', | |
100 | name: 'wal_size', | |
101 | fieldLabel: gettext('WAL size') + ' (GiB)', | |
102 | minValue: 0.5, | |
103 | maxValue: 128*1024, | |
104 | decimalPrecision: 2, | |
105 | allowBlank: true, | |
106 | disabled: true, | |
107 | emptyText: gettext('Automatic') | |
108 | } | |
109 | ] | |
deca45c1 TL |
110 | }, |
111 | { | |
112 | xtype: 'displayfield', | |
113 | padding: '5 0 0 0', | |
114 | userCls: 'pve-hint', | |
115 | value: 'Note: Ceph is not compatible with disks backed by a hardware ' + | |
116 | 'RAID controller. For details see ' + | |
117 | '<a target="_blank" href="' + Proxmox.Utils.get_help_link('chapter_pveceph') + '">the reference documentation</a>.', | |
fddeb25b | 118 | } |
4d3e918a DC |
119 | ] |
120 | }); | |
4ea09218 | 121 | |
4d3e918a | 122 | me.callParent(); |
4ea09218 DM |
123 | } |
124 | }); | |
125 | ||
126 | Ext.define('PVE.CephRemoveOsd', { | |
9fccc702 | 127 | extend: 'Proxmox.window.Edit', |
4ea09218 DM |
128 | alias: ['widget.pveCephRemoveOsd'], |
129 | ||
130 | isRemove: true, | |
131 | ||
132 | showProgress: true, | |
89cd5a3f DC |
133 | method: 'DELETE', |
134 | items: [ | |
135 | { | |
896c0d50 | 136 | xtype: 'proxmoxcheckbox', |
89cd5a3f DC |
137 | name: 'cleanup', |
138 | checked: true, | |
139 | labelWidth: 130, | |
c56634f1 | 140 | fieldLabel: gettext('Cleanup Disks') |
89cd5a3f DC |
141 | } |
142 | ], | |
4ea09218 | 143 | initComponent : function() { |
d5e771ce | 144 | |
4ea09218 DM |
145 | var me = this; |
146 | ||
147 | if (!me.nodename) { | |
148 | throw "no node name specified"; | |
149 | } | |
150 | if (me.osdid === undefined || me.osdid < 0) { | |
151 | throw "no osdid specified"; | |
152 | } | |
153 | ||
d5e771ce | 154 | me.isCreate = true; |
4ea09218 | 155 | |
fb0e1813 | 156 | me.title = gettext('Destroy') + ': Ceph OSD osd.' + me.osdid.toString(); |
c474314e | 157 | |
4ea09218 | 158 | Ext.applyIf(me, { |
d5e771ce | 159 | url: "/nodes/" + me.nodename + "/ceph/osd/" + me.osdid.toString() |
4ea09218 DM |
160 | }); |
161 | ||
162 | me.callParent(); | |
163 | } | |
164 | }); | |
165 | ||
5960a66c DC |
166 | Ext.define('PVE.CephSetFlags', { |
167 | extend: 'Proxmox.window.Edit', | |
168 | xtype: 'pveCephSetFlags', | |
169 | ||
5960a66c DC |
170 | showProgress: true, |
171 | ||
172 | width: 600, | |
173 | onlineHelp: 'pve_ceph_osds', | |
174 | isCreate: true, | |
60456379 TL |
175 | title: Ext.String.format(gettext('Manage {0}'), 'Global OSD Flags'), |
176 | submitText: gettext('Apply'), | |
5960a66c DC |
177 | |
178 | items: [ | |
179 | { | |
180 | xtype: 'inputpanel', | |
181 | onGetValues: function(values) { | |
182 | var me = this; | |
183 | var val = {}; | |
184 | var data = me.down('#flaggrid').getStore().each((rec) => { | |
185 | val[rec.data.name] = rec.data.value ? 1 : 0; | |
186 | }); | |
187 | ||
188 | return val; | |
189 | }, | |
190 | items: [ | |
191 | { | |
192 | xtype: 'grid', | |
193 | itemId: 'flaggrid', | |
f6556196 TL |
194 | store: { |
195 | listeners: { | |
196 | update: function() { | |
197 | this.commitChanges(); | |
198 | } | |
199 | } | |
200 | }, | |
5960a66c DC |
201 | |
202 | columns: [ | |
203 | { | |
204 | text: gettext('Enable'), | |
205 | xtype: 'checkcolumn', | |
206 | width: 60, | |
207 | dataIndex: 'value', | |
208 | }, | |
209 | { | |
210 | text: 'Name', | |
211 | dataIndex: 'name', | |
212 | }, | |
213 | { | |
214 | text: 'Description', | |
215 | flex: 1, | |
216 | dataIndex: 'description', | |
217 | }, | |
218 | ] | |
60456379 | 219 | }, |
5960a66c DC |
220 | ], |
221 | }, | |
222 | ], | |
223 | ||
224 | initComponent : function() { | |
225 | var me = this; | |
226 | ||
227 | if (!me.nodename) { | |
228 | throw "no node name specified"; | |
229 | } | |
230 | ||
231 | Ext.applyIf(me, { | |
232 | url: "/nodes/" + me.nodename + "/ceph/flags2", | |
233 | method: 'PUT', | |
234 | }); | |
235 | ||
236 | me.callParent(); | |
237 | var grid = me.down('#flaggrid'); | |
238 | me.load({ | |
239 | success: function(response, options) { | |
240 | var data = response.result.data; | |
241 | grid.getStore().setData(data); | |
242 | // set the put url correctly | |
243 | me.url = "/nodes/" + me.nodename + "/ceph/flags"; | |
244 | } | |
245 | }) | |
246 | } | |
247 | }); | |
248 | ||
4ea09218 DM |
249 | Ext.define('PVE.node.CephOsdTree', { |
250 | extend: 'Ext.tree.Panel', | |
251 | alias: ['widget.pveNodeCephOsdTree'], | |
ba93a9c6 | 252 | onlineHelp: 'chapter_pveceph', |
3982a214 DC |
253 | |
254 | viewModel: { | |
255 | data: { | |
256 | nodename: '', | |
257 | flags: [], | |
258 | maxversion: '0', | |
0b88c18a | 259 | mixedversions: false, |
3982a214 DC |
260 | versions: {}, |
261 | isOsd: false, | |
262 | downOsd: false, | |
263 | upOsd: false, | |
264 | inOsd: false, | |
265 | outOsd: false, | |
266 | osdid: '', | |
267 | osdhost: '', | |
268 | } | |
269 | }, | |
270 | ||
271 | controller: { | |
272 | xclass: 'Ext.app.ViewController', | |
273 | ||
274 | reload: function() { | |
275 | var me = this.getView(); | |
276 | var vm = this.getViewModel(); | |
277 | var nodename = vm.get('nodename'); | |
278 | var sm = me.getSelectionModel(); | |
279 | Proxmox.Utils.API2Request({ | |
280 | url: "/nodes/" + nodename + "/ceph/osd", | |
281 | waitMsgTarget: me, | |
282 | method: 'GET', | |
283 | failure: function(response, opts) { | |
284 | var msg = response.htmlStatus; | |
285 | PVE.Utils.showCephInstallOrMask(me, msg, nodename, | |
286 | function(win){ | |
287 | me.mon(win, 'cephInstallWindowClosed', this.reload); | |
288 | } | |
289 | ); | |
290 | }, | |
291 | success: function(response, opts) { | |
292 | var data = response.result.data; | |
293 | var selected = me.getSelection(); | |
294 | var name; | |
295 | if (selected.length) { | |
296 | name = selected[0].data.name; | |
297 | } | |
298 | vm.set('versions', data.versions); | |
299 | // extract max version | |
0b88c18a DC |
300 | var maxversion = "0"; |
301 | var mixedversions = false; | |
302 | var traverse; | |
303 | traverse = function(node, fn) { | |
304 | fn(node); | |
305 | if (Array.isArray(node.children)) { | |
306 | node.children.forEach(c => { traverse(c, fn); }); | |
3982a214 | 307 | } |
0b88c18a DC |
308 | }; |
309 | traverse(data.root, node => { | |
310 | // compatibility for old api call | |
311 | if (node.type === 'host' && node.version === undefined) { | |
312 | node.version = data.versions[node.name]; | |
313 | } | |
314 | ||
315 | if (node.version === undefined) { | |
316 | return; | |
317 | } | |
318 | ||
319 | if (node.version !== maxversion && maxversion !== "0") { | |
320 | mixedversions = true; | |
321 | } | |
322 | ||
323 | if (PVE.Utils.compare_ceph_versions(node.version, maxversion) > 0) { | |
324 | maxversion = node.version; | |
325 | } | |
326 | ||
3982a214 DC |
327 | }); |
328 | vm.set('maxversion', maxversion); | |
0b88c18a | 329 | vm.set('mixedversions', mixedversions); |
3982a214 DC |
330 | sm.deselectAll(); |
331 | me.setRootNode(data.root); | |
332 | me.expandAll(); | |
333 | if (name) { | |
334 | var node = me.getRootNode().findChild('name', name, true); | |
335 | if (node) { | |
336 | me.setSelection([node]); | |
337 | } | |
338 | } | |
339 | ||
340 | var flags = data.flags.split(','); | |
341 | vm.set('flags', flags); | |
3982a214 DC |
342 | } |
343 | }); | |
344 | }, | |
345 | ||
346 | osd_cmd: function(comp) { | |
347 | var me = this; | |
348 | var vm = this.getViewModel(); | |
349 | var cmd = comp.cmd; | |
350 | var params = comp.params || {}; | |
351 | var osdid = vm.get('osdid'); | |
352 | ||
353 | var doRequest = function() { | |
354 | Proxmox.Utils.API2Request({ | |
355 | url: "/nodes/" + vm.get('osdhost') + "/ceph/osd/" + osdid + '/' + cmd, | |
356 | waitMsgTarget: me.getView(), | |
357 | method: 'POST', | |
358 | params: params, | |
359 | success: () => { me.reload(); }, | |
360 | failure: function(response, opts) { | |
361 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
362 | } | |
363 | }); | |
364 | }; | |
365 | ||
366 | if (cmd === 'scrub') { | |
367 | Ext.MessageBox.defaultButton = params.deep === 1 ? 2 : 1; | |
368 | Ext.Msg.show({ | |
369 | title: gettext('Confirm'), | |
370 | icon: params.deep === 1 ? Ext.Msg.WARNING : Ext.Msg.QUESTION, | |
371 | msg: params.deep !== 1 ? | |
372 | Ext.String.format(gettext("Scrub OSD.{0}"), osdid) : | |
373 | Ext.String.format(gettext("Deep Scrub OSD.{0}"), osdid) + | |
374 | "<br>Caution: This can reduce performance while it is running.", | |
375 | buttons: Ext.Msg.YESNO, | |
376 | callback: function(btn) { | |
377 | if (btn !== 'yes') { | |
378 | return; | |
379 | } | |
380 | doRequest(); | |
381 | } | |
382 | }); | |
383 | } else { | |
384 | doRequest(); | |
385 | } | |
386 | }, | |
387 | ||
388 | create_osd: function() { | |
389 | var me = this; | |
390 | var vm = this.getViewModel(); | |
391 | Ext.create('PVE.CephCreateOsd', { | |
392 | nodename: vm.get('nodename'), | |
393 | taskDone: () => { me.reload(); } | |
394 | }).show(); | |
395 | }, | |
396 | ||
397 | destroy_osd: function() { | |
398 | var me = this; | |
399 | var vm = this.getViewModel(); | |
400 | Ext.create('PVE.CephRemoveOsd', { | |
401 | nodename: vm.get('osdhost'), | |
402 | osdid: vm.get('osdid'), | |
403 | taskDone: () => { me.reload(); } | |
404 | }).show(); | |
405 | }, | |
406 | ||
1c58ffa6 | 407 | set_flags: function() { |
3982a214 DC |
408 | var me = this; |
409 | var vm = this.getViewModel(); | |
1c58ffa6 DC |
410 | Ext.create('PVE.CephSetFlags', { |
411 | nodename: vm.get('nodename'), | |
412 | taskDone: () => { me.reload(); } | |
413 | }).show(); | |
3982a214 DC |
414 | }, |
415 | ||
416 | service_cmd: function(comp) { | |
417 | var me = this; | |
418 | var vm = this.getViewModel(); | |
419 | var cmd = comp.cmd || comp; | |
420 | Proxmox.Utils.API2Request({ | |
421 | url: "/nodes/" + vm.get('osdhost') + "/ceph/" + cmd, | |
422 | params: { service: "osd." + vm.get('osdid') }, | |
423 | waitMsgTarget: me.getView(), | |
424 | method: 'POST', | |
425 | success: function(response, options) { | |
426 | var upid = response.result.data; | |
427 | var win = Ext.create('Proxmox.window.TaskProgress', { | |
428 | upid: upid, | |
429 | taskDone: () => { me.reload(); } | |
430 | }); | |
431 | win.show(); | |
432 | }, | |
433 | failure: function(response, opts) { | |
434 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
435 | } | |
436 | }); | |
437 | }, | |
438 | ||
439 | set_selection_status: function(tp, selection) { | |
440 | if (selection.length < 1) { | |
441 | return; | |
442 | } | |
443 | var rec = selection[0]; | |
444 | var vm = this.getViewModel(); | |
445 | ||
446 | var isOsd = (rec.data.host && (rec.data.type === 'osd') && (rec.data.id >= 0)); | |
447 | ||
448 | vm.set('isOsd', isOsd); | |
449 | vm.set('downOsd', isOsd && rec.data.status === 'down'); | |
450 | vm.set('upOsd', isOsd && rec.data.status !== 'down'); | |
451 | vm.set('inOsd', isOsd && rec.data.in); | |
452 | vm.set('outOsd', isOsd && !rec.data.in); | |
453 | vm.set('osdid', isOsd ? rec.data.id : undefined); | |
454 | vm.set('osdhost', isOsd ? rec.data.host : undefined); | |
3982a214 DC |
455 | }, |
456 | ||
457 | render_status: function(value, metaData, rec) { | |
458 | if (!value) { | |
459 | return value; | |
460 | } | |
461 | var inout = rec.data['in'] ? 'in' : 'out'; | |
462 | var updownicon = value === 'up' ? 'good fa-arrow-circle-up' : | |
463 | 'critical fa-arrow-circle-down'; | |
464 | ||
465 | var inouticon = rec.data['in'] ? 'good fa-circle' : | |
466 | 'warning fa-circle-o'; | |
467 | ||
468 | var text = value + ' <i class="fa ' + updownicon + '"></i> / ' + | |
469 | inout + ' <i class="fa ' + inouticon + '"></i>'; | |
470 | ||
471 | return text; | |
472 | }, | |
473 | ||
474 | render_wal: function(value, metaData, rec) { | |
475 | if (!value && | |
476 | rec.data.osdtype === 'bluestore' && | |
477 | rec.data.type === 'osd') { | |
478 | return 'N/A'; | |
479 | } | |
480 | return value; | |
481 | }, | |
482 | ||
483 | render_version: function(value, metadata, rec) { | |
484 | var vm = this.getViewModel(); | |
485 | var versions = vm.get('versions'); | |
486 | var icon = ""; | |
487 | var version = value || ""; | |
0b88c18a DC |
488 | var maxversion = vm.get('maxversion'); |
489 | if (value && value != maxversion) { | |
490 | if (rec.data.type === 'host' || versions[rec.data.host] !== maxversion) { | |
491 | icon = PVE.Utils.get_ceph_icon_html('HEALTH_UPGRADE'); | |
492 | } else { | |
493 | icon = PVE.Utils.get_ceph_icon_html('HEALTH_OLD'); | |
494 | } | |
495 | } else if (value && vm.get('mixedversions')) { | |
496 | icon = PVE.Utils.get_ceph_icon_html('HEALTH_OK'); | |
3982a214 DC |
497 | } |
498 | ||
499 | return icon + version; | |
500 | }, | |
501 | ||
502 | render_osd_val: function(value, metaData, rec) { | |
503 | return (rec.data.type === 'osd') ? value : ''; | |
504 | }, | |
a3368752 TL |
505 | render_osd_weight: function(value, metaData, rec) { |
506 | if (rec.data.type !== 'osd') { | |
507 | return ''; | |
508 | } | |
509 | return Ext.util.Format.number(value, '0.00###'); | |
510 | }, | |
3982a214 | 511 | |
a9e23b28 TL |
512 | render_osd_latency: function(value, metaData, rec) { |
513 | if (rec.data.type !== 'osd') { | |
514 | return ''; | |
515 | } | |
516 | let commit_ms = rec.data.commit_latency_ms, | |
517 | apply_ms = rec.data.apply_latency_ms; | |
518 | return apply_ms + ' / ' + commit_ms; | |
519 | }, | |
520 | ||
3982a214 DC |
521 | render_osd_size: function(value, metaData, rec) { |
522 | return this.render_osd_val(PVE.Utils.render_size(value), metaData, rec); | |
523 | }, | |
524 | ||
525 | control: { | |
526 | '#': { | |
527 | selectionchange: 'set_selection_status' | |
528 | } | |
529 | }, | |
530 | ||
531 | init: function(view) { | |
532 | var me = this; | |
533 | var vm = this.getViewModel(); | |
534 | ||
535 | if (!view.pveSelNode.data.node) { | |
536 | throw "no node name specified"; | |
537 | } | |
538 | ||
539 | vm.set('nodename', view.pveSelNode.data.node); | |
540 | ||
541 | me.callParent(); | |
542 | me.reload(); | |
543 | } | |
544 | }, | |
545 | ||
361aafd0 DC |
546 | stateful: true, |
547 | stateId: 'grid-ceph-osd', | |
3982a214 DC |
548 | rootVisible: false, |
549 | useArrows: true, | |
550 | ||
89cd5a3f DC |
551 | columns: [ |
552 | { | |
553 | xtype: 'treecolumn', | |
554 | text: 'Name', | |
555 | dataIndex: 'name', | |
556 | width: 150 | |
557 | }, | |
558 | { | |
559 | text: 'Type', | |
560 | dataIndex: 'type', | |
413ada0f | 561 | hidden: true, |
89cd5a3f | 562 | align: 'right', |
a3f146fc | 563 | width: 75 |
89cd5a3f | 564 | }, |
33a7e157 DC |
565 | { |
566 | text: gettext("Class"), | |
567 | dataIndex: 'device_class', | |
568 | align: 'right', | |
a3f146fc | 569 | width: 75 |
33a7e157 | 570 | }, |
7d406f18 DC |
571 | { |
572 | text: "OSD Type", | |
573 | dataIndex: 'osdtype', | |
574 | align: 'right', | |
a3f146fc | 575 | width: 100 |
7d406f18 DC |
576 | }, |
577 | { | |
578 | text: "Bluestore Device", | |
579 | dataIndex: 'blfsdev', | |
580 | align: 'right', | |
a3f146fc | 581 | width: 75, |
7d406f18 DC |
582 | hidden: true |
583 | }, | |
584 | { | |
585 | text: "DB Device", | |
586 | dataIndex: 'dbdev', | |
587 | align: 'right', | |
a3f146fc | 588 | width: 75, |
7d406f18 DC |
589 | hidden: true |
590 | }, | |
591 | { | |
592 | text: "WAL Device", | |
593 | dataIndex: 'waldev', | |
594 | align: 'right', | |
3982a214 | 595 | renderer: 'render_wal', |
a3f146fc | 596 | width: 75, |
7d406f18 DC |
597 | hidden: true |
598 | }, | |
89cd5a3f DC |
599 | { |
600 | text: 'Status', | |
601 | dataIndex: 'status', | |
602 | align: 'right', | |
3982a214 | 603 | renderer: 'render_status', |
a3f146fc | 604 | width: 120 |
89cd5a3f | 605 | }, |
e0297023 DC |
606 | { |
607 | text: gettext('Version'), | |
608 | dataIndex: 'version', | |
a3f146fc | 609 | align: 'right', |
3982a214 | 610 | renderer: 'render_version' |
e0297023 | 611 | }, |
89cd5a3f DC |
612 | { |
613 | text: 'weight', | |
614 | dataIndex: 'crush_weight', | |
615 | align: 'right', | |
a3368752 | 616 | renderer: 'render_osd_weight', |
a3f146fc | 617 | width: 90 |
89cd5a3f DC |
618 | }, |
619 | { | |
620 | text: 'reweight', | |
621 | dataIndex: 'reweight', | |
622 | align: 'right', | |
a3368752 | 623 | renderer: 'render_osd_weight', |
89cd5a3f DC |
624 | width: 90 |
625 | }, | |
626 | { | |
cfb10313 TL |
627 | text: gettext('Used') + ' (%)', |
628 | dataIndex: 'percent_used', | |
629 | align: 'right', | |
630 | renderer: function(value, metaData, rec) { | |
631 | if (rec.data.type !== 'osd') { | |
632 | return ''; | |
35c9c3d6 | 633 | } |
cfb10313 TL |
634 | return Ext.util.Format.number(value, '0.00'); |
635 | }, | |
636 | width: 100 | |
637 | }, | |
638 | { | |
639 | text: gettext('Total'), | |
640 | dataIndex: 'total_space', | |
641 | align: 'right', | |
642 | renderer: 'render_osd_size', | |
643 | width: 100 | |
89cd5a3f DC |
644 | }, |
645 | { | |
a9e23b28 TL |
646 | text: 'Apply/Commit<br>Latency (ms)', |
647 | dataIndex: 'apply_latency_ms', | |
648 | align: 'right', | |
649 | renderer: 'render_osd_latency', | |
650 | width: 120 | |
89cd5a3f DC |
651 | } |
652 | ], | |
4ea09218 | 653 | |
4ea09218 | 654 | |
3982a214 DC |
655 | tbar: { |
656 | items: [ | |
657 | { | |
658 | text: gettext('Reload'), | |
659 | iconCls: 'fa fa-refresh', | |
660 | handler: 'reload' | |
661 | }, | |
a3f146fc | 662 | '-', |
3982a214 DC |
663 | { |
664 | text: gettext('Create') + ': OSD', | |
665 | handler: 'create_osd', | |
666 | }, | |
667 | { | |
60456379 | 668 | text: Ext.String.format(gettext('Manage {0}'), 'Global Flags'), |
1c58ffa6 | 669 | handler: 'set_flags', |
3982a214 DC |
670 | }, |
671 | '->', | |
672 | { | |
673 | xtype: 'tbtext', | |
674 | data: { | |
675 | osd: undefined | |
4ea09218 | 676 | }, |
3982a214 DC |
677 | bind: { |
678 | data: { | |
679 | osd: "{osdid}" | |
e2924302 | 680 | } |
4ea09218 | 681 | }, |
3982a214 DC |
682 | tpl: [ |
683 | '<tpl if="osd">', | |
684 | 'osd.{osd}:', | |
685 | '<tpl else>', | |
686 | gettext('No OSD selected'), | |
687 | '</tpl>' | |
688 | ] | |
6f82e1b6 | 689 | }, |
3982a214 DC |
690 | { |
691 | text: gettext('Start'), | |
692 | iconCls: 'fa fa-play', | |
693 | disabled: true, | |
694 | bind: { | |
695 | disabled: '{!downOsd}' | |
696 | }, | |
697 | cmd: 'start', | |
698 | handler: 'service_cmd' | |
699 | }, | |
700 | { | |
701 | text: gettext('Stop'), | |
702 | iconCls: 'fa fa-stop', | |
703 | disabled: true, | |
704 | bind: { | |
705 | disabled: '{!upOsd}' | |
706 | }, | |
707 | cmd: 'stop', | |
708 | handler: 'service_cmd' | |
709 | }, | |
710 | { | |
711 | text: gettext('Restart'), | |
712 | iconCls: 'fa fa-refresh', | |
713 | disabled: true, | |
714 | bind: { | |
715 | disabled: '{!upOsd}' | |
716 | }, | |
717 | cmd: 'restart', | |
718 | handler: 'service_cmd' | |
719 | }, | |
720 | '-', | |
721 | { | |
722 | text: 'Out', | |
723 | iconCls: 'fa fa-circle-o', | |
724 | disabled: true, | |
725 | bind: { | |
726 | disabled: '{!inOsd}' | |
727 | }, | |
728 | cmd: 'out', | |
729 | handler: 'osd_cmd' | |
730 | }, | |
731 | { | |
732 | text: 'In', | |
733 | iconCls: 'fa fa-circle', | |
734 | disabled: true, | |
735 | bind: { | |
736 | disabled: '{!outOsd}' | |
737 | }, | |
738 | cmd: 'in', | |
739 | handler: 'osd_cmd' | |
740 | }, | |
741 | '-', | |
742 | { | |
3b0ae6b2 | 743 | text: gettext('More'), |
3982a214 DC |
744 | iconCls: 'fa fa-bars', |
745 | disabled: true, | |
746 | bind: { | |
747 | disabled: '{!isOsd}' | |
748 | }, | |
749 | menu: [ | |
750 | { | |
751 | text: gettext('Scrub'), | |
752 | iconCls: 'fa fa-shower', | |
753 | cmd: 'scrub', | |
754 | handler: 'osd_cmd' | |
755 | }, | |
756 | { | |
757 | text: gettext('Deep Scrub'), | |
758 | iconCls: 'fa fa-bath', | |
759 | cmd: 'scrub', | |
760 | params: { | |
761 | deep: 1, | |
762 | }, | |
763 | handler: 'osd_cmd' | |
764 | }, | |
765 | { | |
766 | text: gettext('Destroy'), | |
767 | itemId: 'remove', | |
768 | iconCls: 'fa fa-fw fa-trash-o', | |
769 | bind: { | |
770 | disabled: '{!downOsd}' | |
771 | }, | |
772 | handler: 'destroy_osd' | |
773 | } | |
774 | ], | |
4ea09218 | 775 | } |
3982a214 DC |
776 | ] |
777 | }, | |
778 | ||
779 | fields: [ | |
780 | 'name', 'type', 'status', 'host', 'in', 'id' , | |
781 | { type: 'number', name: 'reweight' }, | |
782 | { type: 'number', name: 'percent_used' }, | |
783 | { type: 'integer', name: 'bytes_used' }, | |
784 | { type: 'integer', name: 'total_space' }, | |
785 | { type: 'integer', name: 'apply_latency_ms' }, | |
786 | { type: 'integer', name: 'commit_latency_ms' }, | |
787 | { type: 'string', name: 'device_class' }, | |
788 | { type: 'string', name: 'osdtype' }, | |
789 | { type: 'string', name: 'blfsdev' }, | |
790 | { type: 'string', name: 'dbdev' }, | |
791 | { type: 'string', name: 'waldev' }, | |
792 | { type: 'string', name: 'version', calculate: function(data) { | |
793 | return PVE.Utils.parse_ceph_version(data); | |
794 | } }, | |
795 | { type: 'string', name: 'iconCls', calculate: function(data) { | |
796 | var iconMap = { | |
797 | host: 'fa-building', | |
798 | osd: 'fa-hdd-o', | |
799 | root: 'fa-server', | |
800 | }; | |
801 | return 'fa x-fa-tree ' + iconMap[data.type]; | |
802 | } }, | |
803 | { type: 'number', name: 'crush_weight' } | |
804 | ], | |
4ea09218 | 805 | }); |