From 8b6842caa2f9608f9de7c059a21743025ae1c1e2 Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Mon, 30 Jul 2018 10:26:00 +0200 Subject: [PATCH] add API for LVM management currently only list and create, the list is in a format so that we can use it in an extjs tree Signed-off-by: Dominik Csapak --- PVE/API2/Disks.pm | 8 +- PVE/API2/Disks/LVM.pm | 178 ++++++++++++++++++++++++++++++++++++++++ PVE/API2/Disks/Makefile | 6 ++ PVE/API2/Makefile | 1 + 4 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 PVE/API2/Disks/LVM.pm create mode 100644 PVE/API2/Disks/Makefile diff --git a/PVE/API2/Disks.pm b/PVE/API2/Disks.pm index de8287e..7ae81eb 100644 --- a/PVE/API2/Disks.pm +++ b/PVE/API2/Disks.pm @@ -8,11 +8,16 @@ use PVE::Diskmanage; use HTTP::Status qw(:constants); use PVE::JSONSchema qw(get_standard_option); +use PVE::API2::Disks::LVM; + use PVE::RESTHandler; use base qw(PVE::RESTHandler); -use Data::Dumper; +__PACKAGE__->register_method ({ + subclass => "PVE::API2::Disks::LVM", + path => 'lvm', +}); __PACKAGE__->register_method ({ name => 'index', @@ -42,6 +47,7 @@ __PACKAGE__->register_method ({ { name => 'list' }, { name => 'initgpt' }, { name => 'smart' }, + { name => 'lvm' }, ]; return $result; diff --git a/PVE/API2/Disks/LVM.pm b/PVE/API2/Disks/LVM.pm new file mode 100644 index 0000000..baf3365 --- /dev/null +++ b/PVE/API2/Disks/LVM.pm @@ -0,0 +1,178 @@ +package PVE::API2::Disks::LVM; + +use strict; +use warnings; + +use PVE::Storage::LVMPlugin; +use PVE::Diskmanage; +use PVE::JSONSchema qw(get_standard_option); +use PVE::API2::Storage::Config; +use PVE::Tools qw(lock_file); + +use PVE::RPCEnvironment; +use PVE::RESTHandler; + +use base qw(PVE::RESTHandler); + +__PACKAGE__->register_method ({ + name => 'index', + path => '', + method => 'GET', + proxyto => 'node', + protected => 1, + permissions => { + check => ['perm', '/', ['Sys.Audit', 'Datastore.Audit'], any => 1], + }, + description => "List LVM Volume Groups", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + }, + }, + returns => { + type => 'object', + properties => { + leaf => { + type => 'boolean', + }, + children => { + type => 'array', + items => { + type => "object", + properties => { + leaf => { + type => 'boolean', + }, + name => { + type => 'string', + description => 'The name of the volume group', + }, + size => { + type => 'integer', + description => 'The size of the volume group in bytes', + }, + free => { + type => 'integer', + description => 'The free bytes in the volume group', + }, + children => { + optional => 1, + type => 'array', + description => 'The underlying physical volumes', + items => { + type => 'object', + properties => { + leaf => { + type => 'boolean', + }, + name => { + type => 'string', + description => 'The name of the physical volume', + }, + size => { + type => 'integer', + description => 'The size of the physical volume in bytes', + }, + free => { + type => 'integer', + description => 'The free bytes in the physical volume', + }, + }, + }, + }, + }, + }, + }, + }, + }, + code => sub { + my ($param) = @_; + + my $result = []; + + my $vgs = PVE::Storage::LVMPlugin::lvm_vgs(1); + + foreach my $vg_name (sort keys %$vgs) { + my $vg = $vgs->{$vg_name}; + $vg->{name} = $vg_name; + $vg->{leaf} = 0; + foreach my $pv (@{$vg->{pvs}}) { + $pv->{leaf} = 1; + } + $vg->{children} = delete $vg->{pvs}; + push @$result, $vg; + } + + return { + leaf => 0, + children => $result, + }; + }}); + +__PACKAGE__->register_method ({ + name => 'create', + path => '', + method => 'POST', + proxyto => 'node', + protected => 1, + permissions => { + check => ['perm', '/', ['Sys.Modify', 'Datastore.Allocate']], + }, + description => "Create an LVM Volume Group", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + name => get_standard_option('pve-storage-id'), + device => { + type => 'string', + description => 'The block device you want to create the volume group on', + }, + add_storage => { + description => "Configure storage using the Volume Group", + type => 'boolean', + optional => 1, + default => 0, + }, + }, + }, + returns => { type => 'string' }, + code => sub { + my ($param) = @_; + + my $rpcenv = PVE::RPCEnvironment::get(); + my $user = $rpcenv->get_user(); + + my $name = $param->{name}; + my $dev = $param->{device}; + my $node = $param->{node}; + + $dev = PVE::Diskmanage::verify_blockdev_path($dev); + die "device $dev is already in use\n" if PVE::Diskmanage::disk_is_used($dev); + + my $worker = sub { + my $res = lock_file('/run/lock/pve-diskmanage.lck', undef, sub { + PVE::Storage::LVMPlugin::lvm_create_volume_group($dev, $name); + + if ($param->{add_storage}) { + my $storage_params = { + type => 'lvm', + vgname => $name, + storage => $name, + content => 'rootdir,images', + shared => 0, + nodes => $node, + }; + + PVE::API2::Storage::Config->create($storage_params); + } + }); + + die "$@" if $@; + }; + + return $rpcenv->fork_worker('lvmcreate', $name, $user, $worker); + }}); + +1; diff --git a/PVE/API2/Disks/Makefile b/PVE/API2/Disks/Makefile new file mode 100644 index 0000000..7b41f89 --- /dev/null +++ b/PVE/API2/Disks/Makefile @@ -0,0 +1,6 @@ + +SOURCES= LVM.pm + +.PHONY: install +install: + for i in ${SOURCES}; do install -D -m 0644 $$i ${DESTDIR}${PERLDIR}/PVE/API2/Disks/$$i; done diff --git a/PVE/API2/Makefile b/PVE/API2/Makefile index 7b7226e..fe316c5 100644 --- a/PVE/API2/Makefile +++ b/PVE/API2/Makefile @@ -4,3 +4,4 @@ install: install -D -m 0644 Disks.pm ${DESTDIR}${PERLDIR}/PVE/API2/Disks.pm make -C Storage install + make -C Disks install -- 2.39.5