[pve-devel] [PATCH manager 4/7] ui: ceph pool: add rbd namespace panel

Aaron Lauterer a.lauterer at proxmox.com
Fri Dec 6 14:55:11 CET 2024


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.lauterer at proxmox.com>
---
the overall idea on how to handle the relationship between the two grid
panels was taken from the vnet firewall panel.

 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 9346c939..a4ae4c71 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',
@@ -278,9 +313,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' }],
 
@@ -411,11 +449,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', {
@@ -449,6 +488,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,
@@ -532,10 +590,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', {
@@ -605,3 +665,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





More information about the pve-devel mailing list