From a83d8eb178dd3947bf1f380dedec0acb91dded27 Mon Sep 17 00:00:00 2001 From: Fabian Ebner Date: Mon, 25 Oct 2021 15:47:45 +0200 Subject: [PATCH] api: disks: add DELETE endpoint for directory, lvm, lvmthin, zfs Signed-off-by: Fabian Ebner --- PVE/API2/Disks/Directory.pm | 44 +++++++++++++++++++++++++++++++++++++ PVE/API2/Disks/LVM.pm | 35 +++++++++++++++++++++++++++++ PVE/API2/Disks/LVMThin.pm | 42 +++++++++++++++++++++++++++++++++++ PVE/API2/Disks/ZFS.pm | 40 +++++++++++++++++++++++++++++++++ 4 files changed, 161 insertions(+) diff --git a/PVE/API2/Disks/Directory.pm b/PVE/API2/Disks/Directory.pm index 3a90a2e..36cebbc 100644 --- a/PVE/API2/Disks/Directory.pm +++ b/PVE/API2/Disks/Directory.pm @@ -3,6 +3,8 @@ package PVE::API2::Disks::Directory; use strict; use warnings; +use POSIX; + use PVE::Diskmanage; use PVE::JSONSchema qw(get_standard_option); use PVE::RESTHandler; @@ -301,4 +303,46 @@ __PACKAGE__->register_method ({ return $rpcenv->fork_worker('dircreate', $name, $user, $worker); }}); +__PACKAGE__->register_method ({ + name => 'delete', + path => '{name}', + method => 'DELETE', + proxyto => 'node', + protected => 1, + permissions => { + check => ['perm', '/', ['Sys.Modify', 'Datastore.Allocate']], + }, + description => "Unmounts the storage and removes the mount unit.", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + name => get_standard_option('pve-storage-id'), + }, + }, + returns => { type => 'string' }, + code => sub { + my ($param) = @_; + + my $rpcenv = PVE::RPCEnvironment::get(); + my $user = $rpcenv->get_user(); + + my $name = $param->{name}; + + my $worker = sub { + my $path = "/mnt/pve/$name"; + my $mountunitname = PVE::Systemd::escape_unit($path, 1) . ".mount"; + my $mountunitpath = "/etc/systemd/system/$mountunitname"; + + PVE::Diskmanage::locked_disk_action(sub { + run_command(['systemctl', 'stop', $mountunitname]); + run_command(['systemctl', 'disable', $mountunitname]); + + unlink $mountunitpath or $! == ENOENT or die "cannot remove $mountunitpath - $!\n"; + }); + }; + + return $rpcenv->fork_worker('dirremove', $name, $user, $worker); + }}); + 1; diff --git a/PVE/API2/Disks/LVM.pm b/PVE/API2/Disks/LVM.pm index 885e02b..ee9e282 100644 --- a/PVE/API2/Disks/LVM.pm +++ b/PVE/API2/Disks/LVM.pm @@ -187,4 +187,39 @@ __PACKAGE__->register_method ({ return $rpcenv->fork_worker('lvmcreate', $name, $user, $worker); }}); +__PACKAGE__->register_method ({ + name => 'delete', + path => '{name}', + method => 'DELETE', + proxyto => 'node', + protected => 1, + permissions => { + check => ['perm', '/', ['Sys.Modify', 'Datastore.Allocate']], + }, + description => "Remove an LVM Volume Group.", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + name => get_standard_option('pve-storage-id'), + }, + }, + returns => { type => 'string' }, + code => sub { + my ($param) = @_; + + my $rpcenv = PVE::RPCEnvironment::get(); + my $user = $rpcenv->get_user(); + + my $name = $param->{name}; + + my $worker = sub { + PVE::Diskmanage::locked_disk_action(sub { + PVE::Storage::LVMPlugin::lvm_destroy_volume_group($name); + }); + }; + + return $rpcenv->fork_worker('lvmremove', $name, $user, $worker); + }}); + 1; diff --git a/PVE/API2/Disks/LVMThin.pm b/PVE/API2/Disks/LVMThin.pm index ced4b6a..52f3062 100644 --- a/PVE/API2/Disks/LVMThin.pm +++ b/PVE/API2/Disks/LVMThin.pm @@ -165,4 +165,46 @@ __PACKAGE__->register_method ({ return $rpcenv->fork_worker('lvmthincreate', $name, $user, $worker); }}); +__PACKAGE__->register_method ({ + name => 'delete', + path => '{name}', + method => 'DELETE', + proxyto => 'node', + protected => 1, + permissions => { + check => ['perm', '/', ['Sys.Modify', 'Datastore.Allocate']], + }, + description => "Remove an LVM thin pool.", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + name => get_standard_option('pve-storage-id'), + 'volume-group' => get_standard_option('pve-storage-id'), + }, + }, + returns => { type => 'string' }, + code => sub { + my ($param) = @_; + + my $rpcenv = PVE::RPCEnvironment::get(); + my $user = $rpcenv->get_user(); + + my $vg = $param->{'volume-group'}; + my $lv = $param->{name}; + + my $worker = sub { + PVE::Diskmanage::locked_disk_action(sub { + my $thinpools = PVE::Storage::LvmThinPlugin::list_thinpools(); + + die "no such thin pool ${vg}/${lv}\n" + if !grep { $_->{lv} eq $lv && $_->{vg} eq $vg } $thinpools->@*; + + run_command(['lvremove', '-y', "${vg}/${lv}"]); + }); + }; + + return $rpcenv->fork_worker('lvmthinremove', "${vg}-${lv}", $user, $worker); + }}); + 1; diff --git a/PVE/API2/Disks/ZFS.pm b/PVE/API2/Disks/ZFS.pm index 7f96bb7..e8d5e7c 100644 --- a/PVE/API2/Disks/ZFS.pm +++ b/PVE/API2/Disks/ZFS.pm @@ -449,4 +449,44 @@ __PACKAGE__->register_method ({ return $rpcenv->fork_worker('zfscreate', $name, $user, $worker); }}); +__PACKAGE__->register_method ({ + name => 'delete', + path => '{name}', + method => 'DELETE', + proxyto => 'node', + protected => 1, + permissions => { + check => ['perm', '/', ['Sys.Modify', 'Datastore.Allocate']], + }, + description => "Destroy a ZFS pool.", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + name => get_standard_option('pve-storage-id'), + }, + }, + returns => { type => 'string' }, + code => sub { + my ($param) = @_; + + my $rpcenv = PVE::RPCEnvironment::get(); + my $user = $rpcenv->get_user(); + + my $name = $param->{name}; + + my $worker = sub { + PVE::Diskmanage::locked_disk_action(sub { + if (-e '/lib/systemd/system/zfs-import@.service') { + my $importunit = 'zfs-import@' . PVE::Systemd::escape_unit($name) . '.service'; + run_command(['systemctl', 'disable', $importunit]); + } + + run_command(['zpool', 'destroy', $name]); + }); + }; + + return $rpcenv->fork_worker('zfsremove', $name, $user, $worker); + }}); + 1;