From 409f8203e0e3a4f53e19ab94df067be7d6ba735c Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Tue, 23 Aug 2016 12:20:46 +0200 Subject: [PATCH] add api entries for disk management adds a new class (intended to be used under nodes in pve-manager) which adds the three api calls: list, smart and init list being a general list of the available disk with infos smart being a call to get the smart data from a given device init being a call to write a gpt header to an unused disk Signed-off-by: Dominik Csapak --- PVE/API2/Disks.pm | 192 ++++++++++++++++++++++++++++++++++++++++++++++ PVE/API2/Makefile | 3 +- 2 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 PVE/API2/Disks.pm diff --git a/PVE/API2/Disks.pm b/PVE/API2/Disks.pm new file mode 100644 index 0000000..279d351 --- /dev/null +++ b/PVE/API2/Disks.pm @@ -0,0 +1,192 @@ +package PVE::API2::Disks; + +use strict; +use warnings; + +use PVE::SafeSyslog; +use PVE::Diskmanage; +use HTTP::Status qw(:constants); +use PVE::JSONSchema qw(get_standard_option); + +use PVE::RESTHandler; + +use base qw(PVE::RESTHandler); + +use Data::Dumper; + +__PACKAGE__->register_method ({ + name => 'index', + path => '', + method => 'GET', + proxyto => 'node', + permissions => { user => 'all' }, + description => "Node index.", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + }, + }, + returns => { + type => 'array', + items => { + type => "object", + properties => {}, + }, + links => [ { rel => 'child', href => "{name}" } ], + }, + code => sub { + my ($param) = @_; + + my $result = [ + { name => 'list' }, + { name => 'initgpt' }, + { name => 'smart' }, + ]; + + return $result; + }}); + +__PACKAGE__->register_method ({ + name => 'list', + path => 'list', + method => 'GET', + description => "List local disks.", + protected => 1, + proxyto => 'node', + permissions => { + check => ['perm', '/', ['Sys.Audit', 'Datastore.Audit'], any => 1], + }, + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + }, + }, + returns => { + type => 'array', + items => { + type => 'object', + properties => { + devpath => { + type => 'string', + description => 'The device path', + }, + used => { type => 'string', optional => 1 }, + gpt => { type => 'boolean' }, + size => { type => 'integer'}, + osdid => { type => 'integer'}, + vendor => { type => 'string', optional => 1 }, + model => { type => 'string', optional => 1 }, + serial => { type => 'string', optional => 1 }, + wwn => { type => 'string', optional => 1}, + health => { type => 'string', optional => 1}, + }, + }, + }, + code => sub { + my ($param) = @_; + + my $disks = PVE::Diskmanage::get_disks(); + + my $result = []; + + foreach my $disk (sort keys %$disks) { + my $entry = $disks->{$disk}; + push @$result, $entry; + } + return $result; + }}); + +__PACKAGE__->register_method ({ + name => 'smart', + path => 'smart', + method => 'GET', + description => "Get SMART Health of a disk.", + protected => 1, + proxyto => "node", + permissions => { + check => ['perm', '/', ['Sys.Audit', 'Datastore.Audit'], any => 1], + }, + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + disk => { + type => 'string', + pattern => '^/dev/[a-zA-Z0-9\/]+$', + description => "Block device name", + }, + healthonly => { + type => 'boolean', + description => "If true returns only the health status", + optional => 1, + }, + }, + }, + returns => { type => 'object' }, + code => sub { + my ($param) = @_; + + my $disk = PVE::Diskmanage::verify_blockdev_path($param->{disk}); + + my $result = {}; + + if ($param->{healthonly}) { + $result = { health => PVE::Diskmanage::get_smart_health($disk) }; + } else { + $result = PVE::Diskmanage::get_smart_data($disk); + } + + return $result; + }}); + +__PACKAGE__->register_method ({ + name => 'initgpt', + path => 'initgpt', + method => 'POST', + description => "Initialize Disk with GPT", + protected => 1, + proxyto => "node", + permissions => { + check => ['perm', '/', ['Sys.Modify']], + }, + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + disk => { + type => 'string', + description => "Block device name", + pattern => '^/dev/[a-zA-Z0-9\/]+$', + }, + uuid => { + type => 'string', + description => 'UUID for the GPT table', + pattern => '[a-fA-F0-9\-]+', + maxLength => 36, + optional => 1, + }, + }, + }, + returns => { type => 'string' }, + code => sub { + my ($param) = @_; + + my $disk = PVE::Diskmanage::verify_blockdev_path($param->{disk}); + + my $rpcenv = PVE::RPCEnvironment::get(); + + my $authuser = $rpcenv->get_user(); + + die "disk $disk already in use\n" if PVE::Diskmanage::disk_is_used($disk); + my $worker = sub { + PVE::Diskmanage::init_disk($disk, $param->{uuid}); + }; + + my $diskid = $disk; + $diskid =~ s|^.*/||; # remove all up to the last slash + return $rpcenv->fork_worker('diskinit', $diskid, $authuser, $worker); + }}); + +1; diff --git a/PVE/API2/Makefile b/PVE/API2/Makefile index e3ccdc1..7b7226e 100644 --- a/PVE/API2/Makefile +++ b/PVE/API2/Makefile @@ -2,4 +2,5 @@ .PHONY: install install: - make -C Storage install \ No newline at end of file + install -D -m 0644 Disks.pm ${DESTDIR}${PERLDIR}/PVE/API2/Disks.pm + make -C Storage install