* [pve-devel] [PATCH manager, docs v3 0/6] Ceph: add RBD Namespace management
@ 2025-04-04 14:53 Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 1/6] api: ceph: add rbd namespace management endpoints Aaron Lauterer
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Aaron Lauterer @ 2025-04-04 14:53 UTC (permalink / raw)
To: pve-devel
The series adds the necessary API endpoints and GUI to manage RBD
namespaces in a HCI cluster. The Ceph Pool panel in the UI needed a bit
more work to fit in a new grid for the namespaces. More in the actual
patch (3/6).
Additional future work can be made, for example to add a new scan option
for the RBD storage backend that scans for namespaces. But that only has
a tangential relationship to this series.
changes since
v2:
a more thorough change in the backend and cleaner implementation in the
UI. More in the appropriate patches
v1:
Only on patch 1/6, integrating the feedback received. More details in
the patch itself.
manager: Aaron Lauterer (5):
api: ceph: add rbd namespace management endpoints
pveceph: add pool namespace subcommands
ui: ceph pool: add rbd namespace panel
ui: utils: add ceph rbd namespace task names
ui: storage rbd: remove hint for manual rbd namespace creation
PVE/API2/Ceph/Pool.pm | 203 ++++++++++++++++++++++++++-
PVE/CLI/pveceph.pm | 9 ++
www/manager6/Utils.js | 2 +
www/manager6/ceph/Pool.js | 237 +++++++++++++++++++++++++++++++-
www/manager6/node/Config.js | 3 +-
www/manager6/storage/RBDEdit.js | 21 ---
6 files changed, 450 insertions(+), 25 deletions(-)
docs: Aaron Lauterer (1):
pveceph: add section for rbd namespaces
pveceph.adoc | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pve-devel] [PATCH manager v3 1/6] api: ceph: add rbd namespace management endpoints
2025-04-04 14:53 [pve-devel] [PATCH manager, docs v3 0/6] Ceph: add RBD Namespace management Aaron Lauterer
@ 2025-04-04 14:53 ` Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 2/6] pveceph: add pool namespace subcommands Aaron Lauterer
` (4 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Aaron Lauterer @ 2025-04-04 14:53 UTC (permalink / raw)
To: pve-devel
RBD supports namespaces. To make the management easier and possible via
the web UI, we need to add API endpoints to:
* list
* create
* delete
namespaces.
We only allow creatng namespaces for pools that have the RBD application
set.
Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
---
changes since
v2:
* use long params instead of positional ones when calling `rbd`
* remove default pool name 'rbd'. we are not the `rbd` utility, we can
require the parameter from the caller at all times
* limit the namespace name pattern to pve-storage-id. this is a safety
precaution to avoid any special characters in the namespace name.
* some smaller style and bug fixes
v1:
* integrated recommendations:
* code style in many places
* added check on removal if a storage config that uses the namespace
exists. I can be overriden with the new optional force flag
* on create we trim the namespace parameter and check if it has any
length. Is there an option in the API that would do that for us
already?
* added TODO note as we might want to rethink the ACL privileges
PVE/API2/Ceph/Pool.pm | 203 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 201 insertions(+), 2 deletions(-)
diff --git a/PVE/API2/Ceph/Pool.pm b/PVE/API2/Ceph/Pool.pm
index 5ee982f4..b34c3306 100644
--- a/PVE/API2/Ceph/Pool.pm
+++ b/PVE/API2/Ceph/Pool.pm
@@ -3,6 +3,8 @@ package PVE::API2::Ceph::Pool;
use strict;
use warnings;
+use JSON qw(decode_json);
+
use PVE::Ceph::Tools;
use PVE::Ceph::Services;
use PVE::JSONSchema qw(get_standard_option parse_property_string);
@@ -10,7 +12,7 @@ use PVE::RADOS;
use PVE::RESTHandler;
use PVE::RPCEnvironment;
use PVE::Storage;
-use PVE::Tools qw(extract_param);
+use PVE::Tools qw(extract_param run_command);
use PVE::API2::Storage::Config;
@@ -32,6 +34,7 @@ my $get_autoscale_status = sub {
return $data;
};
+# TODO: think about adding dedicated Ceph ACL privileges as the currently used ones don't match well
__PACKAGE__->register_method ({
name => 'lspools',
@@ -302,7 +305,7 @@ my $ceph_pool_common_options = sub {
my $add_storage = sub {
- my ($pool, $storeid, $ec_data_pool) = @_;
+ my ($pool, $storeid, $ec_data_pool, $namespace) = @_;
my $storage_params = {
type => 'rbd',
@@ -312,6 +315,8 @@ my $add_storage = sub {
content => 'rootdir,images',
};
+ $storage_params->{namespace} = $namespace if $namespace;
+
$storage_params->{'data-pool'} = $ec_data_pool if $ec_data_pool;
PVE::API2::Storage::Config->create($storage_params);
@@ -798,4 +803,198 @@ __PACKAGE__->register_method ({
}});
+my $get_rbd_namespaces = sub {
+ my ($pool) = @_;
+
+ my $raw = '';
+ run_command(
+ ['/usr/bin/rbd', 'namespace', 'list', '--pool', $pool, '--format', 'json'],
+ outfunc => sub { $raw .= shift },
+ errmsg => "rbd error",
+ errfunc => sub {},
+ );
+ return [] if $raw eq '[]';
+
+ my ($untainted_raw) = $raw =~ /^(.+)$/; # untaint
+ my $namespaces = eval { decode_json($untainted_raw) };
+ die "failed to parse as JSON - $@\n" if $@;
+
+ return [
+ map { { name => $_->{name} } } $namespaces->@*
+ ];
+};
+
+__PACKAGE__->register_method ({
+ name => 'listnamespaces',
+ path => '{name}/namespace',
+ method => 'GET',
+ permissions => {
+ check => ['perm', '/', [ 'Sys.Audit', 'Datastore.Audit' ], any => 1],
+ },
+ description => "Get pool RBD namespaces.",
+ proxyto => 'node',
+ protected => 1,
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ name => {
+ description => 'The name of the pool.',
+ type => 'string',
+ },
+ },
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => 'object',
+ properties => {
+ name => { type => 'string', title => "Namespace" }
+ },
+ },
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $pool = extract_param($param, 'name') // 'rbd';
+ return $get_rbd_namespaces->($pool);
+ }});
+
+
+__PACKAGE__->register_method ({
+ name => 'createnamespace',
+ path => '{name}/namespace',
+ method => 'POST',
+ permissions => {
+ check => ['perm', '/', [ 'Sys.Modify' ]],
+ },
+ description => "Create new RBD namespace.",
+ proxyto => 'node',
+ protected => 1,
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ name => {
+ description => 'The name of the pool.',
+ type => 'string',
+ },
+ namespace => {
+ description => 'The name of the new namespace',
+ type => 'string',
+ format => 'pve-storage-id',
+ },
+ 'add-storage' => {
+ description => "Configure VM and CT storage using the new namespace.",
+ type => 'boolean',
+ optional => 1,
+ default => "0",
+ },
+ },
+ },
+ returns => { type => 'string' },
+ code => sub {
+ my ($param) = @_;
+
+ my $pool = extract_param($param, 'name');
+ my $namespace = PVE::Tools::trim(extract_param($param, 'namespace'));
+ my $add_storages = extract_param($param, 'add-storage');
+
+ die "namespace cannot be empty\n" if length($namespace) < 1; # in case it was just whitespace
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $user = $rpcenv->get_user();
+ if ($add_storages) {
+ $rpcenv->check($user, '/storage', ['Datastore.Allocate']);
+ die "namespace name contains characters which are illegal for storage naming\n"
+ if !PVE::JSONSchema::parse_storage_id("${pool}-${namespace}");
+ }
+
+ my $rados = PVE::RADOS->new();
+ my $apps = $rados->mon_command({ prefix => "osd pool application get", pool => "$pool", });
+ die "the pool does not have application 'rbd' enabled\n" if !defined($apps->{rbd});
+
+ my $current_namespaces = { map { $_->{name} => 1 } $get_rbd_namespaces->($pool)->@*};
+ die "namespace already exists\n" if $current_namespaces->{$namespace};
+
+ my $worker = sub {
+ run_command(
+ ['/usr/bin/rbd', 'namespace', 'create', '--pool', ${pool}, '--namespace', ${namespace}],
+ errmsg => "rbd create namespace error",
+ errfunc => sub {},
+ outfunc => sub {},
+ );
+ if ($add_storages) {
+ eval { $add_storage->($pool, "${pool}-${namespace}", 0, $namespace) };
+ die "adding PVE storage for ceph rbd namespace failed: pool: ${pool}, namespace: ${namespace}: $@\n" if $@;
+ }
+ };
+
+ return $rpcenv->fork_worker('cephcreaterbdnamespace', $pool, $user, $worker);
+ }});
+
+
+__PACKAGE__->register_method ({
+ name => 'destroynamespace',
+ path => '{name}/namespace',
+ method => 'DELETE',
+ permissions => {
+ check => ['perm', '/', [ 'Sys.Modify' ]],
+ },
+ description => "Delete RBD namespace.",
+ proxyto => 'node',
+ protected => 1,
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ name => {
+ description => 'The name of the pool.',
+ type => 'string',
+ },
+ namespace => {
+ description => 'The name of the namespace',
+ type => 'string',
+ },
+ force => {
+ description => 'Force removal of the namespace',
+ type => 'boolean',
+ optional => 1,
+ },
+ },
+ },
+ returns => { type => 'string' },
+ code => sub {
+ my ($param) = @_;
+
+ my $pool = extract_param($param, 'name');
+ my $namespace = extract_param($param, 'namespace');
+ my $force = extract_param($param, 'force');
+
+ if (!$force) {
+ my $storages = $get_storages->($pool);
+ for my $storage (keys $storages->%*) {
+ if (
+ defined($storages->{$storage}->{namespace})
+ && $storages->{$storage}->{namespace} eq $namespace
+ ) {
+ die "namespace '${namespace}' is configured in storage '${storage}', remove it first\n";
+ }
+ }
+ }
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $user = $rpcenv->get_user();
+ my $worker = sub {
+ run_command(
+ ['/usr/bin/rbd', 'namespace', 'remove', '--pool', ${pool}, '--namespace', ${namespace}],
+ errmsg => "rbd remove namespace error",
+ errfunc => sub {},
+ outfunc => sub {},
+ );
+ };
+
+ return $rpcenv->fork_worker('cephdestroyrbdnamespace', $pool, $user, $worker);
+ }});
+
1;
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pve-devel] [PATCH manager v3 2/6] pveceph: add pool namespace subcommands
2025-04-04 14:53 [pve-devel] [PATCH manager, docs v3 0/6] Ceph: add RBD Namespace management Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 1/6] api: ceph: add rbd namespace management endpoints Aaron Lauterer
@ 2025-04-04 14:53 ` Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 3/6] ui: ceph pool: add rbd namespace panel Aaron Lauterer
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Aaron Lauterer @ 2025-04-04 14:53 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
---
changes since v2:
* define alias for 'namespace list' correctly
v1: none
PVE/CLI/pveceph.pm | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/PVE/CLI/pveceph.pm b/PVE/CLI/pveceph.pm
index 488aea04..a549ae80 100755
--- a/PVE/CLI/pveceph.pm
+++ b/PVE/CLI/pveceph.pm
@@ -482,6 +482,15 @@ our $cmddef = {
my ($data, $schema, $options) = @_;
PVE::CLIFormatter::print_api_result($data, $schema, undef, $options);
}, $PVE::RESTHandler::standard_output_options],
+ namespace => {
+ ls => [ 'PVE::API2::Ceph::Pool', 'listnamespaces', ['name'], { node => $nodename}, sub {
+ my ($data, $schema, $options) = @_;
+ PVE::CLIFormatter::print_api_result($data, $schema, undef, $options);
+ }, $PVE::RESTHandler::standard_output_options],
+ list => { alias => 'ls' },
+ create => [ 'PVE::API2::Ceph::Pool', 'createnamespace', ['name', 'namespace', 'add-storage'], { node => $nodename}],
+ destroy => [ 'PVE::API2::Ceph::Pool', 'destroynamespace', ['name', 'namespace'], { node => $nodename }],
+ },
},
lspools => { alias => 'pool ls' },
createpool => { alias => 'pool create' },
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pve-devel] [PATCH manager v3 3/6] ui: ceph pool: add rbd namespace panel
2025-04-04 14:53 [pve-devel] [PATCH manager, docs v3 0/6] Ceph: add RBD Namespace management Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 1/6] api: ceph: add rbd namespace management endpoints Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 2/6] pveceph: add pool namespace subcommands Aaron Lauterer
@ 2025-04-04 14:53 ` Aaron Lauterer
2025-04-04 15:19 ` [pve-devel] [PATCH manager v3 3/6 follow up] " Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 4/6] ui: utils: add ceph rbd namespace task names Aaron Lauterer
` (2 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Aaron Lauterer @ 2025-04-04 14:53 UTC (permalink / raw)
To: 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. 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@proxmox.com>
---
changes since v2:
* make new PoolView declarative
* add interface to pveNodeCephRbdNamespacelist that handles changes to
the pool name instead of doing that in detail from the
pveNodeCephPoolList grid.
* switch to basic extjs.data.Store
* some smaller bug and style fixes that were reported
v1: none
www/manager6/ceph/Pool.js | 237 +++++++++++++++++++++++++++++++++++-
www/manager6/node/Config.js | 3 +-
2 files changed, 238 insertions(+), 2 deletions(-)
diff --git a/www/manager6/ceph/Pool.js b/www/manager6/ceph/Pool.js
index c7e5e480..f4ca05d7 100644
--- a/www/manager6/ceph/Pool.js
+++ b/www/manager6/ceph/Pool.js
@@ -1,3 +1,56 @@
+Ext.define('PVE.node.Ceph.PoolView', {
+ extend: 'Ext.panel.Panel',
+ alias: 'widget.pveNodeCephPoolView',
+ mixins: ['Proxmox.Mixin.CBind'],
+
+ onlineHelp: 'pve_ceph_pools',
+ scrollable: 'y',
+
+ referenceHolder: true,
+
+ cbindData: function() {
+ let me = this;
+ return {
+ nodename: me.nodename,
+ };
+ },
+
+ layout: 'border',
+
+ items: [
+ {
+ xtype: 'pveNodeCephPoolList',
+ region: 'center',
+ border: 'false',
+ cbind: {
+ nodename: '{nodename}',
+ },
+ listeners: {
+ select: function(_record, item, _index) {
+ let me = this;
+ if ('rbd' in item.data.application_metadata) {
+ me.up().lookup('pveNodeCephRbdNamespacelist').setPoolname(item.id);
+ } else {
+ me.up().lookup('pveNodeCephRbdNamespacelist').setPoolname(undefined);
+ }
+ },
+ },
+ },
+ {
+ xtype: 'pveNodeCephRbdNamespacelist',
+ region: 'south',
+ height: '50%',
+ border: false,
+ disabled: true,
+ reference: 'pveNodeCephRbdNamespacelist',
+ cbind: {
+ nodename: '{nodename}',
+ },
+ },
+ ],
+
+});
+
Ext.define('PVE.CephPoolInputPanel', {
extend: 'Proxmox.panel.InputPanel',
xtype: 'pveCephPoolInputPanel',
@@ -280,6 +333,8 @@ Ext.define('PVE.node.Ceph.PoolList', {
onlineHelp: 'chapter_pveceph',
+ title: gettext('Ceph Pools'),
+
stateful: true,
stateId: 'grid-ceph-pools',
bufferedRenderer: false,
@@ -413,11 +468,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', {
@@ -538,6 +594,7 @@ Ext.define('PVE.node.Ceph.PoolList', {
});
me.callParent();
+ me.store.rstore.load();
},
}, function() {
Ext.define('ceph-pool-list', {
@@ -608,3 +665,181 @@ 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',
+ renderer: Ext.htmlEncode,
+ },
+ ],
+
+ setPoolname: function(poolname) {
+ let me = this;
+ if (poolname) {
+ me.poolname = poolname;
+ let ns_store = me.getStore();
+ ns_store.setProxy({
+ type: 'proxmox',
+ url: `/api2/json/nodes/${me.nodename}/ceph/pool/${me.poolname}/namespace`,
+ });
+ ns_store.load();
+ me.setDisabled(false);
+ } else {
+ me.poolname = undefined;
+ me.getStore().setData([]);
+ me.setDisabled(true);
+ }
+ },
+
+ initComponent: function() {
+ let me = this;
+
+ let nodename = me.nodename;
+ if (!nodename) {
+ throw "no node name specified";
+ }
+
+ let sm = Ext.create('Ext.selection.RowModel', {});
+
+ let store = Ext.create('Ext.data.Store', {
+ storeid: 'ceph-rbd-namespace-list' + nodename,
+ model: 'ceph-rbd-namespace-list',
+ proxy: {
+ type: 'proxmox',
+ url: undefined,
+ },
+ });
+
+ // manages the "install ceph?" overlay
+ PVE.Utils.monitor_ceph_installed(me, store, nodename);
+
+ let 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: () => store.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: () => store.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: Ext.htmlEncode(namespace),
+ },
+ item: {
+ type: 'RbdNamespace',
+ id: namespace,
+ },
+ taskName: 'cephdestroyrbdnamespace',
+ autoShow: true,
+ listeners: {
+ destroy: () => store.load(),
+ },
+ });
+ },
+ },
+ ],
+ listeners: {
+ activate: () => store.startUpdate(),
+ destroy: () => store.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
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pve-devel] [PATCH manager v3 4/6] ui: utils: add ceph rbd namespace task names
2025-04-04 14:53 [pve-devel] [PATCH manager, docs v3 0/6] Ceph: add RBD Namespace management Aaron Lauterer
` (2 preceding siblings ...)
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 3/6] ui: ceph pool: add rbd namespace panel Aaron Lauterer
@ 2025-04-04 14:53 ` Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 5/6] ui: storage rbd: remove hint for manual rbd namespace creation Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH docs v3] pveceph: add section for rbd namespaces Aaron Lauterer
5 siblings, 0 replies; 11+ messages in thread
From: Aaron Lauterer @ 2025-04-04 14:53 UTC (permalink / raw)
To: pve-devel
Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
---
no changes since v1
www/manager6/Utils.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index aa415759..a21ffec7 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -1993,11 +1993,13 @@ Ext.define('PVE.Utils', {
cephcreatemon: ['Ceph Monitor', gettext('Create')],
cephcreateosd: ['Ceph OSD', gettext('Create')],
cephcreatepool: ['Ceph Pool', gettext('Create')],
+ cephcreaterbdnamespace: ['Ceph RBD Namespace', gettext('Create')],
cephdestroymds: ['Ceph Metadata Server', gettext('Destroy')],
cephdestroymgr: ['Ceph Manager', gettext('Destroy')],
cephdestroymon: ['Ceph Monitor', gettext('Destroy')],
cephdestroyosd: ['Ceph OSD', gettext('Destroy')],
cephdestroypool: ['Ceph Pool', gettext('Destroy')],
+ cephdestroyrbdnamespace: ['Ceph RBD Namespace', gettext('Destroy')],
cephdestroyfs: ['CephFS', gettext('Destroy')],
cephfscreate: ['CephFS', gettext('Create')],
cephsetpool: ['Ceph Pool', gettext('Edit')],
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pve-devel] [PATCH manager v3 5/6] ui: storage rbd: remove hint for manual rbd namespace creation
2025-04-04 14:53 [pve-devel] [PATCH manager, docs v3 0/6] Ceph: add RBD Namespace management Aaron Lauterer
` (3 preceding siblings ...)
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 4/6] ui: utils: add ceph rbd namespace task names Aaron Lauterer
@ 2025-04-04 14:53 ` Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH docs v3] pveceph: add section for rbd namespaces Aaron Lauterer
5 siblings, 0 replies; 11+ messages in thread
From: Aaron Lauterer @ 2025-04-04 14:53 UTC (permalink / raw)
To: pve-devel
they can now be created with proxmox ve tooling directly
Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
---
no changes since v1
www/manager6/storage/RBDEdit.js | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/www/manager6/storage/RBDEdit.js b/www/manager6/storage/RBDEdit.js
index 15fc1304..e41da1e1 100644
--- a/www/manager6/storage/RBDEdit.js
+++ b/www/manager6/storage/RBDEdit.js
@@ -5,7 +5,6 @@ Ext.define('PVE.storage.Ceph.Model', {
data: {
pveceph: true,
pvecephPossible: true,
- namespacePresent: false,
},
});
@@ -27,16 +26,10 @@ Ext.define('PVE.storage.Ceph.Controller', {
disable: 'resetField',
enable: 'resetField',
},
- 'textfield[name=namespace]': {
- change: 'updateNamespaceHint',
- },
},
resetField: function(field) {
field.reset();
},
- updateNamespaceHint: function(field, newVal, oldVal) {
- this.getViewModel().set('namespacePresent', newVal);
- },
queryMonitors: function(field, newVal, oldVal) {
// we get called with two signatures, the above one for a field
// change event and the afterrender from the view, this check only
@@ -95,9 +88,6 @@ Ext.define('PVE.storage.RBDInputPanel', {
this.lookupReference('pvecephRef').setValue(false);
this.lookupReference('pvecephRef').resetOriginalValue();
}
- if (values.namespace) {
- this.getViewModel().set('namespacePresent', true);
- }
this.callParent([values]);
},
@@ -238,17 +228,6 @@ Ext.define('PVE.storage.RBDInputPanel', {
allowBlank: true,
},
];
- me.advancedColumn2 = [
- {
- xtype: 'displayfield',
- name: 'namespace-hint',
- userCls: 'pmx-hint',
- value: gettext('RBD namespaces must be created manually!'),
- bind: {
- hidden: '{!namespacePresent}',
- },
- },
- ];
me.callParent();
},
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pve-devel] [PATCH docs v3] pveceph: add section for rbd namespaces
2025-04-04 14:53 [pve-devel] [PATCH manager, docs v3 0/6] Ceph: add RBD Namespace management Aaron Lauterer
` (4 preceding siblings ...)
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 5/6] ui: storage rbd: remove hint for manual rbd namespace creation Aaron Lauterer
@ 2025-04-04 14:53 ` Aaron Lauterer
2025-04-11 8:33 ` [pve-devel] [PATCH docs v3 follow-up] " Aaron Lauterer
5 siblings, 1 reply; 11+ messages in thread
From: Aaron Lauterer @ 2025-04-04 14:53 UTC (permalink / raw)
To: pve-devel
and a few basic examples on how to manage them.
Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
---
changes since v2:
* {pve} instead of written out
* incorporated other small fixes and style recommendation
v1: none
pveceph.adoc | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/pveceph.adoc b/pveceph.adoc
index 79aa045..ab0be25 100644
--- a/pveceph.adoc
+++ b/pveceph.adoc
@@ -800,6 +800,47 @@ You can find a more in-depth introduction to the PG autoscaler on Ceph's Blog -
https://ceph.io/rados/new-in-nautilus-pg-merging-and-autotuning/[New in
Nautilus: PG merging and autotuning].
+[[pve_ceph_rbd_namespaces]]
+RBD Namespaces
+~~~~~~~~~~~~~~
+
+Namespaces in the rados block device (RBD) layer can be used to have multiple
+Proxmox VE clusters using the same pool, but still be logically separated.
+Namespaces can be managed in the web UI in the 'Node -> Ceph -> Pools' panel.
+
+Alternatively, the `pveceph` or Ceph's `rbd` footnote:[https://docs.ceph.com/en/latest/man/8/rbd/]
+utility can be used too. To list all RBD namespaces of the pool `vmstore`, run the
+following command:
+[source, bash]
+----
+pveceph pool namespace ls vmstore
+----
+The result will be for example:
+[source, bash]
+----
+┌───────────┐
+│ Namespace │
+╞═══════════╡
+│ bar │
+├───────────┤
+│ foo │
+└───────────┘
+----
+
+To create a new RBD namespace `baz` in the pool `vmstore`, run:
+[source, bash]
+----
+pveceph pool namespace create vmstore baz --add-storage 1
+----
+The `--add-storage` parameter is optional an when set, will create a new
+storage configuration with the new namespace.
+
+To delete the `baz` RBD namespace in pool `vmstore`:
+[source, bash]
+----
+pveceph pool namespace destroy vmstore baz
+----
+
[[pve_ceph_device_classes]]
Ceph CRUSH & Device Classes
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pve-devel] [PATCH manager v3 3/6 follow up] ui: ceph pool: add rbd namespace panel
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 3/6] ui: ceph pool: add rbd namespace panel Aaron Lauterer
@ 2025-04-04 15:19 ` Aaron Lauterer
0 siblings, 0 replies; 11+ messages in thread
From: Aaron Lauterer @ 2025-04-04 15:19 UTC (permalink / raw)
To: 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. 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@proxmox.com>
---
Please use this follow up instead of the original!
I forgot to remove two listeners at the end of the
pveNodeCephRbdNamespacelist component that caused problems when
navigating away from the ceph pool panel!
changes since v2:
* make new PoolView declarative
* add interface to pveNodeCephRbdNamespacelist that handles changes to
the pool name instead of doing that in detail from the
pveNodeCephPoolList grid.
* switch to basic extjs.data.Store
* some smaller bug and style fixes that were reported
v1: none
www/manager6/ceph/Pool.js | 235 +++++++++++++++++++++++++++++++++++-
www/manager6/node/Config.js | 3 +-
2 files changed, 236 insertions(+), 2 deletions(-)
diff --git a/www/manager6/ceph/Pool.js b/www/manager6/ceph/Pool.js
index 2b41d220..8bdf041f 100644
--- a/www/manager6/ceph/Pool.js
+++ b/www/manager6/ceph/Pool.js
@@ -1,3 +1,56 @@
+Ext.define('PVE.node.Ceph.PoolView', {
+ extend: 'Ext.panel.Panel',
+ alias: 'widget.pveNodeCephPoolView',
+ mixins: ['Proxmox.Mixin.CBind'],
+
+ onlineHelp: 'pve_ceph_pools',
+ scrollable: 'y',
+
+ referenceHolder: true,
+
+ cbindData: function() {
+ let me = this;
+ return {
+ nodename: me.nodename,
+ };
+ },
+
+ layout: 'border',
+
+ items: [
+ {
+ xtype: 'pveNodeCephPoolList',
+ region: 'center',
+ border: 'false',
+ cbind: {
+ nodename: '{nodename}',
+ },
+ listeners: {
+ select: function(_record, item, _index) {
+ let me = this;
+ if ('rbd' in item.data.application_metadata) {
+ me.up().lookup('pveNodeCephRbdNamespacelist').setPoolname(item.id);
+ } else {
+ me.up().lookup('pveNodeCephRbdNamespacelist').setPoolname(undefined);
+ }
+ },
+ },
+ },
+ {
+ xtype: 'pveNodeCephRbdNamespacelist',
+ region: 'south',
+ height: '50%',
+ border: false,
+ disabled: true,
+ reference: 'pveNodeCephRbdNamespacelist',
+ cbind: {
+ nodename: '{nodename}',
+ },
+ },
+ ],
+
+});
+
Ext.define('PVE.CephPoolInputPanel', {
extend: 'Proxmox.panel.InputPanel',
xtype: 'pveCephPoolInputPanel',
@@ -280,6 +333,8 @@ Ext.define('PVE.node.Ceph.PoolList', {
onlineHelp: 'chapter_pveceph',
+ title: gettext('Ceph Pools'),
+
stateful: true,
stateId: 'grid-ceph-pools',
bufferedRenderer: false,
@@ -414,11 +469,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', {
@@ -539,6 +595,7 @@ Ext.define('PVE.node.Ceph.PoolList', {
});
me.callParent();
+ me.store.rstore.load();
},
}, function() {
Ext.define('ceph-pool-list', {
@@ -609,3 +666,179 @@ 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',
+ renderer: Ext.htmlEncode,
+ },
+ ],
+
+ setPoolname: function(poolname) {
+ let me = this;
+ if (poolname) {
+ me.poolname = poolname;
+ let ns_store = me.getStore();
+ ns_store.setProxy({
+ type: 'proxmox',
+ url: `/api2/json/nodes/${me.nodename}/ceph/pool/${me.poolname}/namespace`,
+ });
+ ns_store.load();
+ me.setDisabled(false);
+ } else {
+ me.poolname = undefined;
+ me.getStore().setData([]);
+ me.setDisabled(true);
+ }
+ },
+
+ initComponent: function() {
+ let me = this;
+
+ let nodename = me.nodename;
+ if (!nodename) {
+ throw "no node name specified";
+ }
+
+ let sm = Ext.create('Ext.selection.RowModel', {});
+
+ let store = Ext.create('Ext.data.Store', {
+ storeid: 'ceph-rbd-namespace-list' + nodename,
+ model: 'ceph-rbd-namespace-list',
+ proxy: {
+ type: 'proxmox',
+ url: undefined,
+ },
+ });
+
+ // manages the "install ceph?" overlay
+ PVE.Utils.monitor_ceph_installed(me, store, nodename);
+
+ let 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: () => store.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: () => store.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: Ext.htmlEncode(namespace),
+ },
+ item: {
+ type: 'RbdNamespace',
+ id: namespace,
+ },
+ taskName: 'cephdestroyrbdnamespace',
+ autoShow: true,
+ listeners: {
+ destroy: () => store.load(),
+ },
+ });
+ },
+ },
+ ],
+ listeners: {
+ 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
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pve-devel] [PATCH docs v3 follow-up] pveceph: add section for rbd namespaces
2025-04-04 14:53 ` [pve-devel] [PATCH docs v3] pveceph: add section for rbd namespaces Aaron Lauterer
@ 2025-04-11 8:33 ` Aaron Lauterer
0 siblings, 0 replies; 11+ messages in thread
From: Aaron Lauterer @ 2025-04-11 8:33 UTC (permalink / raw)
To: pve-devel
and a few basic examples on how to manage them.
Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
---
Please use this instead of the original v3 docs patch. It seems I forgot
to commit the changes before creating the patch :-/bin
changes since v2:
* {pve} instead of written out
* incorporated other small fixes and style recommendation
pveceph.adoc | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/pveceph.adoc b/pveceph.adoc
index 79aa045..3680ac2 100644
--- a/pveceph.adoc
+++ b/pveceph.adoc
@@ -800,6 +800,47 @@ You can find a more in-depth introduction to the PG autoscaler on Ceph's Blog -
https://ceph.io/rados/new-in-nautilus-pg-merging-and-autotuning/[New in
Nautilus: PG merging and autotuning].
+[[pve_ceph_rbd_namespaces]]
+RBD Namespaces
+~~~~~~~~~~~~~~
+
+Namespaces in the rados block device (RBD) layer can be used to have multiple
+{pve} clusters using the same pool, but still be logically separated.
+Namespaces can be managed in the web UI in the 'Node -> Ceph -> Pools' panel.
+
+Alternatively, the `pveceph` or Ceph's `rbd` footnote:[https://docs.ceph.com/en/latest/man/8/rbd/]
+utility can be used too. To list all RBD namespaces of the pool `vmstore`, run the
+following command:
+[source, bash]
+----
+pveceph pool namespace ls vmstore
+----
+The result will be for example:
+[source, bash]
+----
+┌───────────┐
+│ Namespace │
+╞═══════════╡
+│ bar │
+├───────────┤
+│ foo │
+└───────────┘
+----
+
+To create a new RBD namespace `baz` in the pool `vmstore`, run:
+[source, bash]
+----
+pveceph pool namespace create vmstore baz --add-storage 1
+----
+The `--add-storage` parameter is optional and when set, will create a new
+storage configuration with the new namespace.
+
+To delete the empty `baz` RBD namespace in pool `vmstore`:
+[source, bash]
+----
+pveceph pool namespace destroy vmstore baz
+----
+
[[pve_ceph_device_classes]]
Ceph CRUSH & Device Classes
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [pve-devel] [PATCH manager v3 3/6 follow up] ui: ceph pool: add rbd namespace panel
2025-04-04 15:18 [pve-devel] [PATCH manager v3 3/6 follow up] ui: ceph pool: add rbd namespace panel Aaron Lauterer
@ 2025-04-04 15:20 ` Aaron Lauterer
0 siblings, 0 replies; 11+ messages in thread
From: Aaron Lauterer @ 2025-04-04 15:20 UTC (permalink / raw)
To: pve-devel
Sorry for the noise. Please ignore this one. I sent it again with the
correct in-reply-to to get the threading right.
On 2025-04-04 17:18, Aaron Lauterer wrote:
> 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. 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@proxmox.com>
> ---
> Please use this follow up instead of the original!
> I forgot to remove two listeners at the end of the
> pveNodeCephRbdNamespacelist component that caused problems when
> navigating away from the ceph pool panel!
>
> changes since v2:
> * make new PoolView declarative
> * add interface to pveNodeCephRbdNamespacelist that handles changes to
> the pool name instead of doing that in detail from the
> pveNodeCephPoolList grid.
> * switch to basic extjs.data.Store
> * some smaller bug and style fixes that were reported
>
> v1: none
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pve-devel] [PATCH manager v3 3/6 follow up] ui: ceph pool: add rbd namespace panel
@ 2025-04-04 15:18 Aaron Lauterer
2025-04-04 15:20 ` Aaron Lauterer
0 siblings, 1 reply; 11+ messages in thread
From: Aaron Lauterer @ 2025-04-04 15:18 UTC (permalink / raw)
To: 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. 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@proxmox.com>
---
Please use this follow up instead of the original!
I forgot to remove two listeners at the end of the
pveNodeCephRbdNamespacelist component that caused problems when
navigating away from the ceph pool panel!
changes since v2:
* make new PoolView declarative
* add interface to pveNodeCephRbdNamespacelist that handles changes to
the pool name instead of doing that in detail from the
pveNodeCephPoolList grid.
* switch to basic extjs.data.Store
* some smaller bug and style fixes that were reported
v1: none
www/manager6/ceph/Pool.js | 235 +++++++++++++++++++++++++++++++++++-
www/manager6/node/Config.js | 3 +-
2 files changed, 236 insertions(+), 2 deletions(-)
diff --git a/www/manager6/ceph/Pool.js b/www/manager6/ceph/Pool.js
index 2b41d220..8bdf041f 100644
--- a/www/manager6/ceph/Pool.js
+++ b/www/manager6/ceph/Pool.js
@@ -1,3 +1,56 @@
+Ext.define('PVE.node.Ceph.PoolView', {
+ extend: 'Ext.panel.Panel',
+ alias: 'widget.pveNodeCephPoolView',
+ mixins: ['Proxmox.Mixin.CBind'],
+
+ onlineHelp: 'pve_ceph_pools',
+ scrollable: 'y',
+
+ referenceHolder: true,
+
+ cbindData: function() {
+ let me = this;
+ return {
+ nodename: me.nodename,
+ };
+ },
+
+ layout: 'border',
+
+ items: [
+ {
+ xtype: 'pveNodeCephPoolList',
+ region: 'center',
+ border: 'false',
+ cbind: {
+ nodename: '{nodename}',
+ },
+ listeners: {
+ select: function(_record, item, _index) {
+ let me = this;
+ if ('rbd' in item.data.application_metadata) {
+ me.up().lookup('pveNodeCephRbdNamespacelist').setPoolname(item.id);
+ } else {
+ me.up().lookup('pveNodeCephRbdNamespacelist').setPoolname(undefined);
+ }
+ },
+ },
+ },
+ {
+ xtype: 'pveNodeCephRbdNamespacelist',
+ region: 'south',
+ height: '50%',
+ border: false,
+ disabled: true,
+ reference: 'pveNodeCephRbdNamespacelist',
+ cbind: {
+ nodename: '{nodename}',
+ },
+ },
+ ],
+
+});
+
Ext.define('PVE.CephPoolInputPanel', {
extend: 'Proxmox.panel.InputPanel',
xtype: 'pveCephPoolInputPanel',
@@ -280,6 +333,8 @@ Ext.define('PVE.node.Ceph.PoolList', {
onlineHelp: 'chapter_pveceph',
+ title: gettext('Ceph Pools'),
+
stateful: true,
stateId: 'grid-ceph-pools',
bufferedRenderer: false,
@@ -414,11 +469,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', {
@@ -539,6 +595,7 @@ Ext.define('PVE.node.Ceph.PoolList', {
});
me.callParent();
+ me.store.rstore.load();
},
}, function() {
Ext.define('ceph-pool-list', {
@@ -609,3 +666,179 @@ 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',
+ renderer: Ext.htmlEncode,
+ },
+ ],
+
+ setPoolname: function(poolname) {
+ let me = this;
+ if (poolname) {
+ me.poolname = poolname;
+ let ns_store = me.getStore();
+ ns_store.setProxy({
+ type: 'proxmox',
+ url: `/api2/json/nodes/${me.nodename}/ceph/pool/${me.poolname}/namespace`,
+ });
+ ns_store.load();
+ me.setDisabled(false);
+ } else {
+ me.poolname = undefined;
+ me.getStore().setData([]);
+ me.setDisabled(true);
+ }
+ },
+
+ initComponent: function() {
+ let me = this;
+
+ let nodename = me.nodename;
+ if (!nodename) {
+ throw "no node name specified";
+ }
+
+ let sm = Ext.create('Ext.selection.RowModel', {});
+
+ let store = Ext.create('Ext.data.Store', {
+ storeid: 'ceph-rbd-namespace-list' + nodename,
+ model: 'ceph-rbd-namespace-list',
+ proxy: {
+ type: 'proxmox',
+ url: undefined,
+ },
+ });
+
+ // manages the "install ceph?" overlay
+ PVE.Utils.monitor_ceph_installed(me, store, nodename);
+
+ let 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: () => store.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: () => store.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: Ext.htmlEncode(namespace),
+ },
+ item: {
+ type: 'RbdNamespace',
+ id: namespace,
+ },
+ taskName: 'cephdestroyrbdnamespace',
+ autoShow: true,
+ listeners: {
+ destroy: () => store.load(),
+ },
+ });
+ },
+ },
+ ],
+ listeners: {
+ 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
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-04-11 8:34 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-04 14:53 [pve-devel] [PATCH manager, docs v3 0/6] Ceph: add RBD Namespace management Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 1/6] api: ceph: add rbd namespace management endpoints Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 2/6] pveceph: add pool namespace subcommands Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 3/6] ui: ceph pool: add rbd namespace panel Aaron Lauterer
2025-04-04 15:19 ` [pve-devel] [PATCH manager v3 3/6 follow up] " Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 4/6] ui: utils: add ceph rbd namespace task names Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH manager v3 5/6] ui: storage rbd: remove hint for manual rbd namespace creation Aaron Lauterer
2025-04-04 14:53 ` [pve-devel] [PATCH docs v3] pveceph: add section for rbd namespaces Aaron Lauterer
2025-04-11 8:33 ` [pve-devel] [PATCH docs v3 follow-up] " Aaron Lauterer
2025-04-04 15:18 [pve-devel] [PATCH manager v3 3/6 follow up] ui: ceph pool: add rbd namespace panel Aaron Lauterer
2025-04-04 15:20 ` Aaron Lauterer
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