From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 482F176866 for ; Tue, 19 Oct 2021 11:34:34 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 298BD2B08D for ; Tue, 19 Oct 2021 11:34:01 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 3147A2AF36 for ; Tue, 19 Oct 2021 11:33:56 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id C94AD45459 for ; Tue, 19 Oct 2021 11:33:55 +0200 (CEST) From: Dominik Csapak To: pve-devel@lists.proxmox.com Date: Tue, 19 Oct 2021 11:33:52 +0200 Message-Id: <20211019093353.2451987-12-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211019093353.2451987-1-d.csapak@proxmox.com> References: <20211019093353.2451987-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.288 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH manager 10/11] api: cephfs: add destroy cephfs api call X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Oct 2021 09:34:34 -0000 with 'remove-storages' and 'remove-pools' as optional parameters Signed-off-by: Dominik Csapak --- PVE/API2/Ceph/FS.pm | 119 ++++++++++++++++++++++++++++++++++++++++++ PVE/Ceph/Tools.pm | 15 ++++++ www/manager6/Utils.js | 1 + 3 files changed, 135 insertions(+) diff --git a/PVE/API2/Ceph/FS.pm b/PVE/API2/Ceph/FS.pm index 8bf71524..a325c4bd 100644 --- a/PVE/API2/Ceph/FS.pm +++ b/PVE/API2/Ceph/FS.pm @@ -217,4 +217,123 @@ __PACKAGE__->register_method ({ } }); +my $get_storages = sub { + my ($fs, $is_default) = @_; + + my $cfg = PVE::Storage::config(); + + my $storages = $cfg->{ids}; + my $res = {}; + foreach my $storeid (keys %$storages) { + my $curr = $storages->{$storeid}; + next if $curr->{type} ne 'cephfs'; + my $cur_fs = $curr->{'fs-name'}; + $res->{$storeid} = $storages->{$storeid} + if (!defined($cur_fs) && $is_default) || (defined($cur_fs) && $fs eq $cur_fs); + } + + return $res; +}; + +__PACKAGE__->register_method ({ + name => 'destroyfs', + path => '{name}', + method => 'DELETE', + description => "Destroy a Ceph filesystem", + proxyto => 'node', + protected => 1, + permissions => { + check => ['perm', '/', [ 'Sys.Modify' ]], + }, + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + name => { + description => "The ceph filesystem name.", + type => 'string', + }, + 'remove-storages' => { + description => "Remove all pveceph-managed storages configured for this fs.", + type => 'boolean', + optional => 1, + default => 0, + }, + 'remove-pools' => { + description => "Remove data and metadata pools configured for this fs.", + 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 $fs_name = $param->{name}; + + my $fs; + my $fs_list = PVE::Ceph::Tools::ls_fs(); + for my $entry (@$fs_list) { + next if $entry->{name} ne $fs_name; + $fs = $entry; + last; + } + die "no such cephfs '$fs_name'\n" if !$fs; + + my $worker = sub { + my $rados = PVE::RADOS->new(); + + my $defaultfs; + if ($param->{'remove-storages'}) { + my $fs_dump = $rados->mon_command({ prefix => "fs dump" }); + for my $fs ($fs_dump->{filesystems}->@*) { + next if $fs->{id} != $fs_dump->{default_fscid}; + $defaultfs = $fs->{mdsmap}->{fs_name}; + } + warn "no default fs found, maybe not all relevant storages are removed\n" + if !defined($defaultfs); + } + + PVE::Ceph::Tools::destroy_fs($fs_name, $rados); + + if ($param->{'remove-pools'}) { + warn "removing metadata pool '$fs->{metadata_pool}'\n"; + eval { PVE::Ceph::Tools::destroy_pool($fs->{metadata_pool}, $rados) }; + warn "$@\n" if $@; + + foreach my $pool ($fs->{data_pools}->@*) { + warn "removing data pool '$pool'\n"; + eval { PVE::Ceph::Tools::destroy_pool($pool, $rados) }; + warn "$@\n" if $@; + } + } + + if ($param->{'remove-storages'}) { + my $storages = $get_storages->($fs_name, $fs_name eq ($defaultfs // '')); + 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('cephdestroyfs', $fs_name, $user, $worker); + }}); + 1; diff --git a/PVE/Ceph/Tools.pm b/PVE/Ceph/Tools.pm index 2f818276..36d7788a 100644 --- a/PVE/Ceph/Tools.pm +++ b/PVE/Ceph/Tools.pm @@ -340,6 +340,21 @@ sub create_fs { }); } +sub destroy_fs { + my ($fs, $rados) = @_; + + if (!defined($rados)) { + $rados = PVE::RADOS->new(); + } + + $rados->mon_command({ + prefix => "fs rm", + fs_name => $fs, + 'yes_i_really_mean_it' => JSON::true, + format => 'plain', + }); +} + sub setup_pve_symlinks { # fail if we find a real file instead of a link if (-f $ceph_cfgpath) { diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js index ee92cd43..3c385ea9 100644 --- a/www/manager6/Utils.js +++ b/www/manager6/Utils.js @@ -1830,6 +1830,7 @@ Ext.define('PVE.Utils', { cephdestroymon: ['Ceph Monitor', gettext('Destroy')], cephdestroyosd: ['Ceph OSD', gettext('Destroy')], cephdestroypool: ['Ceph Pool', gettext('Destroy')], + cephdestroyfs: ['CephFS', gettext('Destroy')], cephfscreate: ['CephFS', gettext('Create')], cephsetpool: ['Ceph Pool', gettext('Edit')], cephsetflags: ['', gettext('Change global Ceph flags')], -- 2.30.2