public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Dominik Csapak <d.csapak@proxmox.com>
To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>,
	Aaron Lauterer <a.lauterer@proxmox.com>
Subject: Re: [pve-devel] [PATCH manager v2 4/4] ui: osd: add details window
Date: Mon, 17 Oct 2022 16:30:07 +0200	[thread overview]
Message-ID: <d32bdd0a-4e82-4307-6b61-3030d7bdbef6@proxmox.com> (raw)
In-Reply-To: <20220706130126.282308-5-a.lauterer@proxmox.com>

comments inline:

On 7/6/22 15:01, Aaron Lauterer wrote:
> 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 <a.lauterer@proxmox.com>
> ---
> changes since v2:
> - adapting API urls
> - renaming me.url to me.baseUrl
> 
>   www/manager6/Makefile           |   1 +
>   www/manager6/ceph/OSD.js        |  26 +++
>   www/manager6/ceph/OSDDetails.js | 289 ++++++++++++++++++++++++++++++++
>   3 files changed, 316 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', {
>   		    '</tpl>',
>   		],
>   	    },
> +	    {
> +		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..738aa227
> --- /dev/null
> +++ b/www/manager6/ceph/OSDDetails.js
> @@ -0,0 +1,289 @@
> +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.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,
> +		method: 'GET',
> +		failure: function(response, opts) {
> +		    Proxmox.Utils.setErrorMask(view, response.htmlStatus);

the 'view' here is the whole window, in case of an error, we even mask the
'close' button. better use the tabpanel, or wrap the toolbar + tabpanel in
a panel which you can then use

> +		},
> +		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);

map_data is only used once, so it could be done inline?

> +		    d.bdev.device = 'block';

wouldn't it make sense to do that in the api?

> +		    let devData = [d.bdev];
> +		    if (d.db) {
> +			d.db.device = 'db';

same here?

> +			devData.push(d.db);
> +		    }
> +		    if (d.wal) {
> +			d.wal.device = 'wal';

and here?

> +			devData.push(d.wal);

also seeing this, wouldn't it make sense to just return a 'devices' array
from the api instead of building it here in the ui?

i know it's not very likely that we get another device type, but since
we are now inventing it, shouldn't it match with what we expect in the gui?
(one could argue that having it the current way makes for a nicer api, since
i can directly access the properties... mhmm)

> +		    }
> +		    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.baseUrl}/lv-info`);
> +		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;

AFAIR, these can be specified on the grid with 'viewConfig', e.g.
having the following in the grid config:

viewConfig: {
	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')}<br>(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')}<br>(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',
> +				    maskOnLoad: 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();
> +    },
> +});





  reply	other threads:[~2022-10-17 14:30 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-06 13:01 [pve-devel] [PATCH widget-toolkit/manager v2 0/4] Ceph OSD: add detail infos Aaron Lauterer
2022-07-06 13:01 ` [pve-devel] [PATCH widget-toolkit v2 1/4] ObjectGrid: optionally show loading mask on load Aaron Lauterer
2022-10-17 14:29   ` Dominik Csapak
2022-07-06 13:01 ` [pve-devel] [PATCH manager v2 2/4] api ceph osd: add OSD index, metadata and lv-info Aaron Lauterer
2022-10-17 14:29   ` Dominik Csapak
2022-07-06 13:01 ` [pve-devel] [PATCH manager v2 3/4] ui utils: add renderer for ceph osd addresses Aaron Lauterer
2022-10-17 14:29   ` Dominik Csapak
2022-07-06 13:01 ` [pve-devel] [PATCH manager v2 4/4] ui: osd: add details window Aaron Lauterer
2022-10-17 14:30   ` Dominik Csapak [this message]
2022-10-12 12:09 ` [pve-devel] [PATCH widget-toolkit/manager v2 0/4] Ceph OSD: add detail infos Aaron Lauterer
2022-10-17 14:29 ` Dominik Csapak
2022-10-18  9:14   ` Aaron Lauterer
2022-10-19  6:46     ` Dominik Csapak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d32bdd0a-4e82-4307-6b61-3030d7bdbef6@proxmox.com \
    --to=d.csapak@proxmox.com \
    --cc=a.lauterer@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal