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 8F2087804A for ; Mon, 25 Oct 2021 16:01:49 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 70FAA2427E for ; Mon, 25 Oct 2021 16:01:48 +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 3C85923F05 for ; Mon, 25 Oct 2021 16:01:42 +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 E0B9045F6D for ; Mon, 25 Oct 2021 16:01:41 +0200 (CEST) From: Dominik Csapak To: pve-devel@lists.proxmox.com Date: Mon, 25 Oct 2021 16:01:38 +0200 Message-Id: <20211025140139.2015470-13-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211025140139.2015470-1-d.csapak@proxmox.com> References: <20211025140139.2015470-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.273 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 v2 11/11] pveceph: add 'fs destroy' command 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: Mon, 25 Oct 2021 14:01:49 -0000 with 'remove-storages' and 'remove-pools' as optional parameters Signed-off-by: Dominik Csapak --- PVE/CLI/pveceph.pm | 120 ++++++++++++++++++++++++++++++++++++++++++ PVE/Ceph/Tools.pm | 15 ++++++ www/manager6/Utils.js | 1 + 3 files changed, 136 insertions(+) diff --git a/PVE/CLI/pveceph.pm b/PVE/CLI/pveceph.pm index b04d1346..995cfcd5 100755 --- a/PVE/CLI/pveceph.pm +++ b/PVE/CLI/pveceph.pm @@ -221,6 +221,125 @@ __PACKAGE__->register_method ({ return undef; }}); +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 => 'destroyfs', + method => 'DELETE', + description => "Destroy a Ceph filesystem", + 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(); + + 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(); + + if ($param->{'remove-storages'}) { + my $defaultfs; + 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); + + my $storages = $get_storages->($fs_name, $fs_name eq ($defaultfs // '')); + for my $storeid (keys %$storages) { + my $store = $storages->{$storeid}; + if (!$store->{disable}) { + die "storage '$storeid' is not disabled, make sure to disable ". + "and unmount the storage first\n"; + } + } + + my $err; + for 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; + } + + 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 $@; + } + } + + }; + return $rpcenv->fork_worker('cephdestroyfs', $fs_name, $user, $worker); + }}); + our $cmddef = { init => [ 'PVE::API2::Ceph', 'init', [], { node => $nodename } ], pool => { @@ -256,6 +375,7 @@ our $cmddef = { destroypool => { alias => 'pool destroy' }, fs => { create => [ 'PVE::API2::Ceph::FS', 'createfs', [], { node => $nodename }], + destroy => [ __PACKAGE__, 'destroyfs', ['name'], { node => $nodename }], }, osd => { create => [ 'PVE::API2::Ceph::OSD', 'createosd', ['dev'], { node => $nodename }, $upid_exit], 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 274d4db2..38615c30 100644 --- a/www/manager6/Utils.js +++ b/www/manager6/Utils.js @@ -1831,6 +1831,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