[pve-devel] [PATCH manager v2 1/8] api: ceph: subclass pools
Dominik Csapak
d.csapak at proxmox.com
Tue Nov 24 14:53:20 CET 2020
mhmm.. you did not simply move the code, you added at least the 'titles'
it would be better to have a commit which really only moves the
code to a new file
or at least mention it in the commit message
one comment inline
On 11/24/20 11:58 AM, Alwin Antreich wrote:
> for better handling and since the pool endpoints got more entries.
>
> Signed-off-by: Alwin Antreich <a.antreich at proxmox.com>
> ---
> PVE/API2/Ceph/Makefile | 1 +
> PVE/API2/Ceph.pm | 380 +-------------------------------------
> PVE/API2/Ceph/POOLS.pm | 404 +++++++++++++++++++++++++++++++++++++++++
> PVE/CLI/pveceph.pm | 9 +-
> 4 files changed, 416 insertions(+), 378 deletions(-)
> create mode 100644 PVE/API2/Ceph/POOLS.pm
>
> diff --git a/PVE/API2/Ceph/Makefile b/PVE/API2/Ceph/Makefile
> index 5b6493d5..65c7b862 100644
> --- a/PVE/API2/Ceph/Makefile
> +++ b/PVE/API2/Ceph/Makefile
> @@ -5,6 +5,7 @@ PERLSOURCE= \
> MON.pm \
> OSD.pm \
> FS.pm \
> + POOLS.pm \
why POOLS.pm and not Pools.pm ?
the others are only capitalized because they are abbreviations
i'd prefer Pools.pm (but this is debatable...)
> MDS.pm
>
> all:
> diff --git a/PVE/API2/Ceph.pm b/PVE/API2/Ceph.pm
> index c3a3091d..8e7e525e 100644
> --- a/PVE/API2/Ceph.pm
> +++ b/PVE/API2/Ceph.pm
> @@ -20,6 +20,7 @@ use PVE::Tools qw(run_command file_get_contents file_set_contents);
>
> use PVE::API2::Ceph::OSD;
> use PVE::API2::Ceph::FS;
> +use PVE::API2::Ceph::POOLS;
> use PVE::API2::Ceph::MDS;
> use PVE::API2::Ceph::MGR;
> use PVE::API2::Ceph::MON;
> @@ -54,6 +55,11 @@ __PACKAGE__->register_method ({
> path => 'fs',
> });
>
> +__PACKAGE__->register_method ({
> + subclass => "PVE::API2::Ceph::POOLS",
> + path => 'pools',
> +});
> +
> __PACKAGE__->register_method ({
> name => 'index',
> path => '',
> @@ -239,35 +245,6 @@ __PACKAGE__->register_method ({
> return $res;
> }});
>
> -my $add_storage = sub {
> - my ($pool, $storeid) = @_;
> -
> - my $storage_params = {
> - type => 'rbd',
> - pool => $pool,
> - storage => $storeid,
> - krbd => 0,
> - content => 'rootdir,images',
> - };
> -
> - PVE::API2::Storage::Config->create($storage_params);
> -};
> -
> -my $get_storages = sub {
> - my ($pool) = @_;
> -
> - my $cfg = PVE::Storage::config();
> -
> - my $storages = $cfg->{ids};
> - my $res = {};
> - foreach my $storeid (keys %$storages) {
> - my $curr = $storages->{$storeid};
> - $res->{$storeid} = $storages->{$storeid}
> - if $curr->{type} eq 'rbd' && $pool eq $curr->{pool};
> - }
> -
> - return $res;
> -};
>
> __PACKAGE__->register_method ({
> name => 'init',
> @@ -583,227 +560,6 @@ __PACKAGE__->register_method ({
> return PVE::Ceph::Tools::ceph_cluster_status();
> }});
>
> -__PACKAGE__->register_method ({
> - name => 'lspools',
> - path => 'pools',
> - method => 'GET',
> - description => "List all pools.",
> - proxyto => 'node',
> - protected => 1,
> - permissions => {
> - check => ['perm', '/', [ 'Sys.Audit', 'Datastore.Audit' ], any => 1],
> - },
> - parameters => {
> - additionalProperties => 0,
> - properties => {
> - node => get_standard_option('pve-node'),
> - },
> - },
> - returns => {
> - type => 'array',
> - items => {
> - type => "object",
> - properties => {
> - pool => { type => 'integer', title => 'ID' },
> - pool_name => { type => 'string', title => 'Name' },
> - size => { type => 'integer', title => 'Size' },
> - min_size => { type => 'integer', title => 'Min Size' },
> - pg_num => { type => 'integer', title => 'PG Num' },
> - pg_autoscale_mode => { type => 'string', optional => 1, title => 'PG Autoscale Mode' },
> - crush_rule => { type => 'integer', title => 'Crush Rule' },
> - crush_rule_name => { type => 'string', title => 'Crush Rule Name' },
> - percent_used => { type => 'number', title => '%-Used' },
> - bytes_used => { type => 'integer', title => 'Used' },
> - },
> - },
> - links => [ { rel => 'child', href => "{pool_name}" } ],
> - },
> - code => sub {
> - my ($param) = @_;
> -
> - PVE::Ceph::Tools::check_ceph_inited();
> -
> - my $rados = PVE::RADOS->new();
> -
> - my $stats = {};
> - my $res = $rados->mon_command({ prefix => 'df' });
> -
> - foreach my $d (@{$res->{pools}}) {
> - next if !$d->{stats};
> - next if !defined($d->{id});
> - $stats->{$d->{id}} = $d->{stats};
> - }
> -
> - $res = $rados->mon_command({ prefix => 'osd dump' });
> - my $rulestmp = $rados->mon_command({ prefix => 'osd crush rule dump'});
> -
> - my $rules = {};
> - for my $rule (@$rulestmp) {
> - $rules->{$rule->{rule_id}} = $rule->{rule_name};
> - }
> -
> - my $data = [];
> - my $attr_list = [
> - 'pool',
> - 'pool_name',
> - 'size',
> - 'min_size',
> - 'pg_num',
> - 'crush_rule',
> - 'pg_autoscale_mode',
> - ];
> -
> - foreach my $e (@{$res->{pools}}) {
> - my $d = {};
> - foreach my $attr (@$attr_list) {
> - $d->{$attr} = $e->{$attr} if defined($e->{$attr});
> - }
> -
> - if (defined($d->{crush_rule}) && defined($rules->{$d->{crush_rule}})) {
> - $d->{crush_rule_name} = $rules->{$d->{crush_rule}};
> - }
> -
> - if (my $s = $stats->{$d->{pool}}) {
> - $d->{bytes_used} = $s->{bytes_used};
> - $d->{percent_used} = $s->{percent_used};
> - }
> - push @$data, $d;
> - }
> -
> -
> - return $data;
> - }});
> -
> -
> -my $ceph_pool_common_options = sub {
> - my ($nodefault) = shift;
> - my $options = {
> - name => {
> - description => "The name of the pool. It must be unique.",
> - type => 'string',
> - },
> - size => {
> - description => 'Number of replicas per object',
> - type => 'integer',
> - default => 3,
> - optional => 1,
> - minimum => 1,
> - maximum => 7,
> - },
> - min_size => {
> - description => 'Minimum number of replicas per object',
> - type => 'integer',
> - default => 2,
> - optional => 1,
> - minimum => 1,
> - maximum => 7,
> - },
> - pg_num => {
> - description => "Number of placement groups.",
> - type => 'integer',
> - default => 128,
> - optional => 1,
> - minimum => 8,
> - maximum => 32768,
> - },
> - crush_rule => {
> - description => "The rule to use for mapping object placement in the cluster.",
> - type => 'string',
> - optional => 1,
> - },
> - application => {
> - description => "The application of the pool.",
> - default => 'rbd',
> - type => 'string',
> - enum => ['rbd', 'cephfs', 'rgw'],
> - optional => 1,
> - },
> - pg_autoscale_mode => {
> - description => "The automatic PG scaling mode of the pool.",
> - type => 'string',
> - enum => ['on', 'off', 'warn'],
> - default => 'warn',
> - optional => 1,
> - },
> - };
> -
> - if ($nodefault) {
> - delete $options->{$_}->{default} for keys %$options;
> - }
> - return $options;
> -};
> -
> -
> -__PACKAGE__->register_method ({
> - name => 'createpool',
> - path => 'pools',
> - method => 'POST',
> - description => "Create POOL",
> - proxyto => 'node',
> - protected => 1,
> - permissions => {
> - check => ['perm', '/', [ 'Sys.Modify' ]],
> - },
> - parameters => {
> - additionalProperties => 0,
> - properties => {
> - node => get_standard_option('pve-node'),
> - add_storages => {
> - description => "Configure VM and CT storage using the new pool.",
> - type => 'boolean',
> - optional => 1,
> - },
> - %{ $ceph_pool_common_options->() },
> - },
> - },
> - returns => { type => 'string' },
> - code => sub {
> - my ($param) = @_;
> -
> - PVE::Cluster::check_cfs_quorum();
> - PVE::Ceph::Tools::check_ceph_configured();
> -
> - my $pool = $param->{name};
> - my $rpcenv = PVE::RPCEnvironment::get();
> - my $user = $rpcenv->get_user();
> -
> - if ($param->{add_storages}) {
> - $rpcenv->check($user, '/storage', ['Datastore.Allocate']);
> - die "pool name contains characters which are illegal for storage naming\n"
> - if !PVE::JSONSchema::parse_storage_id($pool);
> - }
> -
> - my $ceph_param = \%$param;
> - for my $item ('add_storages', 'name', 'node') {
> - # not ceph parameters
> - delete $ceph_param->{$item};
> - }
> -
> - # pool defaults
> - $ceph_param->{pg_num} //= 128;
> - $ceph_param->{size} //= 3;
> - $ceph_param->{min_size} //= 2;
> - $ceph_param->{application} //= 'rbd';
> - $ceph_param->{pg_autoscale_mode} //= 'warn';
> -
> - my $worker = sub {
> -
> - PVE::Ceph::Tools::create_pool($pool, $ceph_param);
> -
> - if ($param->{add_storages}) {
> - my $err;
> - eval { $add_storage->($pool, "${pool}"); };
> - if ($@) {
> - warn "failed to add storage: $@";
> - $err = 1;
> - }
> - die "adding storage for pool '$pool' failed, check log and add manually!\n"
> - if $err;
> - }
> - };
> -
> - return $rpcenv->fork_worker('cephcreatepool', $pool, $user, $worker);
> - }});
>
> my $possible_flags = PVE::Ceph::Tools::get_possible_osd_flags();
> my $possible_flags_list = [ sort keys %$possible_flags ];
> @@ -913,130 +669,6 @@ __PACKAGE__->register_method ({
> return undef;
> }});
>
> -__PACKAGE__->register_method ({
> - name => 'destroypool',
> - path => 'pools/{name}',
> - method => 'DELETE',
> - description => "Destroy pool",
> - proxyto => 'node',
> - protected => 1,
> - permissions => {
> - check => ['perm', '/', [ 'Sys.Modify' ]],
> - },
> - parameters => {
> - additionalProperties => 0,
> - properties => {
> - node => get_standard_option('pve-node'),
> - name => {
> - description => "The name of the pool. It must be unique.",
> - type => 'string',
> - },
> - force => {
> - description => "If true, destroys pool even if in use",
> - type => 'boolean',
> - optional => 1,
> - default => 0,
> - },
> - remove_storages => {
> - description => "Remove all pveceph-managed storages configured for this pool",
> - type => 'boolean',
> - optional => 1,
> - default => 0,
> - },
> - },
> - },
> - returns => { type => 'string' },
> - code => sub {
> - my ($param) = @_;
> -
> - PVE::Ceph::Tools::check_ceph_inited();
> -
> - my $rpcenv = PVE::RPCEnvironment::get();
> - my $user = $rpcenv->get_user();
> - $rpcenv->check($user, '/storage', ['Datastore.Allocate'])
> - if $param->{remove_storages};
> -
> - my $pool = $param->{name};
> -
> - my $worker = sub {
> - my $storages = $get_storages->($pool);
> -
> - # if not forced, destroy ceph pool only when no
> - # vm disks are on it anymore
> - if (!$param->{force}) {
> - my $storagecfg = PVE::Storage::config();
> - foreach my $storeid (keys %$storages) {
> - my $storage = $storages->{$storeid};
> -
> - # check if any vm disks are on the pool
> - print "checking storage '$storeid' for RBD images..\n";
> - my $res = PVE::Storage::vdisk_list($storagecfg, $storeid);
> - die "ceph pool '$pool' still in use by storage '$storeid'\n"
> - if @{$res->{$storeid}} != 0;
> - }
> - }
> -
> - PVE::Ceph::Tools::destroy_pool($pool);
> -
> - if ($param->{remove_storages}) {
> - my $err;
> - foreach my $storeid (keys %$storages) {
> - # skip external clusters, not managed by pveceph
> - next if $storages->{$storeid}->{monhost};
> - eval { PVE::API2::Storage::Config->delete({storage => $storeid}) };
> - if ($@) {
> - warn "failed to remove storage '$storeid': $@\n";
> - $err = 1;
> - }
> - }
> - die "failed to remove (some) storages - check log and remove manually!\n"
> - if $err;
> - }
> - };
> - return $rpcenv->fork_worker('cephdestroypool', $pool, $user, $worker);
> - }});
> -
> -
> -__PACKAGE__->register_method ({
> - name => 'setpool',
> - path => 'pools/{name}',
> - method => 'PUT',
> - description => "Change POOL settings",
> - proxyto => 'node',
> - protected => 1,
> - permissions => {
> - check => ['perm', '/', [ 'Sys.Modify' ]],
> - },
> - parameters => {
> - additionalProperties => 0,
> - properties => {
> - node => get_standard_option('pve-node'),
> - %{ $ceph_pool_common_options->('nodefault') },
> - },
> - },
> - returns => { type => 'string' },
> - code => sub {
> - my ($param) = @_;
> -
> - PVE::Ceph::Tools::check_ceph_configured();
> -
> - my $rpcenv = PVE::RPCEnvironment::get();
> - my $authuser = $rpcenv->get_user();
> -
> - my $pool = $param->{name};
> - my $ceph_param = \%$param;
> - for my $item ('name', 'node') {
> - # not ceph parameters
> - delete $ceph_param->{$item};
> - }
> -
> - my $worker = sub {
> - PVE::Ceph::Tools::set_pool($pool, $ceph_param);
> - };
> -
> - return $rpcenv->fork_worker('cephsetpool', $pool, $authuser, $worker);
> - }});
> -
>
> __PACKAGE__->register_method ({
> name => 'crush',
> diff --git a/PVE/API2/Ceph/POOLS.pm b/PVE/API2/Ceph/POOLS.pm
> new file mode 100644
> index 00000000..744f2bce
> --- /dev/null
> +++ b/PVE/API2/Ceph/POOLS.pm
> @@ -0,0 +1,404 @@
> +package PVE::API2::Ceph::POOLS;
> +
> +use strict;
> +use warnings;
> +
> +use PVE::Ceph::Tools;
> +use PVE::Ceph::Services;
> +use PVE::JSONSchema qw(get_standard_option);
> +use PVE::RADOS;
> +use PVE::RESTHandler;
> +use PVE::RPCEnvironment;
> +use PVE::Storage;
> +
> +use PVE::API2::Storage::Config;
> +
> +use base qw(PVE::RESTHandler);
> +
> +my $ceph_pool_common_options = sub {
> + my ($nodefault) = shift;
> + my $options = {
> + name => {
> + title => 'Name',
> + description => "The name of the pool. It must be unique.",
> + type => 'string',
> + },
> + size => {
> + description => 'Number of replicas per object',
> + title => 'Size',
> + type => 'integer',
> + default => 3,
> + optional => 1,
> + minimum => 1,
> + maximum => 7,
> + },
> + min_size => {
> + description => 'Minimum number of replicas per object',
> + title => 'Min Size',
> + type => 'integer',
> + default => 2,
> + optional => 1,
> + minimum => 1,
> + maximum => 7,
> + },
> + pg_num => {
> + description => "Number of placement groups.",
> + title => 'PG Num',
> + type => 'integer',
> + default => 128,
> + optional => 1,
> + minimum => 8,
> + maximum => 32768,
> + },
> + crush_rule => {
> + description => "The rule to use for mapping object placement in the cluster.",
> + title => 'Crush Rule Name',
> + type => 'string',
> + optional => 1,
> + },
> + application => {
> + description => "The application of the pool.",
> + title => 'Application',
> + default => 'rbd',
> + type => 'string',
> + enum => ['rbd', 'cephfs', 'rgw'],
> + optional => 1,
> + },
> + pg_autoscale_mode => {
> + description => "The automatic PG scaling mode of the pool.",
> + title => 'PG Autoscale Mode',
> + type => 'string',
> + enum => ['on', 'off', 'warn'],
> + default => 'warn',
> + optional => 1,
> + },
> + };
> +
> + if ($nodefault) {
> + delete $options->{$_}->{default} for keys %$options;
> + }
> + return $options;
> +};
> +
> +my $add_storage = sub {
> + my ($pool, $storeid) = @_;
> +
> + my $storage_params = {
> + type => 'rbd',
> + pool => $pool,
> + storage => $storeid,
> + krbd => 0,
> + content => 'rootdir,images',
> + };
> +
> + PVE::API2::Storage::Config->create($storage_params);
> +};
> +
> +my $get_storages = sub {
> + my ($pool) = @_;
> +
> + my $cfg = PVE::Storage::config();
> +
> + my $storages = $cfg->{ids};
> + my $res = {};
> + foreach my $storeid (keys %$storages) {
> + my $curr = $storages->{$storeid};
> + $res->{$storeid} = $storages->{$storeid}
> + if $curr->{type} eq 'rbd' && $pool eq $curr->{pool};
> + }
> +
> + return $res;
> +};
> +
> +
> +__PACKAGE__->register_method ({
> + name => 'lspools',
> + path => '',
> + method => 'GET',
> + description => "List all pools.",
> + proxyto => 'node',
> + protected => 1,
> + permissions => {
> + check => ['perm', '/', [ 'Sys.Audit', 'Datastore.Audit' ], any => 1],
> + },
> + parameters => {
> + additionalProperties => 0,
> + properties => {
> + node => get_standard_option('pve-node'),
> + },
> + },
> + returns => {
> + type => 'array',
> + items => {
> + type => "object",
> + properties => {
> + pool => { type => 'integer', title => 'ID' },
> + pool_name => { type => 'string', title => 'Name' },
> + size => { type => 'integer', title => 'Size' },
> + min_size => { type => 'integer', title => 'Min Size' },
> + pg_num => { type => 'integer', title => 'PG Num' },
> + pg_autoscale_mode => { type => 'string', optional => 1, title => 'PG Autoscale Mode' },
> + crush_rule => { type => 'integer', title => 'Crush Rule' },
> + crush_rule_name => { type => 'string', title => 'Crush Rule Name' },
> + percent_used => { type => 'number', title => '%-Used' },
> + bytes_used => { type => 'integer', title => 'Used' },
> + },
> + },
> + links => [ { rel => 'child', href => "{pool_name}" } ],
> + },
> + code => sub {
> + my ($param) = @_;
> +
> + PVE::Ceph::Tools::check_ceph_inited();
> +
> + my $rados = PVE::RADOS->new();
> +
> + my $stats = {};
> + my $res = $rados->mon_command({ prefix => 'df' });
> +
> + foreach my $d (@{$res->{pools}}) {
> + next if !$d->{stats};
> + next if !defined($d->{id});
> + $stats->{$d->{id}} = $d->{stats};
> + }
> +
> + $res = $rados->mon_command({ prefix => 'osd dump' });
> + my $rulestmp = $rados->mon_command({ prefix => 'osd crush rule dump'});
> +
> + my $rules = {};
> + for my $rule (@$rulestmp) {
> + $rules->{$rule->{rule_id}} = $rule->{rule_name};
> + }
> +
> + my $data = [];
> + my $attr_list = [
> + 'pool',
> + 'pool_name',
> + 'size',
> + 'min_size',
> + 'pg_num',
> + 'crush_rule',
> + 'pg_autoscale_mode',
> + ];
> +
> + foreach my $e (@{$res->{pools}}) {
> + my $d = {};
> + foreach my $attr (@$attr_list) {
> + $d->{$attr} = $e->{$attr} if defined($e->{$attr});
> + }
> +
> + if (defined($d->{crush_rule}) && defined($rules->{$d->{crush_rule}})) {
> + $d->{crush_rule_name} = $rules->{$d->{crush_rule}};
> + }
> +
> + if (my $s = $stats->{$d->{pool}}) {
> + $d->{bytes_used} = $s->{bytes_used};
> + $d->{percent_used} = $s->{percent_used};
> + }
> + push @$data, $d;
> + }
> +
> +
> + return $data;
> + }});
> +
> +
> +# FIXME: use pools/{pool_name} with PVE 7.0
> +__PACKAGE__->register_method ({
> + name => 'createpool',
> + path => '',
> + method => 'POST',
> + description => "Create POOL",
> + proxyto => 'node',
> + protected => 1,
> + permissions => {
> + check => ['perm', '/', [ 'Sys.Modify' ]],
> + },
> + parameters => {
> + additionalProperties => 0,
> + properties => {
> + node => get_standard_option('pve-node'),
> + add_storages => {
> + description => "Configure VM and CT storage using the new pool.",
> + type => 'boolean',
> + optional => 1,
> + },
> + %{ $ceph_pool_common_options->() },
> + },
> + },
> + returns => { type => 'string' },
> + code => sub {
> + my ($param) = @_;
> +
> + PVE::Cluster::check_cfs_quorum();
> + PVE::Ceph::Tools::check_ceph_configured();
> +
> + my $pool = $param->{name};
> + my $rpcenv = PVE::RPCEnvironment::get();
> + my $user = $rpcenv->get_user();
> +
> + if ($param->{add_storages}) {
> + $rpcenv->check($user, '/storage', ['Datastore.Allocate']);
> + die "pool name contains characters which are illegal for storage naming\n"
> + if !PVE::JSONSchema::parse_storage_id($pool);
> + }
> +
> + my $ceph_param = \%$param;
> + for my $item ('add_storages', 'name', 'node') {
> + # not ceph parameters
> + delete $ceph_param->{$item};
> + }
> +
> + # pool defaults
> + $ceph_param->{pg_num} //= 128;
> + $ceph_param->{size} //= 3;
> + $ceph_param->{min_size} //= 2;
> + $ceph_param->{application} //= 'rbd';
> + $ceph_param->{pg_autoscale_mode} //= 'warn';
> +
> + my $worker = sub {
> +
> + PVE::Ceph::Tools::create_pool($pool, $ceph_param);
> +
> + if ($param->{add_storages}) {
> + my $err;
> + eval { $add_storage->($pool, "${pool}"); };
> + if ($@) {
> + warn "failed to add storage: $@";
> + $err = 1;
> + }
> + die "adding storage for pool '$pool' failed, check log and add manually!\n"
> + if $err;
> + }
> + };
> +
> + return $rpcenv->fork_worker('cephcreatepool', $pool, $user, $worker);
> + }});
> +
> +
> +__PACKAGE__->register_method ({
> + name => 'destroypool',
> + path => '{name}',
> + method => 'DELETE',
> + description => "Destroy pool",
> + proxyto => 'node',
> + protected => 1,
> + permissions => {
> + check => ['perm', '/', [ 'Sys.Modify' ]],
> + },
> + parameters => {
> + additionalProperties => 0,
> + properties => {
> + node => get_standard_option('pve-node'),
> + name => {
> + description => "The name of the pool. It must be unique.",
> + type => 'string',
> + },
> + force => {
> + description => "If true, destroys pool even if in use",
> + type => 'boolean',
> + optional => 1,
> + default => 0,
> + },
> + remove_storages => {
> + description => "Remove all pveceph-managed storages configured for this pool",
> + type => 'boolean',
> + optional => 1,
> + default => 0,
> + },
> + },
> + },
> + returns => { type => 'string' },
> + code => sub {
> + my ($param) = @_;
> +
> + PVE::Ceph::Tools::check_ceph_inited();
> +
> + my $rpcenv = PVE::RPCEnvironment::get();
> + my $user = $rpcenv->get_user();
> + $rpcenv->check($user, '/storage', ['Datastore.Allocate'])
> + if $param->{remove_storages};
> +
> + my $pool = $param->{name};
> +
> + my $worker = sub {
> + my $storages = $get_storages->($pool);
> +
> + # if not forced, destroy ceph pool only when no
> + # vm disks are on it anymore
> + if (!$param->{force}) {
> + my $storagecfg = PVE::Storage::config();
> + foreach my $storeid (keys %$storages) {
> + my $storage = $storages->{$storeid};
> +
> + # check if any vm disks are on the pool
> + print "checking storage '$storeid' for RBD images..\n";
> + my $res = PVE::Storage::vdisk_list($storagecfg, $storeid);
> + die "ceph pool '$pool' still in use by storage '$storeid'\n"
> + if @{$res->{$storeid}} != 0;
> + }
> + }
> +
> + PVE::Ceph::Tools::destroy_pool($pool);
> +
> + if ($param->{remove_storages}) {
> + my $err;
> + foreach my $storeid (keys %$storages) {
> + # skip external clusters, not managed by pveceph
> + next if $storages->{$storeid}->{monhost};
> + eval { PVE::API2::Storage::Config->delete({storage => $storeid}) };
> + if ($@) {
> + warn "failed to remove storage '$storeid': $@\n";
> + $err = 1;
> + }
> + }
> + die "failed to remove (some) storages - check log and remove manually!\n"
> + if $err;
> + }
> + };
> + return $rpcenv->fork_worker('cephdestroypool', $pool, $user, $worker);
> + }});
> +
> +
> +__PACKAGE__->register_method ({
> + name => 'setpool',
> + path => '{name}',
> + method => 'PUT',
> + description => "Change POOL settings",
> + proxyto => 'node',
> + protected => 1,
> + permissions => {
> + check => ['perm', '/', [ 'Sys.Modify' ]],
> + },
> + parameters => {
> + additionalProperties => 0,
> + properties => {
> + node => get_standard_option('pve-node'),
> + %{ $ceph_pool_common_options->('nodefault') },
> + },
> + },
> + returns => { type => 'string' },
> + code => sub {
> + my ($param) = @_;
> +
> + PVE::Ceph::Tools::check_ceph_configured();
> +
> + my $rpcenv = PVE::RPCEnvironment::get();
> + my $authuser = $rpcenv->get_user();
> +
> + my $pool = $param->{name};
> + my $ceph_param = \%$param;
> + for my $item ('name', 'node') {
> + # not ceph parameters
> + delete $ceph_param->{$item};
> + }
> +
> + my $worker = sub {
> + PVE::Ceph::Tools::set_pool($pool, $ceph_param);
> + };
> +
> + return $rpcenv->fork_worker('cephsetpool', $pool, $authuser, $worker);
> + }});
> +
> +
> +1;
> diff --git a/PVE/CLI/pveceph.pm b/PVE/CLI/pveceph.pm
> index 3d7bf2b1..69421ca6 100755
> --- a/PVE/CLI/pveceph.pm
> +++ b/PVE/CLI/pveceph.pm
> @@ -21,6 +21,7 @@ use PVE::Ceph::Tools;
> use PVE::Ceph::Services;
> use PVE::API2::Ceph;
> use PVE::API2::Ceph::FS;
> +use PVE::API2::Ceph::POOLS;
> use PVE::API2::Ceph::MDS;
> use PVE::API2::Ceph::MGR;
> use PVE::API2::Ceph::MON;
> @@ -178,7 +179,7 @@ __PACKAGE__->register_method ({
> our $cmddef = {
> init => [ 'PVE::API2::Ceph', 'init', [], { node => $nodename } ],
> pool => {
> - ls => [ 'PVE::API2::Ceph', 'lspools', [], { node => $nodename }, sub {
> + ls => [ 'PVE::API2::Ceph::POOLS', 'lspools', [], { node => $nodename }, sub {
> my ($data, $schema, $options) = @_;
> PVE::CLIFormatter::print_api_result($data, $schema,
> [
> @@ -193,9 +194,9 @@ our $cmddef = {
> ],
> $options);
> }, $PVE::RESTHandler::standard_output_options],
> - create => [ 'PVE::API2::Ceph', 'createpool', ['name'], { node => $nodename }],
> - destroy => [ 'PVE::API2::Ceph', 'destroypool', ['name'], { node => $nodename } ],
> - set => [ 'PVE::API2::Ceph', 'setpool', ['name'], { node => $nodename } ],
> + create => [ 'PVE::API2::Ceph::POOLS', 'createpool', ['name'], { node => $nodename }],
> + destroy => [ 'PVE::API2::Ceph::POOLS', 'destroypool', ['name'], { node => $nodename } ],
> + set => [ 'PVE::API2::Ceph::POOLS', 'setpool', ['name'], { node => $nodename } ],
> },
> lspools => { alias => 'pool ls' },
> createpool => { alias => 'pool create' },
>
More information about the pve-devel
mailing list