From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id D183F1FF16E for ; Mon, 23 Dec 2024 17:00:58 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 556ACB4A1; Mon, 23 Dec 2024 17:00:47 +0100 (CET) From: Aaron Lauterer To: pve-devel@lists.proxmox.com Date: Mon, 23 Dec 2024 17:00:05 +0100 Message-Id: <20241223160008.218710-4-a.lauterer@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241223160008.218710-1-a.lauterer@proxmox.com> References: <20241223160008.218710-1-a.lauterer@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.036 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH manager v2 3/6] ui: ceph pool: add rbd namespace panel 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: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" 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 --- 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