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: 10+ 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-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
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox