mirror of
https://git.proxmox.com/git/pve-manager
synced 2025-06-05 16:00:05 +00:00

they live there now, so we can delete them here and use the ones from widget-toolkit instead Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
827 lines
18 KiB
JavaScript
827 lines
18 KiB
JavaScript
Ext.define('PVE.CephCreateOsd', {
|
|
extend: 'Proxmox.window.Edit',
|
|
xtype: 'pveCephCreateOsd',
|
|
|
|
subject: 'Ceph OSD',
|
|
|
|
showProgress: true,
|
|
|
|
onlineHelp: 'pve_ceph_osds',
|
|
|
|
initComponent: function() {
|
|
let me = this;
|
|
|
|
if (!me.nodename) {
|
|
throw "no node name specified";
|
|
}
|
|
|
|
me.isCreate = true;
|
|
|
|
Ext.applyIf(me, {
|
|
url: "/nodes/" + me.nodename + "/ceph/osd",
|
|
method: 'POST',
|
|
items: [
|
|
{
|
|
xtype: 'inputpanel',
|
|
onGetValues: function(values) {
|
|
Object.keys(values || {}).forEach(function(name) {
|
|
if (values[name] === '') {
|
|
delete values[name];
|
|
}
|
|
});
|
|
|
|
return values;
|
|
},
|
|
column1: [
|
|
{
|
|
xtype: 'pmxDiskSelector',
|
|
name: 'dev',
|
|
nodename: me.nodename,
|
|
diskType: 'unused',
|
|
fieldLabel: gettext('Disk'),
|
|
allowBlank: false,
|
|
},
|
|
],
|
|
column2: [
|
|
{
|
|
xtype: 'pmxDiskSelector',
|
|
name: 'db_dev',
|
|
nodename: me.nodename,
|
|
diskType: 'journal_disks',
|
|
fieldLabel: gettext('DB Disk'),
|
|
value: '',
|
|
autoSelect: false,
|
|
allowBlank: true,
|
|
emptyText: 'use OSD disk',
|
|
listeners: {
|
|
change: function(field, val) {
|
|
me.down('field[name=db_size]').setDisabled(!val);
|
|
},
|
|
},
|
|
},
|
|
{
|
|
xtype: 'numberfield',
|
|
name: 'db_size',
|
|
fieldLabel: gettext('DB size') + ' (GiB)',
|
|
minValue: 1,
|
|
maxValue: 128*1024,
|
|
decimalPrecision: 2,
|
|
allowBlank: true,
|
|
disabled: true,
|
|
emptyText: gettext('Automatic'),
|
|
},
|
|
],
|
|
advancedColumn1: [
|
|
{
|
|
xtype: 'proxmoxcheckbox',
|
|
name: 'encrypted',
|
|
fieldLabel: gettext('Encrypt OSD'),
|
|
},
|
|
{
|
|
xtype: 'proxmoxKVComboBox',
|
|
comboItems: [
|
|
['hdd', 'HDD'],
|
|
['ssd', 'SSD'],
|
|
['nvme', 'NVMe'],
|
|
],
|
|
name: 'crush-device-class',
|
|
nodename: me.nodename,
|
|
fieldLabel: gettext('Device Class'),
|
|
value: '',
|
|
autoSelect: false,
|
|
allowBlank: true,
|
|
editable: true,
|
|
emptyText: 'auto detect',
|
|
deleteEmpty: !me.isCreate,
|
|
},
|
|
],
|
|
advancedColumn2: [
|
|
{
|
|
xtype: 'pmxDiskSelector',
|
|
name: 'wal_dev',
|
|
nodename: me.nodename,
|
|
diskType: 'journal_disks',
|
|
fieldLabel: gettext('WAL Disk'),
|
|
value: '',
|
|
autoSelect: false,
|
|
allowBlank: true,
|
|
emptyText: 'use OSD/DB disk',
|
|
listeners: {
|
|
change: function(field, val) {
|
|
me.down('field[name=wal_size]').setDisabled(!val);
|
|
},
|
|
},
|
|
},
|
|
{
|
|
xtype: 'numberfield',
|
|
name: 'wal_size',
|
|
fieldLabel: gettext('WAL size') + ' (GiB)',
|
|
minValue: 0.5,
|
|
maxValue: 128*1024,
|
|
decimalPrecision: 2,
|
|
allowBlank: true,
|
|
disabled: true,
|
|
emptyText: gettext('Automatic'),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
xtype: 'displayfield',
|
|
padding: '5 0 0 0',
|
|
userCls: 'pmx-hint',
|
|
value: 'Note: Ceph is not compatible with disks backed by a hardware ' +
|
|
'RAID controller. For details see ' +
|
|
'<a target="_blank" href="' + Proxmox.Utils.get_help_link('chapter_pveceph') + '">the reference documentation</a>.',
|
|
},
|
|
],
|
|
});
|
|
|
|
me.callParent();
|
|
},
|
|
});
|
|
|
|
Ext.define('PVE.CephRemoveOsd', {
|
|
extend: 'Proxmox.window.Edit',
|
|
alias: ['widget.pveCephRemoveOsd'],
|
|
|
|
isRemove: true,
|
|
|
|
showProgress: true,
|
|
method: 'DELETE',
|
|
items: [
|
|
{
|
|
xtype: 'proxmoxcheckbox',
|
|
name: 'cleanup',
|
|
checked: true,
|
|
labelWidth: 130,
|
|
fieldLabel: gettext('Cleanup Disks'),
|
|
},
|
|
],
|
|
initComponent: function() {
|
|
let me = this;
|
|
|
|
if (!me.nodename) {
|
|
throw "no node name specified";
|
|
}
|
|
if (me.osdid === undefined || me.osdid < 0) {
|
|
throw "no osdid specified";
|
|
}
|
|
|
|
me.isCreate = true;
|
|
|
|
me.title = gettext('Destroy') + ': Ceph OSD osd.' + me.osdid.toString();
|
|
|
|
Ext.applyIf(me, {
|
|
url: "/nodes/" + me.nodename + "/ceph/osd/" + me.osdid.toString(),
|
|
});
|
|
|
|
me.callParent();
|
|
},
|
|
});
|
|
|
|
Ext.define('PVE.CephSetFlags', {
|
|
extend: 'Proxmox.window.Edit',
|
|
xtype: 'pveCephSetFlags',
|
|
|
|
showProgress: true,
|
|
|
|
width: 720,
|
|
layout: 'fit',
|
|
|
|
onlineHelp: 'pve_ceph_osds',
|
|
isCreate: true,
|
|
title: Ext.String.format(gettext('Manage {0}'), 'Global OSD Flags'),
|
|
submitText: gettext('Apply'),
|
|
|
|
items: [
|
|
{
|
|
xtype: 'inputpanel',
|
|
onGetValues: function(values) {
|
|
let me = this;
|
|
let val = {};
|
|
me.down('#flaggrid').getStore().each((rec) => {
|
|
val[rec.data.name] = rec.data.value ? 1 : 0;
|
|
});
|
|
|
|
return val;
|
|
},
|
|
items: [
|
|
{
|
|
xtype: 'grid',
|
|
itemId: 'flaggrid',
|
|
store: {
|
|
listeners: {
|
|
update: function() {
|
|
this.commitChanges();
|
|
},
|
|
},
|
|
},
|
|
|
|
columns: [
|
|
{
|
|
text: gettext('Enable'),
|
|
xtype: 'checkcolumn',
|
|
width: 75,
|
|
dataIndex: 'value',
|
|
},
|
|
{
|
|
text: 'Name',
|
|
dataIndex: 'name',
|
|
},
|
|
{
|
|
text: 'Description',
|
|
flex: 1,
|
|
dataIndex: 'description',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
|
|
initComponent: function() {
|
|
let me = this;
|
|
|
|
if (!me.nodename) {
|
|
throw "no node name specified";
|
|
}
|
|
|
|
Ext.applyIf(me, {
|
|
url: "/cluster/ceph/flags",
|
|
method: 'PUT',
|
|
});
|
|
|
|
me.callParent();
|
|
|
|
let grid = me.down('#flaggrid');
|
|
me.load({
|
|
success: function(response, options) {
|
|
let data = response.result.data;
|
|
grid.getStore().setData(data);
|
|
// re-align after store load, else the window is not centered
|
|
me.alignTo(Ext.getBody(), 'c-c');
|
|
},
|
|
});
|
|
},
|
|
});
|
|
|
|
Ext.define('PVE.node.CephOsdTree', {
|
|
extend: 'Ext.tree.Panel',
|
|
alias: ['widget.pveNodeCephOsdTree'],
|
|
onlineHelp: 'chapter_pveceph',
|
|
|
|
viewModel: {
|
|
data: {
|
|
nodename: '',
|
|
flags: [],
|
|
maxversion: '0',
|
|
mixedversions: false,
|
|
versions: {},
|
|
isOsd: false,
|
|
downOsd: false,
|
|
upOsd: false,
|
|
inOsd: false,
|
|
outOsd: false,
|
|
osdid: '',
|
|
osdhost: '',
|
|
},
|
|
},
|
|
|
|
controller: {
|
|
xclass: 'Ext.app.ViewController',
|
|
|
|
reload: function() {
|
|
let me = this;
|
|
let view = me.getView();
|
|
let vm = me.getViewModel();
|
|
let nodename = vm.get('nodename');
|
|
let sm = view.getSelectionModel();
|
|
Proxmox.Utils.API2Request({
|
|
url: "/nodes/" + nodename + "/ceph/osd",
|
|
waitMsgTarget: view,
|
|
method: 'GET',
|
|
failure: function(response, opts) {
|
|
let msg = response.htmlStatus;
|
|
PVE.Utils.showCephInstallOrMask(view, msg, nodename, win =>
|
|
view.mon(win, 'cephInstallWindowClosed', me.reload),
|
|
);
|
|
},
|
|
success: function(response, opts) {
|
|
let data = response.result.data;
|
|
let selected = view.getSelection();
|
|
let name;
|
|
if (selected.length) {
|
|
name = selected[0].data.name;
|
|
}
|
|
vm.set('versions', data.versions);
|
|
// extract max version
|
|
let maxversion = "0";
|
|
let mixedversions = false;
|
|
let traverse;
|
|
traverse = function(node, fn) {
|
|
fn(node);
|
|
if (Array.isArray(node.children)) {
|
|
node.children.forEach(c => { traverse(c, fn); });
|
|
}
|
|
};
|
|
traverse(data.root, node => {
|
|
// compatibility for old api call
|
|
if (node.type === 'host' && !node.version) {
|
|
node.version = data.versions[node.name];
|
|
}
|
|
|
|
if (node.version === undefined) {
|
|
return;
|
|
}
|
|
|
|
if (node.version !== maxversion && maxversion !== "0") {
|
|
mixedversions = true;
|
|
}
|
|
|
|
if (PVE.Utils.compare_ceph_versions(node.version, maxversion) > 0) {
|
|
maxversion = node.version;
|
|
}
|
|
});
|
|
vm.set('maxversion', maxversion);
|
|
vm.set('mixedversions', mixedversions);
|
|
sm.deselectAll();
|
|
view.setRootNode(data.root);
|
|
view.expandAll();
|
|
if (name) {
|
|
let node = view.getRootNode().findChild('name', name, true);
|
|
if (node) {
|
|
view.setSelection([node]);
|
|
}
|
|
}
|
|
|
|
let flags = data.flags.split(',');
|
|
vm.set('flags', flags);
|
|
},
|
|
});
|
|
},
|
|
|
|
osd_cmd: function(comp) {
|
|
let me = this;
|
|
let vm = this.getViewModel();
|
|
let cmd = comp.cmd;
|
|
let params = comp.params || {};
|
|
let osdid = vm.get('osdid');
|
|
|
|
let doRequest = function() {
|
|
Proxmox.Utils.API2Request({
|
|
url: "/nodes/" + vm.get('osdhost') + "/ceph/osd/" + osdid + '/' + cmd,
|
|
waitMsgTarget: me.getView(),
|
|
method: 'POST',
|
|
params: params,
|
|
success: () => { me.reload(); },
|
|
failure: function(response, opts) {
|
|
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
|
|
},
|
|
});
|
|
};
|
|
|
|
if (cmd === 'scrub') {
|
|
Ext.MessageBox.defaultButton = params.deep === 1 ? 2 : 1;
|
|
Ext.Msg.show({
|
|
title: gettext('Confirm'),
|
|
icon: params.deep === 1 ? Ext.Msg.WARNING : Ext.Msg.QUESTION,
|
|
msg: params.deep !== 1
|
|
? Ext.String.format(gettext("Scrub OSD.{0}"), osdid)
|
|
: Ext.String.format(gettext("Deep Scrub OSD.{0}"), osdid) +
|
|
"<br>Caution: This can reduce performance while it is running.",
|
|
buttons: Ext.Msg.YESNO,
|
|
callback: function(btn) {
|
|
if (btn !== 'yes') {
|
|
return;
|
|
}
|
|
doRequest();
|
|
},
|
|
});
|
|
} else {
|
|
doRequest();
|
|
}
|
|
},
|
|
|
|
create_osd: function() {
|
|
let me = this;
|
|
let vm = this.getViewModel();
|
|
Ext.create('PVE.CephCreateOsd', {
|
|
nodename: vm.get('nodename'),
|
|
taskDone: () => { me.reload(); },
|
|
}).show();
|
|
},
|
|
|
|
destroy_osd: function() {
|
|
let me = this;
|
|
let vm = this.getViewModel();
|
|
Ext.create('PVE.CephRemoveOsd', {
|
|
nodename: vm.get('osdhost'),
|
|
osdid: vm.get('osdid'),
|
|
taskDone: () => { me.reload(); },
|
|
}).show();
|
|
},
|
|
|
|
set_flags: function() {
|
|
let me = this;
|
|
let vm = this.getViewModel();
|
|
Ext.create('PVE.CephSetFlags', {
|
|
nodename: vm.get('nodename'),
|
|
taskDone: () => { me.reload(); },
|
|
}).show();
|
|
},
|
|
|
|
service_cmd: function(comp) {
|
|
let me = this;
|
|
let vm = this.getViewModel();
|
|
let cmd = comp.cmd || comp;
|
|
Proxmox.Utils.API2Request({
|
|
url: "/nodes/" + vm.get('osdhost') + "/ceph/" + cmd,
|
|
params: { service: "osd." + vm.get('osdid') },
|
|
waitMsgTarget: me.getView(),
|
|
method: 'POST',
|
|
success: function(response, options) {
|
|
let upid = response.result.data;
|
|
let win = Ext.create('Proxmox.window.TaskProgress', {
|
|
upid: upid,
|
|
taskDone: () => { me.reload(); },
|
|
});
|
|
win.show();
|
|
},
|
|
failure: function(response, opts) {
|
|
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
|
|
},
|
|
});
|
|
},
|
|
|
|
set_selection_status: function(tp, selection) {
|
|
if (selection.length < 1) {
|
|
return;
|
|
}
|
|
let rec = selection[0];
|
|
let vm = this.getViewModel();
|
|
|
|
let isOsd = rec.data.host && rec.data.type === 'osd' && rec.data.id >= 0;
|
|
|
|
vm.set('isOsd', isOsd);
|
|
vm.set('downOsd', isOsd && rec.data.status === 'down');
|
|
vm.set('upOsd', isOsd && rec.data.status !== 'down');
|
|
vm.set('inOsd', isOsd && rec.data.in);
|
|
vm.set('outOsd', isOsd && !rec.data.in);
|
|
vm.set('osdid', isOsd ? rec.data.id : undefined);
|
|
vm.set('osdhost', isOsd ? rec.data.host : undefined);
|
|
},
|
|
|
|
render_status: function(value, metaData, rec) {
|
|
if (!value) {
|
|
return value;
|
|
}
|
|
let inout = rec.data.in ? 'in' : 'out';
|
|
let updownicon = value === 'up' ? 'good fa-arrow-circle-up'
|
|
: 'critical fa-arrow-circle-down';
|
|
|
|
let inouticon = rec.data.in ? 'good fa-circle'
|
|
: 'warning fa-circle-o';
|
|
|
|
let text = value + ' <i class="fa ' + updownicon + '"></i> / ' +
|
|
inout + ' <i class="fa ' + inouticon + '"></i>';
|
|
|
|
return text;
|
|
},
|
|
|
|
render_wal: function(value, metaData, rec) {
|
|
if (!value &&
|
|
rec.data.osdtype === 'bluestore' &&
|
|
rec.data.type === 'osd') {
|
|
return 'N/A';
|
|
}
|
|
return value;
|
|
},
|
|
|
|
render_version: function(value, metadata, rec) {
|
|
let vm = this.getViewModel();
|
|
let versions = vm.get('versions');
|
|
let icon = "";
|
|
let version = value || "";
|
|
let maxversion = vm.get('maxversion');
|
|
if (value && value !== maxversion) {
|
|
if (rec.data.type === 'host' || versions[rec.data.host] !== maxversion) {
|
|
icon = PVE.Utils.get_ceph_icon_html('HEALTH_UPGRADE');
|
|
} else {
|
|
icon = PVE.Utils.get_ceph_icon_html('HEALTH_OLD');
|
|
}
|
|
} else if (value && vm.get('mixedversions')) {
|
|
icon = PVE.Utils.get_ceph_icon_html('HEALTH_OK');
|
|
}
|
|
|
|
return icon + version;
|
|
},
|
|
|
|
render_osd_val: function(value, metaData, rec) {
|
|
return rec.data.type === 'osd' ? value : '';
|
|
},
|
|
render_osd_weight: function(value, metaData, rec) {
|
|
if (rec.data.type !== 'osd') {
|
|
return '';
|
|
}
|
|
return Ext.util.Format.number(value, '0.00###');
|
|
},
|
|
|
|
render_osd_latency: function(value, metaData, rec) {
|
|
if (rec.data.type !== 'osd') {
|
|
return '';
|
|
}
|
|
let commit_ms = rec.data.commit_latency_ms,
|
|
apply_ms = rec.data.apply_latency_ms;
|
|
return apply_ms + ' / ' + commit_ms;
|
|
},
|
|
|
|
render_osd_size: function(value, metaData, rec) {
|
|
return this.render_osd_val(Proxmox.Utils.render_size(value), metaData, rec);
|
|
},
|
|
|
|
control: {
|
|
'#': {
|
|
selectionchange: 'set_selection_status',
|
|
},
|
|
},
|
|
|
|
init: function(view) {
|
|
let me = this;
|
|
let vm = this.getViewModel();
|
|
|
|
if (!view.pveSelNode.data.node) {
|
|
throw "no node name specified";
|
|
}
|
|
|
|
vm.set('nodename', view.pveSelNode.data.node);
|
|
|
|
me.callParent();
|
|
me.reload();
|
|
},
|
|
},
|
|
|
|
stateful: true,
|
|
stateId: 'grid-ceph-osd',
|
|
rootVisible: false,
|
|
useArrows: true,
|
|
|
|
columns: [
|
|
{
|
|
xtype: 'treecolumn',
|
|
text: 'Name',
|
|
dataIndex: 'name',
|
|
width: 150,
|
|
},
|
|
{
|
|
text: 'Type',
|
|
dataIndex: 'type',
|
|
hidden: true,
|
|
align: 'right',
|
|
width: 75,
|
|
},
|
|
{
|
|
text: gettext("Class"),
|
|
dataIndex: 'device_class',
|
|
align: 'right',
|
|
width: 75,
|
|
},
|
|
{
|
|
text: "OSD Type",
|
|
dataIndex: 'osdtype',
|
|
align: 'right',
|
|
width: 100,
|
|
},
|
|
{
|
|
text: "Bluestore Device",
|
|
dataIndex: 'blfsdev',
|
|
align: 'right',
|
|
width: 75,
|
|
hidden: true,
|
|
},
|
|
{
|
|
text: "DB Device",
|
|
dataIndex: 'dbdev',
|
|
align: 'right',
|
|
width: 75,
|
|
hidden: true,
|
|
},
|
|
{
|
|
text: "WAL Device",
|
|
dataIndex: 'waldev',
|
|
align: 'right',
|
|
renderer: 'render_wal',
|
|
width: 75,
|
|
hidden: true,
|
|
},
|
|
{
|
|
text: 'Status',
|
|
dataIndex: 'status',
|
|
align: 'right',
|
|
renderer: 'render_status',
|
|
width: 120,
|
|
},
|
|
{
|
|
text: gettext('Version'),
|
|
dataIndex: 'version',
|
|
align: 'right',
|
|
renderer: 'render_version',
|
|
},
|
|
{
|
|
text: 'weight',
|
|
dataIndex: 'crush_weight',
|
|
align: 'right',
|
|
renderer: 'render_osd_weight',
|
|
width: 90,
|
|
},
|
|
{
|
|
text: 'reweight',
|
|
dataIndex: 'reweight',
|
|
align: 'right',
|
|
renderer: 'render_osd_weight',
|
|
width: 90,
|
|
},
|
|
{
|
|
text: gettext('Used') + ' (%)',
|
|
dataIndex: 'percent_used',
|
|
align: 'right',
|
|
renderer: function(value, metaData, rec) {
|
|
if (rec.data.type !== 'osd') {
|
|
return '';
|
|
}
|
|
return Ext.util.Format.number(value, '0.00');
|
|
},
|
|
width: 100,
|
|
},
|
|
{
|
|
text: gettext('Total'),
|
|
dataIndex: 'total_space',
|
|
align: 'right',
|
|
renderer: 'render_osd_size',
|
|
width: 100,
|
|
},
|
|
{
|
|
text: 'Apply/Commit<br>Latency (ms)',
|
|
dataIndex: 'apply_latency_ms',
|
|
align: 'right',
|
|
renderer: 'render_osd_latency',
|
|
width: 120,
|
|
},
|
|
],
|
|
|
|
|
|
tbar: {
|
|
items: [
|
|
{
|
|
text: gettext('Reload'),
|
|
iconCls: 'fa fa-refresh',
|
|
handler: 'reload',
|
|
},
|
|
'-',
|
|
{
|
|
text: gettext('Create') + ': OSD',
|
|
handler: 'create_osd',
|
|
},
|
|
{
|
|
text: Ext.String.format(gettext('Manage {0}'), 'Global Flags'),
|
|
handler: 'set_flags',
|
|
},
|
|
'->',
|
|
{
|
|
xtype: 'tbtext',
|
|
data: {
|
|
osd: undefined,
|
|
},
|
|
bind: {
|
|
data: {
|
|
osd: "{osdid}",
|
|
},
|
|
},
|
|
tpl: [
|
|
'<tpl if="osd">',
|
|
'osd.{osd}:',
|
|
'<tpl else>',
|
|
gettext('No OSD selected'),
|
|
'</tpl>',
|
|
],
|
|
},
|
|
{
|
|
text: gettext('Start'),
|
|
iconCls: 'fa fa-play',
|
|
disabled: true,
|
|
bind: {
|
|
disabled: '{!downOsd}',
|
|
},
|
|
cmd: 'start',
|
|
handler: 'service_cmd',
|
|
},
|
|
{
|
|
text: gettext('Stop'),
|
|
iconCls: 'fa fa-stop',
|
|
disabled: true,
|
|
bind: {
|
|
disabled: '{!upOsd}',
|
|
},
|
|
cmd: 'stop',
|
|
handler: 'service_cmd',
|
|
},
|
|
{
|
|
text: gettext('Restart'),
|
|
iconCls: 'fa fa-refresh',
|
|
disabled: true,
|
|
bind: {
|
|
disabled: '{!upOsd}',
|
|
},
|
|
cmd: 'restart',
|
|
handler: 'service_cmd',
|
|
},
|
|
'-',
|
|
{
|
|
text: 'Out',
|
|
iconCls: 'fa fa-circle-o',
|
|
disabled: true,
|
|
bind: {
|
|
disabled: '{!inOsd}',
|
|
},
|
|
cmd: 'out',
|
|
handler: 'osd_cmd',
|
|
},
|
|
{
|
|
text: 'In',
|
|
iconCls: 'fa fa-circle',
|
|
disabled: true,
|
|
bind: {
|
|
disabled: '{!outOsd}',
|
|
},
|
|
cmd: 'in',
|
|
handler: 'osd_cmd',
|
|
},
|
|
'-',
|
|
{
|
|
text: gettext('More'),
|
|
iconCls: 'fa fa-bars',
|
|
disabled: true,
|
|
bind: {
|
|
disabled: '{!isOsd}',
|
|
},
|
|
menu: [
|
|
{
|
|
text: gettext('Scrub'),
|
|
iconCls: 'fa fa-shower',
|
|
cmd: 'scrub',
|
|
handler: 'osd_cmd',
|
|
},
|
|
{
|
|
text: gettext('Deep Scrub'),
|
|
iconCls: 'fa fa-bath',
|
|
cmd: 'scrub',
|
|
params: {
|
|
deep: 1,
|
|
},
|
|
handler: 'osd_cmd',
|
|
},
|
|
{
|
|
text: gettext('Destroy'),
|
|
itemId: 'remove',
|
|
iconCls: 'fa fa-fw fa-trash-o',
|
|
bind: {
|
|
disabled: '{!downOsd}',
|
|
},
|
|
handler: 'destroy_osd',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
|
|
fields: [
|
|
'name', 'type', 'status', 'host', 'in', 'id',
|
|
{ type: 'number', name: 'reweight' },
|
|
{ type: 'number', name: 'percent_used' },
|
|
{ type: 'integer', name: 'bytes_used' },
|
|
{ type: 'integer', name: 'total_space' },
|
|
{ type: 'integer', name: 'apply_latency_ms' },
|
|
{ type: 'integer', name: 'commit_latency_ms' },
|
|
{ type: 'string', name: 'device_class' },
|
|
{ type: 'string', name: 'osdtype' },
|
|
{ type: 'string', name: 'blfsdev' },
|
|
{ type: 'string', name: 'dbdev' },
|
|
{ type: 'string', name: 'waldev' },
|
|
{
|
|
type: 'string', name: 'version', calculate: function(data) {
|
|
return PVE.Utils.parse_ceph_version(data);
|
|
},
|
|
},
|
|
{
|
|
type: 'string', name: 'iconCls', calculate: function(data) {
|
|
let iconMap = {
|
|
host: 'fa-building',
|
|
osd: 'fa-hdd-o',
|
|
root: 'fa-server',
|
|
};
|
|
return 'fa x-fa-tree ' + iconMap[data.type];
|
|
},
|
|
},
|
|
{ type: 'number', name: 'crush_weight' },
|
|
],
|
|
});
|