From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id F2CB47929F for ; Fri, 1 Jul 2022 16:16:47 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id C5CB5A795 for ; Fri, 1 Jul 2022 16:16:47 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Fri, 1 Jul 2022 16:16:45 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id E5D8643DAA for ; Fri, 1 Jul 2022 16:16:44 +0200 (CEST) From: Aaron Lauterer To: pve-devel@lists.proxmox.com Date: Fri, 1 Jul 2022 16:16:42 +0200 Message-Id: <20220701141642.2743824-6-a.lauterer@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220701141642.2743824-1-a.lauterer@proxmox.com> References: <20220701141642.2743824-1-a.lauterer@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.168 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment POISEN_SPAM_PILL 0.1 Meta: its spam POISEN_SPAM_PILL_2 0.1 random spam to be learned in bayes POISEN_SPAM_PILL_4 0.1 random spam to be learned in bayes SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pve-devel] [PATCH manager 5/5] ui: osd: add details window X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 01 Jul 2022 14:16:48 -0000 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. Signed-off-by: Aaron Lauterer --- I decided to add a new .js file for the details window because OSD.js is already close to 900 lines long. www/manager6/Makefile | 1 + www/manager6/ceph/OSD.js | 26 +++ www/manager6/ceph/OSDDetails.js | 286 ++++++++++++++++++++++++++++++++ 3 files changed, 313 insertions(+) create mode 100644 www/manager6/ceph/OSDDetails.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index d16770b1..2535aaea 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -179,6 +179,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 78f226ff..75855f95 100644 --- a/www/manager6/ceph/OSD.js +++ b/www/manager6/ceph/OSD.js @@ -481,6 +481,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; @@ -593,6 +607,9 @@ Ext.define('PVE.node.CephOsdTree', { stateId: 'grid-ceph-osd', rootVisible: false, useArrows: true, + listeners: { + itemdblclick: 'run_details', + }, columns: [ { @@ -733,6 +750,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..e7e4e5da --- /dev/null +++ b/www/manager6/ceph/OSDDetails.js @@ -0,0 +1,286 @@ +Ext.define('pve-osd-details-devices', { + extend: 'Ext.data.Model', + fields: ['device', 'type', 'devices', '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.url = `/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.url, + waitMsgTarget: view, + method: 'GET', + failure: function(response, opts) { + Proxmox.Utils.setErrorMask(view, response.htmlStatus); + }, + success: function(response, opts) { + let d = response.result.data; + let map_data = function(data) { + return Object.keys(data).sort().map(x => ({ key: x, value: data[x] })); + }; + let osdData = map_data(d.osd); + d.bdev.device = 'block'; + let devData = [d.bdev]; + if (d.db) { + d.db.device = 'db'; + devData.push(d.db); + } + if (d.wal) { + d.wal.device = 'wal'; + devData.push(d.wal); + } + view.osdStore.loadData(osdData); + let devices = view.lookup('devices'); + let deviceStore = devices.getStore(); + deviceStore.loadData(devData); + + 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.url}/volume`); + detailStore.rstore.getProxy().setExtraParams({ 'type': device }); + detailStore.reload(); + } + }, + + init: function() { + let me = this; + let view = me.getView(); + view.lookup('osdGeneral').down('tableview').enableTextSelection=true; + view.lookup('osdNetwork').down('tableview').enableTextSelection=true; + view.lookup('volumeDetails').down('tableview').enableTextSelection=true; + + me.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'), + 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'), + 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('Name'), dataIndex: 'device' }, + { text: gettext('Type'), dataIndex: 'type' }, + { + text: gettext('Physical Devices'), + dataIndex: 'devices', + }, + { + 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', + showReloading: 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.30.2