This needs a bit of a rework of the Ceph Pool panel because we want to have it right next/below to the pool grid. Additionally we want to en-/disable it if the select pool has RBD as application enabled.
Therefore we introduce a new small panel (Ceph.PoolView) that holds the pool and namespace grid. By passing a reference of the namespace grid into the pool grid, we can control the namespace grid directly from the pool grid. This also means that we need to redirect the submenu in Config.js to use the new intermediate Ceph.PoolView panel instead of the pool grid directly. Signed-off-by: Aaron Lauterer <a.laute...@proxmox.com> --- changes since v1: none www/manager6/ceph/Pool.js | 222 +++++++++++++++++++++++++++++++++++- www/manager6/node/Config.js | 3 +- 2 files changed, 223 insertions(+), 2 deletions(-) diff --git a/www/manager6/ceph/Pool.js b/www/manager6/ceph/Pool.js index c7e5e480..57fb9732 100644 --- a/www/manager6/ceph/Pool.js +++ b/www/manager6/ceph/Pool.js @@ -1,3 +1,38 @@ +Ext.define('PVE.node.Ceph.PoolView', { + extend: 'Ext.panel.Panel', + alias: 'widget.pveNodeCephPoolView', + + onlineHelp: 'pve_ceph_pools', + scrollable: 'y', + + initComponent: function() { + let me = this; + + let RbdNamespacePanel = Ext.createWidget('pveNodeCephRbdNamespacelist', { + region: 'south', + height: '50%', + border: false, + disabled: true, + xtype: 'pveNodeCephRbdNamespacelist', + nodename: me.nodename, + }); + let poolPanel = Ext.createWidget('pveNodeCephPoolList', { + region: 'center', + border: 'false', + xtype: 'pveNodeCephPoolList', + nodename: me.nodename, + RbdNamespacePanel, + }); + + Ext.apply(me, { + layout: 'border', + items: [poolPanel, RbdNamespacePanel], + }); + + me.callParent(); + }, +}); + Ext.define('PVE.CephPoolInputPanel', { extend: 'Proxmox.panel.InputPanel', xtype: 'pveCephPoolInputPanel', @@ -280,9 +315,12 @@ Ext.define('PVE.node.Ceph.PoolList', { onlineHelp: 'chapter_pveceph', + title: gettext('Ceph Pools'), + stateful: true, stateId: 'grid-ceph-pools', bufferedRenderer: false, + RbdNamespacePanel: undefined, features: [{ ftype: 'summary' }], @@ -413,11 +451,12 @@ Ext.define('PVE.node.Ceph.PoolList', { initComponent: function() { var me = this; - var nodename = me.pveSelNode.data.node; + var nodename = me.nodename; if (!nodename) { throw "no node name specified"; } + var sm = Ext.create('Ext.selection.RowModel', {}); var rstore = Ext.create('Proxmox.data.UpdateStore', { @@ -451,6 +490,25 @@ Ext.define('PVE.node.Ceph.PoolList', { }); }; + let item_selected = function(record, item, index) { + if ('rbd' in item.data.application_metadata) { + let poolname = item.id; + + me.RbdNamespacePanel.poolname = poolname; + let ns_store = me.RbdNamespacePanel.getStore(); + ns_store.setData([]); + ns_store.setProxy({ + type: 'proxmox', + url: `/api2/json/nodes/${nodename}/ceph/pool/${poolname}/namespace`, + }); + ns_store.load(); + me.RbdNamespacePanel.setDisabled(false); + } else { + me.RbdNamespacePanel.getStore().setData([]); + me.RbdNamespacePanel.setDisabled(true); + } + }; + Ext.apply(me, { store: store, selModel: sm, @@ -534,10 +592,12 @@ Ext.define('PVE.node.Ceph.PoolList', { activate: () => rstore.startUpdate(), destroy: () => rstore.stopUpdate(), itemdblclick: run_editor, + select: item_selected, }, }); me.callParent(); + me.store.rstore.load(); }, }, function() { Ext.define('ceph-pool-list', { @@ -608,3 +668,163 @@ Ext.define('PVE.form.CephRuleSelector', { }, }); + + +Ext.define('PVE.node.Ceph.RbdNamespaceList', { + extend: 'Ext.grid.GridPanel', + alias: 'widget.pveNodeCephRbdNamespacelist', + + onlineHelp: 'chapter_pveceph', + + title: gettext('RBD Namespaces'), + + emptyText: gettext('No RBD namespace configured'), + + stateful: true, + stateId: 'grid-ceph-rbd-namespaces', + bufferedRenderer: false, + + poolname: undefined, + viewConfig: { + enableTextSelection: true, + }, + + columns: [ + { + text: gettext('Namespace'), + minWidth: 120, + flex: 2, + sortable: true, + dataIndex: 'name', + }, + ], + initComponent: function() { + var me = this; + + var nodename = me.nodename; + if (!nodename) { + throw "no node name specified"; + } + + + var sm = Ext.create('Ext.selection.RowModel', {}); + + var rstore = Ext.create('Proxmox.data.UpdateStore', { + interval: 3000, + storeid: 'ceph-rbd-namespace-list' + nodename, + model: 'ceph-rbd-namespace-list', + proxy: { + type: 'proxmox', + url: `/api2/json/nodes/${nodename}/ceph/pool/rbd/namespace`, + }, + }); + let store = Ext.create('Proxmox.data.DiffStore', { rstore: rstore }); + + // manages the "install ceph?" overlay + PVE.Utils.monitor_ceph_installed(me, rstore, nodename); + + var run_editor = function() { + let rec = sm.getSelection()[0]; + if (!rec || !rec.data.pool_name) { + return; + } + Ext.create('PVE.Ceph.PoolEdit', { + title: gettext('Edit') + ': Ceph Pool', + nodename: nodename, + pool_name: rec.data.pool_name, + isErasure: rec.data.type === 'erasure', + autoShow: true, + listeners: { + destroy: () => rstore.load(), + }, + }); + }; + + Ext.apply(me, { + store: store, + selModel: sm, + tbar: [ + { + text: gettext('Create'), + handler: function() { + Ext.create('Proxmox.window.Edit', { + title: gettext('Create') + ': Ceph RBD Namespace', + isCreate: true, + nodename: nodename, + url: `/nodes/${nodename}/ceph/pool/${me.poolname}/namespace`, + method: 'POST', + autoShow: true, + listeners: { + destroy: () => rstore.load(), + }, + items: [ + { + xtype: 'textfield', + fieldLabel: gettext('Namespace'), + name: 'namespace', + emptyText: gettext('Namespace'), + }, + { + xtype: 'proxmoxcheckbox', + fieldLabel: gettext('Add as Storage'), + value: true, + name: 'add-storage', + autoEl: { + tag: 'div', + 'data-qtip': gettext('Add the new RBD namespace to the cluster storage configuration.'), + }, + }, + ], + }); + }, + }, + { + xtype: 'proxmoxButton', + text: gettext('Destroy'), + selModel: sm, + disabled: true, + handler: function() { + let rec = sm.getSelection()[0]; + if (!rec || !rec.data.name) { + return; + } + let poolName = me.poolname; + let namespace = rec.data.name; + Ext.create('Proxmox.window.SafeDestroy', { + showProgress: true, + url: `/nodes/${nodename}/ceph/pool/${poolName}/namespace`, + params: { + namespace: namespace, + }, + item: { + type: 'RbdNamespace', + id: namespace, + }, + taskName: 'cephdestroyrbdnamespace', + autoShow: true, + listeners: { + destroy: () => rstore.load(), + }, + }); + }, + }, + ], + listeners: { + activate: () => rstore.startUpdate(), + destroy: () => rstore.stopUpdate(), + itemdblclick: run_editor, + }, + }); + + me.callParent(); + }, +}, function() { + Ext.define('ceph-rbd-namespace-list', { + extend: 'Ext.data.Model', + fields: ['name', + { name: 'name', type: 'string' }, + ], + idProperty: 'name', + }); +}); + diff --git a/www/manager6/node/Config.js b/www/manager6/node/Config.js index f4d3ff8a..db9368ad 100644 --- a/www/manager6/node/Config.js +++ b/www/manager6/node/Config.js @@ -391,10 +391,11 @@ Ext.define('PVE.node.Config', { itemId: 'ceph-cephfspanel', }, { - xtype: 'pveNodeCephPoolList', + xtype: 'pveNodeCephPoolView', title: gettext('Pools'), iconCls: 'fa fa-sitemap', groups: ['ceph'], + nodename: nodename, itemId: 'ceph-pools', }, { -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel