api: disks: delete: add flag for cleaning up storage config

Update node restrictions to reflect that the storage is not available
anymore on the particular node. If the storage was only configured for
that node, remove it altogether.

Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>

slight style fixup

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
Fabian Ebner
2021-10-25 15:47:49 +02:00
committed by Fabian Grünbichler
parent f81908eb58
commit cde43c4880
5 changed files with 109 additions and 0 deletions

View File

@ -314,6 +314,13 @@ __PACKAGE__->register_method ({
properties => {
node => get_standard_option('pve-node'),
name => get_standard_option('pve-storage-id'),
'cleanup-config' => {
description => "Marks associated storage(s) as not available on this node anymore ".
"or removes them from the configuration (if configured for this node only).",
type => 'boolean',
optional => 1,
default => 0,
},
'cleanup-disks' => {
description => "Also wipe disk so it can be repurposed afterwards.",
type => 'boolean',
@ -330,6 +337,7 @@ __PACKAGE__->register_method ({
my $user = $rpcenv->get_user();
my $name = $param->{name};
my $node = $param->{node};
my $worker = sub {
my $path = "/mnt/pve/$name";
@ -357,10 +365,22 @@ __PACKAGE__->register_method ({
unlink $mountunitpath or $! == ENOENT or die "cannot remove $mountunitpath - $!\n";
my $config_err;
if ($param->{'cleanup-config'}) {
my $match = sub {
my ($scfg) = @_;
return $scfg->{type} eq 'dir' && $scfg->{path} eq $path;
};
eval { PVE::API2::Storage::Config->cleanup_storages_for_node($match, $node); };
warn $config_err = $@ if $@;
}
if ($to_wipe) {
PVE::Diskmanage::wipe_blockdev($to_wipe);
PVE::Diskmanage::udevadm_trigger($to_wipe);
}
die "config cleanup failed - $config_err" if $config_err;
});
};

View File

@ -198,6 +198,13 @@ __PACKAGE__->register_method ({
properties => {
node => get_standard_option('pve-node'),
name => get_standard_option('pve-storage-id'),
'cleanup-config' => {
description => "Marks associated storage(s) as not available on this node anymore ".
"or removes them from the configuration (if configured for this node only).",
type => 'boolean',
optional => 1,
default => 0,
},
'cleanup-disks' => {
description => "Also wipe disks so they can be repurposed afterwards.",
type => 'boolean',
@ -214,6 +221,7 @@ __PACKAGE__->register_method ({
my $user = $rpcenv->get_user();
my $name = $param->{name};
my $node = $param->{node};
my $worker = sub {
PVE::Diskmanage::locked_disk_action(sub {
@ -222,6 +230,16 @@ __PACKAGE__->register_method ({
PVE::Storage::LVMPlugin::lvm_destroy_volume_group($name);
my $config_err;
if ($param->{'cleanup-config'}) {
my $match = sub {
my ($scfg) = @_;
return $scfg->{type} eq 'lvm' && $scfg->{vgname} eq $name;
};
eval { PVE::API2::Storage::Config->cleanup_storages_for_node($match, $node); };
warn $config_err = $@ if $@;
}
if ($param->{'cleanup-disks'}) {
my $wiped = [];
eval {
@ -235,6 +253,8 @@ __PACKAGE__->register_method ({
PVE::Diskmanage::udevadm_trigger($wiped->@*);
die "cleanup failed - $err" if $err;
}
die "config cleanup failed - $config_err" if $config_err;
});
};

View File

@ -177,6 +177,13 @@ __PACKAGE__->register_method ({
node => get_standard_option('pve-node'),
name => get_standard_option('pve-storage-id'),
'volume-group' => get_standard_option('pve-storage-id'),
'cleanup-config' => {
description => "Marks associated storage(s) as not available on this node anymore ".
"or removes them from the configuration (if configured for this node only).",
type => 'boolean',
optional => 1,
default => 0,
},
'cleanup-disks' => {
description => "Also wipe disks so they can be repurposed afterwards.",
type => 'boolean',
@ -194,6 +201,7 @@ __PACKAGE__->register_method ({
my $vg = $param->{'volume-group'};
my $lv = $param->{name};
my $node = $param->{node};
my $worker = sub {
PVE::Diskmanage::locked_disk_action(sub {
@ -204,6 +212,18 @@ __PACKAGE__->register_method ({
run_command(['lvremove', '-y', "${vg}/${lv}"]);
my $config_err;
if ($param->{'cleanup-config'}) {
my $match = sub {
my ($scfg) = @_;
return $scfg->{type} eq 'lvmthin'
&& $scfg->{vgname} eq $vg
&& $scfg->{thinpool} eq $lv;
};
eval { PVE::API2::Storage::Config->cleanup_storages_for_node($match, $node); };
warn $config_err = $@ if $@;
}
if ($param->{'cleanup-disks'}) {
my $vgs = PVE::Storage::LVMPlugin::lvm_vgs(1);
@ -222,6 +242,8 @@ __PACKAGE__->register_method ({
PVE::Diskmanage::udevadm_trigger($wiped->@*);
die "cleanup failed - $err" if $err;
}
die "config cleanup failed - $config_err" if $config_err;
});
};

View File

@ -460,6 +460,13 @@ __PACKAGE__->register_method ({
properties => {
node => get_standard_option('pve-node'),
name => get_standard_option('pve-storage-id'),
'cleanup-config' => {
description => "Marks associated storage(s) as not available on this node anymore ".
"or removes them from the configuration (if configured for this node only).",
type => 'boolean',
optional => 1,
default => 0,
},
'cleanup-disks' => {
description => "Also wipe disks so they can be repurposed afterwards.",
type => 'boolean',
@ -476,6 +483,7 @@ __PACKAGE__->register_method ({
my $user = $rpcenv->get_user();
my $name = $param->{name};
my $node = $param->{node};
my $worker = sub {
PVE::Diskmanage::locked_disk_action(sub {
@ -516,10 +524,22 @@ __PACKAGE__->register_method ({
run_command(['zpool', 'destroy', $name]);
my $config_err;
if ($param->{'cleanup-config'}) {
my $match = sub {
my ($scfg) = @_;
return $scfg->{type} eq 'zfspool' && $scfg->{pool} eq $name;
};
eval { PVE::API2::Storage::Config->cleanup_storages_for_node($match, $node); };
warn $config_err = $@ if $@;
}
eval { PVE::Diskmanage::wipe_blockdev($_) for $to_wipe->@*; };
my $err = $@;
PVE::Diskmanage::udevadm_trigger($to_wipe->@*);
die "cleanup failed - $err" if $err;
die "config cleanup failed - $config_err" if $config_err;
});
};

View File

@ -38,6 +38,33 @@ my $api_storage_config = sub {
return $scfg;
};
# For storages that $match->($scfg), update node restrictions to not include $node anymore and
# in case no node remains, remove the storage altogether.
sub cleanup_storages_for_node {
my ($self, $match, $node) = @_;
my $config = PVE::Storage::config();
my $cluster_nodes = PVE::Cluster::get_nodelist();
for my $storeid (keys $config->{ids}->%*) {
my $scfg = PVE::Storage::storage_config($config, $storeid);
next if !$match->($scfg);
my $nodes = $scfg->{nodes} || { map { $_ => 1 } $cluster_nodes->@* };
next if !$nodes->{$node}; # not configured on $node, so nothing to do
delete $nodes->{$node};
if (scalar(keys $nodes->%*) > 0) {
$self->update({
nodes => join(',', sort keys $nodes->%*),
storage => $storeid,
});
} else {
$self->delete({storage => $storeid});
}
}
}
__PACKAGE__->register_method ({
name => 'index',
path => '',