From 6757887a5d1a4646f9093c590a9b49565d7cd3c3 Mon Sep 17 00:00:00 2001 From: Aaron Lauterer Date: Mon, 12 Dec 2022 13:14:51 +0100 Subject: [PATCH] ui: osd: add details window MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This new windows provides more detailes about an OSD such as: * PID * Memory usage * various metadata that could be of interest * list of phyiscal disks used for the main disk, db and wal with additional infos about the volumes for each A new 'Details' button is added to the OSD overview and a double click on an OSD will also open this new window. The componend defines the items in the initComponent instead of following a fully declarative approach. This is because we need to pass the same store to multiple Proxmox.ObjectGrids. Signed-off-by: Aaron Lauterer Reviewed-by: Dominik Csapak Tested-by:  Dominik Csapak --- www/manager6/Makefile | 1 + www/manager6/ceph/OSD.js | 26 +++ www/manager6/ceph/OSDDetails.js | 280 ++++++++++++++++++++++++++++++++ 3 files changed, 307 insertions(+) create mode 100644 www/manager6/ceph/OSDDetails.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index b73b729a..2b577c8e 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -188,6 +188,7 @@ JSSRC= \ ceph/Log.js \ ceph/Monitor.js \ ceph/OSD.js \ + ceph/OSDDetails.js \ ceph/Pool.js \ ceph/ServiceList.js \ ceph/Services.js \ diff --git a/www/manager6/ceph/OSD.js b/www/manager6/ceph/OSD.js index ff21bc6f..ebdcc46a 100644 --- a/www/manager6/ceph/OSD.js +++ b/www/manager6/ceph/OSD.js @@ -583,6 +583,20 @@ Ext.define('PVE.node.CephOsdTree', { } }, + run_details: function(view, rec) { + if (rec.data.host && rec.data.type === 'osd' && rec.data.id >= 0) { + this.details(); + } + }, + + details: function() { + let vm = this.getViewModel(); + Ext.create('PVE.CephOsdDetails', { + nodename: vm.get('osdhost'), + osdid: vm.get('osdid'), + }).show(); + }, + set_selection_status: function(tp, selection) { if (selection.length < 1) { return; @@ -695,6 +709,9 @@ Ext.define('PVE.node.CephOsdTree', { stateId: 'grid-ceph-osd', rootVisible: false, useArrows: true, + listeners: { + itemdblclick: 'run_details', + }, columns: [ { @@ -842,6 +859,15 @@ Ext.define('PVE.node.CephOsdTree', { '', ], }, + { + text: gettext('Details'), + iconCls: 'fa fa-info-circle', + disabled: true, + bind: { + disabled: '{!isOsd}', + }, + handler: 'details', + }, { text: gettext('Start'), iconCls: 'fa fa-play', diff --git a/www/manager6/ceph/OSDDetails.js b/www/manager6/ceph/OSDDetails.js new file mode 100644 index 00000000..24af8f15 --- /dev/null +++ b/www/manager6/ceph/OSDDetails.js @@ -0,0 +1,280 @@ +Ext.define('pve-osd-details-devices', { + extend: 'Ext.data.Model', + fields: ['device', 'type', 'physical_device', 'size', 'support_discard', 'dev_node'], + idProperty: 'device', +}); + +Ext.define('PVE.CephOsdDetails', { + extend: 'Ext.window.Window', + alias: ['widget.pveCephOsdDetails'], + + mixins: ['Proxmox.Mixin.CBind'], + + cbindData: function() { + let me = this; + me.baseUrl = `/nodes/${me.nodename}/ceph/osd/${me.osdid}`; + return { + title: `${gettext('Details')}: OSD ${me.osdid}`, + }; + }, + + viewModel: { + data: { + device: '', + }, + }, + + modal: true, + width: 650, + minHeight: 250, + resizable: true, + cbind: { + title: '{title}', + }, + + layout: { + type: 'vbox', + align: 'stretch', + }, + defaults: { + layout: 'fit', + border: false, + }, + + controller: { + xclass: 'Ext.app.ViewController', + + reload: function() { + let view = this.getView(); + + Proxmox.Utils.API2Request({ + url: `${view.baseUrl}/metadata`, + waitMsgTarget: view.lookup('detailsTabs'), + method: 'GET', + failure: function(response, opts) { + Proxmox.Utils.setErrorMask(view.lookup('detailsTabs'), response.htmlStatus); + }, + success: function(response, opts) { + let d = response.result.data; + let osdData = Object.keys(d.osd).sort().map(x => ({ key: x, value: d.osd[x] })); + view.osdStore.loadData(osdData); + let devices = view.lookup('devices'); + let deviceStore = devices.getStore(); + deviceStore.loadData(d.devices); + + view.lookup('osdGeneral').rstore.fireEvent('load', view.osdStore, osdData, true); + view.lookup('osdNetwork').rstore.fireEvent('load', view.osdStore, osdData, true); + + // select 'block' device automatically on first load + if (devices.getSelection().length === 0) { + devices.setSelection(deviceStore.findRecord('device', 'block')); + } + }, + }); + }, + + showDevInfo: function(grid, selected) { + let view = this.getView(); + if (selected[0]) { + let device = selected[0].data.device; + this.getViewModel().set('device', device); + + let detailStore = view.lookup('volumeDetails'); + detailStore.rstore.getProxy().setUrl(`api2/json${view.baseUrl}/lv-info`); + detailStore.rstore.getProxy().setExtraParams({ 'type': device }); + detailStore.setLoading(); + detailStore.rstore.load({ callback: () => detailStore.setLoading(false) }); + } + }, + + init: function() { + this.reload(); + }, + + control: { + 'grid[reference=devices]': { + selectionchange: 'showDevInfo', + }, + }, + }, + tbar: [ + { + text: gettext('Reload'), + iconCls: 'fa fa-refresh', + handler: 'reload', + }, + ], + initComponent: function() { + let me = this; + + me.osdStore = Ext.create('Proxmox.data.ObjectStore'); + + Ext.applyIf(me, { + items: [ + { + xtype: 'tabpanel', + reference: 'detailsTabs', + items: [ + { + xtype: 'proxmoxObjectGrid', + reference: 'osdGeneral', + tooltip: gettext('Various information about the OSD'), + rstore: me.osdStore, + title: gettext('General'), + viewConfig: { + enableTextSelection: true, + }, + gridRows: [ + { + xtype: 'text', + name: 'version', + text: gettext('Version'), + }, + { + xtype: 'text', + name: 'hostname', + text: gettext('Hostname'), + }, + { + xtype: 'text', + name: 'osd_data', + text: gettext('OSD data path'), + }, + { + xtype: 'text', + name: 'osd_objectstore', + text: gettext('OSD object store'), + }, + { + xtype: 'text', + name: 'mem_usage', + text: gettext('Memory usage'), + renderer: Proxmox.Utils.render_size, + }, + { + xtype: 'text', + name: 'pid', + text: `${gettext('Process ID')} (PID)`, + }, + ], + }, + { + xtype: 'proxmoxObjectGrid', + reference: 'osdNetwork', + tooltip: gettext('Addresses and ports used by the OSD service'), + rstore: me.osdStore, + title: gettext('Network'), + viewConfig: { + enableTextSelection: true, + }, + gridRows: [ + { + xtype: 'text', + name: 'front_addr', + text: `${gettext('Front Address')}
(Client & Monitor)`, + renderer: PVE.Utils.render_ceph_osd_addr, + }, + { + xtype: 'text', + name: 'hb_front_addr', + text: gettext('Heartbeat Front Address'), + renderer: PVE.Utils.render_ceph_osd_addr, + }, + { + xtype: 'text', + name: 'back_addr', + text: `${gettext('Back Address')}
(OSD)`, + renderer: PVE.Utils.render_ceph_osd_addr, + }, + { + xtype: 'text', + name: 'hb_back_addr', + text: gettext('Heartbeat Back Address'), + renderer: PVE.Utils.render_ceph_osd_addr, + }, + ], + }, + { + xtype: 'panel', + title: 'Devices', + tooltip: gettext('Physical devices used by the OSD'), + items: [ + { + xtype: 'grid', + border: false, + reference: 'devices', + store: { + model: 'pve-osd-details-devices', + }, + columns: { + items: [ + { text: gettext('Device'), dataIndex: 'device' }, + { text: gettext('Type'), dataIndex: 'type' }, + { + text: gettext('Physical Device'), + dataIndex: 'physical_device', + }, + { + text: gettext('Size'), + dataIndex: 'size', + renderer: Proxmox.Utils.render_size, + }, + { + text: 'Discard', + dataIndex: 'support_discard', + hidden: true, + }, + { + text: gettext('Device node'), + dataIndex: 'dev_node', + hidden: true, + }, + ], + defaults: { + tdCls: 'pointer', + flex: 1, + }, + }, + }, + { + xtype: 'proxmoxObjectGrid', + reference: 'volumeDetails', + maskOnLoad: true, + viewConfig: { + enableTextSelection: true, + }, + bind: { + title: Ext.String.format( + gettext('Volume Details for {0}'), + '{device}', + ), + }, + rows: { + creation_time: { + header: gettext('Creation time'), + }, + lv_name: { + header: gettext('LV Name'), + }, + lv_path: { + header: gettext('LV Path'), + }, + lv_uuid: { + header: gettext('LV UUID'), + }, + vg_name: { + header: gettext('VG Name'), + }, + }, + url: 'nodes/', //placeholder will be set when device is selected + }, + ], + }, + ], + }, + ], + }); + + me.callParent(); + }, +}); -- 2.39.2