[pve-devel] r5033 - in pve-storage/pve2: . PVE/API2/Storage

svn-commits at proxmox.com svn-commits at proxmox.com
Thu Aug 19 14:46:25 CEST 2010


Author: dietmar
Date: 2010-08-19 12:46:25 +0000 (Thu, 19 Aug 2010)
New Revision: 5033

Modified:
   pve-storage/pve2/ChangeLog
   pve-storage/pve2/PVE/API2/Storage/Content.pm
   pve-storage/pve2/PVE/API2/Storage/Status.pm
   pve-storage/pve2/Storage.pm
   pve-storage/pve2/pvesm
Log:
* pvesm: more cleanups - use new API calls



Modified: pve-storage/pve2/ChangeLog
===================================================================
--- pve-storage/pve2/ChangeLog	2010-08-19 11:34:26 UTC (rev 5032)
+++ pve-storage/pve2/ChangeLog	2010-08-19 12:46:25 UTC (rev 5033)
@@ -1,3 +1,7 @@
+2010-08-19  Proxmox Support Team  <support at proxmox.com>
+
+	* pvesm: more cleanups - use new API calls
+
 2010-08-17  Proxmox Support Team  <support at proxmox.com>
 
 	* API2::Storage.pm: moved from pve-manager

Modified: pve-storage/pve2/PVE/API2/Storage/Content.pm
===================================================================
--- pve-storage/pve2/PVE/API2/Storage/Content.pm	2010-08-19 11:34:26 UTC (rev 5032)
+++ pve-storage/pve2/PVE/API2/Storage/Content.pm	2010-08-19 12:46:25 UTC (rev 5033)
@@ -3,8 +3,10 @@
 use strict;
 use warnings;
 
-use PVE::INotify qw(read_file write_file);;
+use PVE::SafeSyslog;
+use PVE::INotify qw(read_file);;
 use PVE::Storage;
+use PVE::Exception qw(raise_param_exc);
 
 use PVE::RESTHandler;
 
