From: Aaron Lauterer <a.lauterer@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH manager 2/7] api: ceph: add rbd namespace management endpoints
Date: Fri, 6 Dec 2024 14:55:09 +0100 [thread overview]
Message-ID: <20241206135514.170226-3-a.lauterer@proxmox.com> (raw)
In-Reply-To: <20241206135514.170226-1-a.lauterer@proxmox.com>
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>
---
PVE/API2/Ceph/Pool.pm | 182 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 180 insertions(+), 2 deletions(-)
diff --git a/PVE/API2/Ceph/Pool.pm b/PVE/API2/Ceph/Pool.pm
index 5ee982f4..47194245 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;
+
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;
@@ -302,7 +304,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 +314,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 +802,178 @@ __PACKAGE__->register_method ({
}});
+my $get_rbd_namespaces = sub {
+ my ($pool) = @_;
+
+ my $cmd = ['/usr/bin/rbd', 'namespace', 'list', $pool, '--format', 'json'];
+ my $raw = '';
+ my $parser = sub { $raw .= shift };
+ run_command($cmd, errmsg => "rbd error", errfunc => sub {}, outfunc => $parser);
+ return [] if $raw eq '[]';
+
+ my $decoded;
+ if ($raw =~ m/^(\[\{.*\}\])$/s) { #untaint
+ $decoded = JSON::decode_json($1);
+ } else {
+ die "got unexpected data from rbd namespace list: '${raw}'\n";
+ }
+
+ my $result = [];
+ for my $val (@$decoded) {
+ push @$result, { name => $val->{name} };
+ }
+ return $result;
+};
+
+__PACKAGE__->register_method ({
+ name => 'listnamespaces',
+ path => '{name}/namespace',
+ method => 'GET',
+ permissions => {
+ check => ['perm', '/', [ 'Sys.Audit', 'Datastore.Audit' ], any => 1],
+ },
+ description => "Get pool RBD namespace index.",
+ proxyto => 'node',
+ protected => 1,
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ name => {
+ description => 'The name of the pool.',
+ type => 'string',
+ default => 'rbd',
+ },
+ },
+ },
+ 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',
+ default => 'rbd',
+ },
+ namespace => {
+ description => 'The name of the new namespace',
+ type => 'string',
+ },
+ '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') // 'rbd';
+ my $namespace = extract_param($param, 'namespace');
+ my $add_storages = extract_param($param, 'add-storage');
+
+ die "specify namespace" if !$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" if !defined($apps->{rbd});
+
+ my $current_namespaces = { map { $_->{name} => 1 } $get_rbd_namespaces->($pool)->@*};
+ die "namespace already exists" if $current_namespaces->{$namespace};
+
+ my $cmd = ['/usr/bin/rbd', 'namespace', 'create', "${pool}/${namespace}"];
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $user = $rpcenv->get_user();
+ my $worker = sub {
+ my $raw = '';
+ my $parser = sub { $raw .= shift };
+ run_command($cmd, errmsg => "rbd create namespace error", errfunc => sub {}, outfunc => $parser);
+ 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',
+ default => 'rbd',
+ },
+ namespace => {
+ description => 'The name of the new namespace',
+ type => 'string',
+ },
+ },
+ },
+ returns => { type => 'string' },
+ code => sub {
+ my ($param) = @_;
+
+ my $pool = extract_param($param, 'name') // 'rbd';
+ my $namespace = extract_param($param, 'namespace');
+
+ die "specify namespace" if !$namespace;
+
+ my $cmd = ['/usr/bin/rbd', 'namespace', 'remove', "${pool}/${namespace}"];
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $user = $rpcenv->get_user();
+ my $worker = sub {
+ my $raw = '';
+ my $parser = sub { $raw .= shift };
+ run_command($cmd, errmsg => "rbd create namespace error", errfunc => sub {}, outfunc => $parser);
+ };
+
+ 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
next prev parent reply other threads:[~2024-12-06 13:55 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-06 13:55 [pve-devel] [PATCH manager, docs 0/7] Ceph: add RBD Namespace management Aaron Lauterer
2024-12-06 13:55 ` [pve-devel] [PATCH manager 1/7] ui: ceph pool: add columns for application Aaron Lauterer
2024-12-10 18:56 ` [pve-devel] applied: " Thomas Lamprecht
2024-12-06 13:55 ` Aaron Lauterer [this message]
2024-12-10 18:52 ` [pve-devel] [PATCH manager 2/7] api: ceph: add rbd namespace management endpoints Thomas Lamprecht
2024-12-23 12:09 ` Aaron Lauterer
2024-12-06 13:55 ` [pve-devel] [PATCH manager 3/7] pveceph: add pool namespace subcommands Aaron Lauterer
2024-12-06 13:55 ` [pve-devel] [PATCH manager 4/7] ui: ceph pool: add rbd namespace panel Aaron Lauterer
2024-12-06 13:55 ` [pve-devel] [PATCH manager 5/7] ui: utils: add ceph rbd namespace task names Aaron Lauterer
2024-12-06 13:55 ` [pve-devel] [PATCH manager 6/7] ui: storage rbd: remove hint for manual rbd namespace creation Aaron Lauterer
2024-12-06 13:55 ` [pve-devel] [PATCH docs 7/7] pveceph: add section for rbd namespaces Aaron Lauterer
2024-12-23 16:02 ` [pve-devel] [PATCH manager, docs 0/7] Ceph: add RBD Namespace management Aaron Lauterer
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=20241206135514.170226-3-a.lauterer@proxmox.com \
--to=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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.