@@ -52,9 +54,7 @@
     parameters => {
     	additionalProperties => 0,
 	properties => {
-	    node => {
-		type => 'string',		
-	    },
+	    node => { type => 'string', format => 'pve-node' },
 	},
     },
     returns => {
@@ -86,7 +86,7 @@
     }});
 
 __PACKAGE__->register_method ({
-    name => 'content', 
+    name => 'list', 
     protected => 1,
     path => '{node}/{storage}',
     method => 'GET',
@@ -94,17 +94,18 @@
     parameters => {
     	additionalProperties => 0,
 	properties => { 
-	    node => {
-		type => 'string',		
+	    node => { type => 'string', format => 'pve-node' },
+	    storage => { type => 'string',  format => 'pve-storage-id' },
+	    content => { 
+		description => "Only list content of this type.",
+		type => 'string', format => 'pve-storage-content',
+		optional => 1,
 	    },
-	    storage => {
-		type => 'string',		
+	    vmid => { 
+		description => "Only list images for this VM",
+		type => 'string', format => 'pve-vmid',
+		optional => 1,		
 	    },
-	    content => {
-		type => 'string',
-		enum => [ @ctypes  ],
-		optional => 1,
-	    }
 	},
     },
     returns => {
@@ -137,7 +138,7 @@
 	foreach my $ct (@$cts) {
 	    my $data;
 	    if ($ct eq 'images') {
-		$data = PVE::Storage::vdisk_list ($cfg, $storeid);
+		$data = PVE::Storage::vdisk_list ($cfg, $storeid, $param->{vmid});
 	    } elsif ($ct eq 'iso') {
 		$data = PVE::Storage::template_list ($cfg, $storeid, 'iso');
 	    } elsif ($ct eq 'vztmpl') {
@@ -157,37 +158,98 @@
     }});
 
 __PACKAGE__->register_method ({
-    name => 'upload', 
+    name => 'create', 
     path => '{node}/{storage}',
     method => 'POST',
-    description => "Upload content.",
+    description => "Allocate or upload content.",
     parameters => {
     	additionalProperties => 0,
 	properties => { 
-	    node => {
-		type => 'string',		
+	    node => { type => 'string', format => 'pve-node' },
+	    storage => { type => 'string',  format => 'pve-storage-id' },
+	    filename => { 
+		description => "The name of the file to create/upload.",
+		type => 'string',
 	    },
-	    storage => {
-		type => 'string',		
+	    vmid => { 
+		description => "Specify owner VM",
+		type => 'string', format => 'pve-vmid',
+		requires => 'size',
+		optional => 1,		
 	    },
-	    upload => {
-		type => 'string',		
+	    # fixme: size in bytes or KBytes?
+	    size => {
+		description => "Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)",
+		type => 'string',
+		pattern => '\d+[MG]?',
+		requires => 'vmid',
+		optional => 1,	
 	    },
+	    'format' => {
+		type => 'string',
+		enum => ['raw', 'qcow2'],
+		requires => 'size',
+		optional => 1,
+	    },
 	},
     },
-    returns => { type => 'null' },
+    returns => {
+	description => "Volume identifier",
+	type => 'string',
+    },
     code => sub {
 	my ($conn, $param) = @_;
 
+	# fixme: connect to node
+	# fixme: can we proxy file uploads at all?
+
 	my $cts = $param->{content} ? [ $param->{content} ] : [ @ctypes ];
 
 	my $node = $param->{node};
 	my $storeid = $param->{storage};
-	my $filename = $param->{upload};
-	my $fh = CGI::upload('upload') || die "unable to get file handle\n";
+	my $name = $param->{filename};
 
-	syslog ('info', "UPLOAD $filename to $node $storeid");
+	if (defined($param->{size})) { # allocate
+
+	    my $sizestr = $param->{size};
+
+	    my $size;
+	    if ($sizestr =~ m/^\d+$/) {
+		$size = $sizestr;
+	    } elsif ($sizestr =~ m/^(\d+)M$/) {
+		$size = $1 * 1024;
+	    } elsif ($sizestr =~ m/^(\d+)G$/) {
+		$size = $1 * 1024 * 1024;
+	    } else {
+		raise_param_exc({ size => "unable to parse size '$sizestr'" });
+	    }
+
+	    # extract FORMAT from name
+	    if ($name =~ m/\.(raw|qcow2)$/) {
+		my $fmt = $1;
+
+		raise_param_exc({ format => "different storage formats ($param->{format} != $fmt)" }) 
+		    if $param->{format} && $param->{format} ne $fmt;
+
+		$param->{format} = $fmt;
+	    }
+
+	    my $cfg = read_file('storagecfg');
+    
+	    my $volid = PVE::Storage::vdisk_alloc ($cfg, $storeid, $param->{vmid}, 
+						   $param->{format}, 
+						   $name, $size);
+
+	    return $volid;
+	} 
+
+	# else we want to upload something
+
+	my $fh = CGI::upload('filename') || die "unable to get file handle\n";
+
+	syslog ('info', "UPLOAD $name to $node $storeid");
 	
+	# fixme:
 	die "upload not implemented\n";
 
 	my $buffer = "";
@@ -209,7 +271,63 @@
 
 	unlink $tmpname; # fixme: proxy to local host import
 
+	# fixme: return volid
+
 	return undef;
+
     }});
 
+__PACKAGE__->register_method ({
+    name => 'delete',
+    protected => 1,
+    # fixme: volid is allowed to contain '/' - how can we fix that ?
+    path => '{node}/{storage}/{volid}',
+    method => 'DELETE',
+    description => "Delete volume",
+    parameters => {
+    	additionalProperties => 0,
+	properties => { 
+	    node => { type => 'string', format => 'pve-node' },
+	    storage => { 
+		type => 'string', format => 'pve-storage-id',
+		optional => 1,
+	    },
+	    volume => {
+		description => "Volume identifier",
+		type => 'string' 
+	    },
+	},
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($conn, $param) = @_;
+
+	# fixme: connect to node
+
+	my $storeid = $param->{storage};
+
+	my $volid;
+
+	if ($param->{volume} =~ m/:/) {
+	    eval {
+		my ($sid, $volname) = PVE::Storage::parse_volume_id ($param->{volume});
+		raise_param_exc({ storage => "storage ID missmatch" }) 
+		    if $storeid && $sid ne $storeid;
+		$volid = $param->{volume};
+	    };
+	    raise_param_exc({ volume => $@}) if $@; 
+	   
+	} else {
+	    raise_param_exc({ volume => "no storage speficied - incomplete volume ID" }) 
+		if !$storeid;
+	    
+	    $volid = "$storeid:$param->{volume}";
+	}
+
+	my $cfg = read_file('storagecfg');
+
+	PVE::Storage::vdisk_free ($cfg, $volid);
+
+	return undef;
+    }});
 1;

Modified: pve-storage/pve2/PVE/API2/Storage/Status.pm
===================================================================
--- pve-storage/pve2/PVE/API2/Storage/Status.pm	2010-08-19 11:34:26 UTC (rev 5032)
+++ pve-storage/pve2/PVE/API2/Storage/Status.pm	2010-08-19 12:46:25 UTC (rev 5033)
@@ -47,16 +47,13 @@
 __PACKAGE__->register_method ({
     name => 'list_status', 
     protected => 1,
-    # /storage/status/{nodeid}
     path => 'status/{node}',
     method => 'GET',
     description => "Get status for all datastores.",
     parameters => {
     	additionalProperties => 0,
 	properties => {
-	    node => {
-		type => 'string',
-	    }
+	    node => { type => 'string', format => 'pve-node' },
 	},
     },
     returns => {
@@ -95,12 +92,8 @@
     parameters => {
     	additionalProperties => 0,
 	properties => {
-	    node => {
-		type => 'string',		
-	    },
-	    storage => {
-		type => 'string',		
-	    },
+	    node => { type => 'string', format => 'pve-node' },
+	    storage => { type => 'string',  format => 'pve-storage-id' },
 	},
     },
     returns => {},

Modified: pve-storage/pve2/Storage.pm
===================================================================
--- pve-storage/pve2/Storage.pm	2010-08-19 11:34:26 UTC (rev 5032)
+++ pve-storage/pve2/Storage.pm	2010-08-19 12:46:25 UTC (rev 5033)
@@ -60,6 +60,29 @@
     return $hostname;
 }
 
+PVE::JSONSchema::register_format('pve-vmid', \&verify_vmid);
+sub verify_vmid {
+    my ($vmid, $noerr) = @_;
+
+    if ($vmid !~ m/^[1-9][0-9]+$/) {
+	return undef if $noerr;
+	die "value does not look like a valid VM ID\n";
+    }
+    return $vmid;
+}
+
+PVE::JSONSchema::register_format('pve-node', \&verify_node_name);
+sub verify_node_name {
+    my ($node, $noerr) = @_;
+
+    # fixme: use better regex ?
+    if ($node !~ m/^[[:alnum:]\-]+$/) {
+	return undef if $noerr;
+	die "value does not look like a valid node name\n";
+    }
+    return $node;
+}
+
 sub read_cluster_config {
     my ($filename, $fh) = @_;
 
@@ -1572,7 +1595,7 @@
 sub vdisk_free {
     my ($cfg, $volid) = @_;
 
-    my ($storeid, $volname) = PVE::Storage::parse_volume_id ($volid);
+    my ($storeid, $volname) = parse_volume_id ($volid);
 
     my $scfg = storage_config ($cfg, $storeid);
 
@@ -2514,18 +2537,4 @@
     return undef;
 }
 
-sub foreach_volid {
-    my ($list, $func) = @_;
-
-    return if !$list;
-
-    foreach my $sid (keys %$list) {
-	foreach my $info (@{$list->{$sid}}) {
-	    my $volname = $info->{volname};
-	    my $volid = "$sid:$volname";
-	    &$func ($volid, $sid, $volname, $info);
-	}
-    }
-}
-
 1;

Modified: pve-storage/pve2/pvesm
===================================================================
--- pve-storage/pve2/pvesm	2010-08-19 11:34:26 UTC (rev 5032)
+++ pve-storage/pve2/pvesm	2010-08-19 12:46:25 UTC (rev 5033)
@@ -2,18 +2,24 @@
 
 use strict;
 use Getopt::Long;
+use Fcntl ':flock';
+use File::Path;
+
 use PVE::INotify qw(read_file);
 use PVE::Storage;
 use PVE::API2::Storage::Config;
-use Fcntl ':flock';
-use File::Path;
+use PVE::API2::Storage::Content;
+use PVE::API2::Storage::Status;
 
+use Data::Dumper; # fixme: remove 
+
 $ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
 
 die "please run as root\n" if $> != 0;
 
 PVE::INotify::inotify_init();
 
+# fixme:
 sub print_usage {
     my $msg = shift;
 
@@ -26,91 +32,37 @@
     exit (-1);
 }
 
-sub print_storage_list {
-    my ($cfg, $storeid, $vmid) = @_;
+sub print_content {
+    my ($sid, $list) = @_;
 
-    my $res = PVE::Storage::vdisk_list ($cfg, $storeid, $vmid);
-
     my $maxlenname = 0;
-    my $maxlenvmid = 0;
+    foreach my $info (@$list) {
 
-    PVE::Storage::foreach_volid ($res, sub {
-	my ($volid, $sid, $volname, $info) = @_;
-	   
+	my $volname = $info->{volname};
+	my $volid = "$sid:$volname";
 	my $sidlen =  length ($volid);
 	$maxlenname = $sidlen if $sidlen > $maxlenname;
-	my $vmid = $info->{vmid};
-	$maxlenvmid = length ($vmid) if length ($vmid) > $maxlenvmid;
-    });
-
-
-    PVE::Storage::foreach_volid ($res, sub {
-	my ($volid, $sid, $volname, $info) = @_;
-	
-	printf "%-${maxlenname}s %-${maxlenvmid}d %5s %10d\n", $volid, 
-	$info->{vmid}, $info->{format}, $info->{size}; 
-    });
-}
-
-sub print_tmpl_list {
-    my ($vlist) = @_;
-
-    PVE::Storage::foreach_volid ($vlist, sub {
-	my ($volid, $sid, $volname, $info) = @_;
-	print "$volid\n"; 
-    });
-}
-
-sub print_iso_list {
-    my ($cfg, $storeid) = @_;
-
-    if ($storeid) {
-	my $scfg = PVE::Storage::storage_config ($cfg, $storeid);     
-	if (!$scfg->{content}->{iso}) {
-	    warn "storage does not support iso images\n";
-	    return;
-	}
     }
 
-    my $res = PVE::Storage::template_list ($cfg, $storeid, 'iso');
-    
-    print_tmpl_list ($res);
-    
-}
+    foreach my $info (@$list) {
+	my $volname = $info->{volname};
+	my $volid = "$sid:$volname";
+	next if !$info->{vmid};
 
-sub print_vztmpl_list {
-    my ($cfg, $storeid) = @_;
-
-    if ($storeid) {
-	my $scfg = PVE::Storage::storage_config ($cfg, $storeid);
-	if (!$scfg->{content}->{vztmpl}) {
-	    warn "storage does not support openvz templates\n";
-	    return;
-	}
+	printf "%-${maxlenname}s %5s %10d %d\n", $volid, 
+	$info->{format}, $info->{size}, $info->{vmid}; 
     }
 
-    my $res = PVE::Storage::template_list ($cfg, $storeid, 'vztmpl');
-    
-    print_tmpl_list ($res);
-}
+    foreach my $info (sort { $a->{format} cmp $b->{format} } @$list) {
+	next if $info->{vmid};
+	my $volname = $info->{volname};
+	my $volid = "$sid:$volname";
 
-sub print_backup_list {
-    my ($cfg, $storeid) = @_;
-
-    if ($storeid) {
-	my $scfg = PVE::Storage::storage_config ($cfg, $storeid);
-	if (!$scfg->{content}->{backup}) {
-	    warn "storage does not support backup files\n";
-	    return;
-	}
+	printf "%-${maxlenname}s %5s %10d\n", $volid, 
+	$info->{format}, $info->{size}; 
     }
-
-    my $res = PVE::Storage::template_list ($cfg, $storeid, 'backup');
-    
-    print_tmpl_list ($res);
 }
 
-
 my $cmd = shift;
 
 if ($cmd eq 'add') {
@@ -144,10 +96,6 @@
     $opts->{storage} = shift;
     $opts->{disable} = 0;
 
-    if (scalar (@ARGV) != 0) {
-	die "wrong number of arguments\n";
-    }
-
     PVE::API2::Storage::Config->cli_handler('update', \@ARGV, $opts);
 
 } elsif ($cmd eq 'disable') {
@@ -157,154 +105,67 @@
     $opts->{storage} = shift;
     $opts->{disable} = 1;
 
-    if (scalar (@ARGV) != 0) {
-	die "wrong number of arguments\n";
-    }
-
     PVE::API2::Storage::Config->cli_handler('update', \@ARGV, $opts);
 
-} elsif ($cmd eq 'alloc') {
+} elsif ($cmd eq 'status') {
 
     my $opts = {};
 
-    if (!GetOptions ($opts, 'format=s')) {
-	exit (-1);
-    }
+    $opts->{node} = read_file('hostname');
 
-    if (scalar (@ARGV) != 4) {
-	die "wrong number of arguments\n";
-    }
+    my $res = PVE::API2::Storage::Status->cli_handler('list_status', \@ARGV, $opts);
 
-    my $storeid = shift;
-    my $vmid = shift;
-
-    my $name = shift;
-    my $sizestr = shift;
-
-    # extract FORMAT from name
-    if ($name =~ m/\.(raw|qcow2)$/) {
-	my $fmt = $1;
-
-	die "different storage formats ($opts->{format} != $fmt)\n" 
-	    if $opts->{format} && $opts->{format} ne $fmt;
-
-	$opts->{format} = $fmt;
+    my $maxlen = 0;
+    foreach my $res (@$res) {
+	my $storeid = $res->{storage};
+	$maxlen = length ($storeid) if length ($storeid) > $maxlen;
     }
-
-    die "unknown storage format '$opts->{format}'\n" 
-	if $opts->{format} && $opts->{format} !~ m/^(raw|qcow2)$/;
-
-    my $size;
-    if ($sizestr =~ m/^\d+$/) {
-	$size = $sizestr;
-    } elsif ($sizestr =~ m/^(\d+)M$/) {
-	$size = $1 * 1024;
-    } elsif ($sizestr =~ m/^(\d+)G$/) {
-	$size = $1 * 1024 * 1024;
-    } else {
-	die "unable to parse size '$sizestr'\n";
-    }
-
-    my $cfg = read_file('storagecfg');
+    $maxlen+=1;
     
-    my $volid = PVE::Storage::vdisk_alloc ($cfg, $storeid, $vmid, 
-					   $opts->{format}, 
-					   $name, $size);
+    foreach my $res (sort { $a->{storage} cmp $b->{storage} } @$res) {
+	my $storeid = $res->{storage};
 
-    print "sucessfuly created '$volid'\n";
+	my $per = $res->{avail} ? int (0.5 + ($res->{used}*100)/$res->{avail}) : 100;
 
-} elsif ($cmd eq 'free') {
-
-    if (scalar (@ARGV) != 1) {
-	die "wrong number of arguments\n";
+	printf "%-${maxlen}s %5s %1d %1d %10d %10d %2d%%\n", $storeid, 
+	$res->{type},$res->{disable}, $res->{active},
+	$res->{avail}, $res->{used}, $per; 
     }
 
-    my $volid = shift;
-
-    my $cfg = read_file('storagecfg');
-    
-    PVE::Storage::vdisk_free ($cfg, $volid);
-
 } elsif ($cmd eq 'list') {
 
-    my $opts = {};
+   my $opts = {};
 
-    if (!GetOptions ($opts, 'id=s', 'vmid=i', 'all', 'iso', 'vztmpl', 'backup')) {
-	exit (-1);
-    }
+   $opts->{storage} = shift;
+   $opts->{node} = read_file('hostname');
 
-    if (scalar (@ARGV) != 0) {
-	die "wrong number of arguments\n";
-    }
- 
-    my $cfg = read_file('storagecfg');
+   my $res = PVE::API2::Storage::Content->cli_handler('list', \@ARGV, $opts);
 
-    my @sids =  PVE::Storage::storage_ids ($cfg);
+   print_content($opts->{storage}, $res);
 
-    my $storeid = $opts->{id};
-    my $vmid = $opts->{vmid};
+} elsif ($cmd eq 'alloc') {
 
-    if ($opts->{iso}) {
+   my $opts = {};
 
-	print_iso_list ($cfg, $storeid);
+   $opts->{node} = read_file('hostname');
 
-    } elsif ($opts->{vztmpl}) {
+   my $volid = PVE::API2::Storage::Content->cli_handler('create', \@ARGV, $opts);
 
-	print_vztmpl_list ($cfg, $storeid);
+   print "sucessfuly created '$volid'\n";
 
-    } elsif ($opts->{backup}) {
+} elsif ($cmd eq 'free') {
 
-	print_backup_list ($cfg, $storeid);
-
-    } elsif (!(defined ($storeid) || defined ($vmid))) {
-	my $maxlen = 0;
-	foreach $storeid (@sids) {
-	    $maxlen = length ($storeid) if length ($storeid) > $maxlen;
-	}
-	$maxlen+=1;
-
-	if ($opts->{all}) {
-	    foreach $storeid (@sids) {
-		my $scfg =  PVE::Storage::storage_config ($cfg, $storeid);
-		next if $scfg->{disable};
-		print_storage_list ($cfg, $storeid, $vmid);
-	    }
-	} else {
-	    my $info = PVE::Storage::storage_info ($cfg);
- 	    
-	    foreach $storeid (sort keys %$info) {
-		my $res = $info->{$storeid};
-
-		my $per = $res->{avail} ? int (0.5 + ($res->{used}*100)/$res->{avail}) : 100;
-
-		printf "%-${maxlen}s %5s %1d %1d %10d %10d %2d%%\n", $storeid, 
-		$res->{type},$res->{disable}, $res->{active},
-		$res->{avail}, $res->{used}, $per; 
-	    }
-	}
-
-    } else {
-	
-	print_storage_list ($cfg, $storeid, $vmid);
-
-    }
-
-} elsif ($cmd eq 'path') {
-
-    my $opts = {};
-
     if (scalar (@ARGV) != 1) {
 	die "wrong number of arguments\n";
     }
 
-    my $volid = shift;
+    my $opts = {};
 
-    my $cfg = read_file('storagecfg');
+    $opts->{node} = read_file('hostname');
+    $opts->{volume} = shift;
 
-    my $path = PVE::Storage::path ($cfg, $volid);
+    PVE::API2::Storage::Content->cli_handler('delete', \@ARGV, $opts);
 
-    print "$path\n";
-
 } elsif ($cmd eq 'scan') {
 
     if (scalar (@ARGV) != 2) {
@@ -335,6 +196,22 @@
 	die "can't execute scan for storage type '$type'\n";
     }
 
+} elsif ($cmd eq 'path') {
+
+    my $opts = {};
+
+    if (scalar (@ARGV) != 1) {
+	die "wrong number of arguments\n";
+    }
+
+    my $volid = shift;
+
+    my $cfg = read_file('storagecfg');
+
+    my $path = PVE::Storage::path ($cfg, $volid);
+
+    print "$path\n";
+
 } elsif ($cmd eq 'lock') {
 
     if (scalar (@ARGV) != 1 && scalar (@ARGV) != 2) {




More information about the pve-devel mailing list