[pve-devel] r5022 - pve-storage/pve2

svn-commits at proxmox.com svn-commits at proxmox.com
Tue Aug 17 09:08:31 CEST 2010


Author: dietmar
Date: 2010-08-17 07:08:31 +0000 (Tue, 17 Aug 2010)
New Revision: 5022

Added:
   pve-storage/pve2/API2Storage.pm
Modified:
   pve-storage/pve2/ChangeLog
   pve-storage/pve2/Makefile
Log:
* API2::Storage.pm: moved from pve-manager



Added: pve-storage/pve2/API2Storage.pm
===================================================================
--- pve-storage/pve2/API2Storage.pm	                        (rev 0)
+++ pve-storage/pve2/API2Storage.pm	2010-08-17 07:08:31 UTC (rev 5022)
@@ -0,0 +1,572 @@
+package PVE::API2::Storage;
+
+# fixme: split things into different files?
+
+# /storage/config GET whole config, CREATE storage
+# /storage/config/{storeid}/ GET/SET storage config
+
+# /storage/status/{node}/ GET/SET status list
+# /storage/status/{node}/{storeid}  GET/SET state (activate/disable)
+
+# /storage/content/{node}/{storeid}/  list/upload content
+# /storage/content/{node}/{storeid}/{volname} DELETE content
+
+
+# /storage/scan/lvm list volume groups
+# /storage/scan/nfs list nfs exports
+# /storage/scan/iscsi list iscsi exports
+
+
+# iso/*.iso
+# vztmpl/*.tgz
+# backup/*.tar
+# images/{vmid}/*.qcow2
+# images/vm-100-test1
+
+use strict;
+use warnings;
+
+use PVE::SafeSyslog;
+use PVE::Inotify qw(read_file write_file);;
+use PVE::Storage;
+use HTTP::Status qw(:constants);
+
+use Data::Dumper; # fixme: remove
+
+use PVE::RESTHandler;
+
+use base qw(PVE::RESTHandler);
+
+my @ctypes = qw(images vztmpl iso backup);
+
+__PACKAGE__->register_method ({
+    name => 'index', 
+    path => '', # /storage/
+    method => 'GET',
+    description => "Storage index.",
+    parameters => {
+    	additionalProperties => 0,
+	properties => {},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => { subdir => { type => 'string'} },
+	},
+	links => [ { rel => 'child', href => "{subdir}" } ],
+    },
+    code => sub {
+	my ($conn, $param) = @_;
+
+	my $res = [
+	    { subdir => 'config' },
+	    { subdir => 'status' },
+	    { subdir => 'content' },
+	    { subdir => 'index' },
+	    { subdir => 'scan' },
+	    ];
+	return $res;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'read_config', 
+    path => 'config/{storage}', 
+    method => 'GET',
+    description => "Read storage configuration.",
+    parameters => {
+    	additionalProperties => 0,
+	properties => {
+	    storage => { type => 'string' },
+	},
+    },
+    returns => {},
+    code => sub {
+	my ($conn, $param) = @_;
+
+	my $cfg = read_file ("storagecfg");
+
+	my $scfg = PVE::Storage::storage_config ($cfg, $param->{storage});
+
+	$scfg->{digest} = $cfg->{digest};
+	$scfg->{time} = time(); # fixme: remove
+
+	my @cta;
+	foreach my $ct (keys %{$scfg->{content}}) {
+	    push @cta, $ct if $scfg->{content}->{$ct};
+	} 
+
+	$scfg->{content} =  join(',', @cta);
+ 
+	return $scfg;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'update_config',
+    protected => 1,
+    path => 'config/{storage}', 
+    method => 'PUT',
+    description => "Update storage configuration.",
+    parameters => {
+    	additionalProperties => 0,
+	properties => { 
+	    storage => { 
+		type => 'string', 
+	    },
+	    path => {
+		type => 'string',
+		optional => 1,
+	    },
+	    content => {
+		type => 'string',
+		optional => 1,
+	    },
+	    disable => {
+		type => 'boolean',
+		optional => 1,
+	    },
+	    shared => {
+		type => 'boolean',
+		optional => 1,
+	    },
+	    digest => {
+		type => 'string',
+		optional => 1,
+	    }
+	},
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($conn, $param) = @_;
+
+	my $storeid = $param->{storage};
+	delete($param->{storage});
+ 
+	my $digest = $param->{digest};
+	delete($param->{digest});
+
+	PVE::Storage::storage_set($storeid, $param, $digest);
+
+	return undef;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'list_storage_config', 
+    path => 'config', # /storage/config
+    method => 'GET',
+    description => "Storage index.",
+    parameters => {
+    	additionalProperties => 0,
+	properties => {},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => { storage => { type => 'string'} },
+	},
+	links => [ { rel => 'child', href => "{storage}" } ],
+    },
+    code => sub {
+	my ($conn, $param) = @_;
+
+	my $cfg = read_file ("storagecfg");
+
+	my @sids =  PVE::Storage::storage_ids ($cfg);
+
+	my $res = [];
+	foreach my $storeid (@sids) {
+	    my $scfg = PVE::Storage::storage_config ($cfg, $storeid);
+	    $scfg->{storage} = $storeid;
+	    push @$res, $scfg;
+	}
+
+	return $res;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'scan_index', 
+    path => 'scan', 
+    method => 'GET',
+    description => "Index of available scan methods",
+    parameters => {
+    	additionalProperties => 0,
+	properties => {},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => { method => { type => 'string'} },
+	},
+	links => [ { rel => 'child', href => "{method}" } ],
+    },
+    code => sub {
+	my ($conn, $param) = @_;
+
+	my $res = [ 
+	    { method => 'lvm' },
+	    { method => 'iscsi' },
+	    { method => 'nfs' },
+	    ];
+
+	return $res;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'scan_server', 
+    path => 'scan/{method}', 
+    method => 'GET',
+    description => "Scan remote storage server.",
+    parameters => {
+    	additionalProperties => 0,
+	properties => {
+	    method => { 
+		type => 'string',
+		enum => [ 'lvm', 'nfs', 'iscsi' ],
+	    }
+	},
+    },
+    returns => {},
+    code => sub {
+	my ($conn, $param) = @_;
+
+	return [];
+    }});
+
+# fixme: move to somewhere else
+__PACKAGE__->register_method ({
+    name => 'cluster_index', 
+    path => 'index', 
+    method => 'GET',
+    description => "Cluster wide storage status.",
+    parameters => {
+    	additionalProperties => 0,
+	properties => {},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => {},
+	},
+#	links => [ { rel => 'child', href => "{storage}" } ],
+    },
+    code => sub {
+	my ($conn, $param) = @_;
+
+	my $nodes = [ 'node-0', 'node-1', 'node-2', 'node-3' ]; # fixme: use the real list
+
+	my $cfg = read_file ("storagecfg");
+
+	my @sids =  PVE::Storage::storage_ids ($cfg);
+
+	my $res = [];
+	foreach my $storeid (@sids) {
+	    my $scfg =  PVE::Storage::storage_config ($cfg, $storeid);
+	    if ($scfg->{shared}) {
+		my $data = { name => $storeid, storage => $storeid, type => $scfg->{type}, shared => 1};
+		push @$res, $data;
+	    } else {
+		# we create a entry for each node
+		foreach my $node (@$nodes) {
+		    my $data = { name => "$storeid ($node)", storage => $storeid, node => $node, 
+				 type => $scfg->{type}, shared => 0};
+		    push @$res, $data;
+		}
+	    }
+	}
+
+	# $resp->{digest} = $cfg->{digest}; # fixme: how do we handle that
+
+	return $res;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'list_nodes', 
+    # /storage/(status|content)
+    path => '{subdir}',  
+    method => 'GET',
+    description => "List storage nodes.",
+    parameters => {
+    	additionalProperties => 0,
+	properties => {
+	    subdir => {
+		type => 'string',
+		enum => [ 'status', 'content' ],
+	    },
+	},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => { node => { type => 'string' } },
+	},
+	links => [ { rel => 'child', href => "{node}" } ],
+    },
+    code => sub {
+	my ($conn, $param) = @_;
+
+	# fixme: use the real list
+	my $nodes = [ 
+	    { node => 'node-0'},
+	    { node => 'node-1'},
+	    { node => 'node-2'},
+	    { node => 'node-3'},
+	    ];
+
+	return $nodes;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'list_store_ids', 
+    # /storage/content/{node}/
+    path => 'content/{node}', 
+    method => 'GET',
+    description => "List storage IDs.",
+    parameters => {
+    	additionalProperties => 0,
+	properties => {
+	    node => {
+		type => 'string',		
+	    },
+	},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => { storage => { type => 'string' } },
+	},
+	links => [ { rel => 'child', href => "{storage}" } ],
+    },
+    code => sub {
+	my ($conn, $param) = @_;
+
+	my $cfg = read_file ("storagecfg");
+
+	my $node = $param->{node};
+
+	# fixme: verify node (node exists)?
+
+	my @sids =  PVE::Storage::storage_ids ($cfg);
+
+	my $res = [];
+	foreach my $storeid (@sids) {
+	    # fixme: check if storeage exists on node ?
+	    push @$res, { storage => $storeid };
+	}
+
+	return $res;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'list_content', 
+    protected => 1,
+    # /storage/content/{nodeid}/{storeid}
+    path => 'content/{node}/{storage}',
+    method => 'GET',
+    description => "List storage content.",
+    parameters => {
+    	additionalProperties => 0,
+	properties => { 
+	    node => {
+		type => 'string',		
+	    },
+	    storage => {
+		type => 'string',		
+	    },
+	    content => {
+		type => 'string',
+		enum => [ @ctypes  ],
+		optional => 1,
+	    }
+	},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => { 
+		volname => { 
+		    type => 'string' 
+		} 
+	    },
+	},
+	links => [ { rel => 'child', href => "{volname}" } ],
+    },
+    code => sub {
+	my ($conn, $param) = @_;
+
+	my $cts = $param->{content} ? [ $param->{content} ] : [ @ctypes ];
+
+	my $node = $param->{node};
+	my $storeid = $param->{storage};
+
+	# fixme: verify $node
+
+	my $cfg = read_file ("storagecfg");
+
+	my $scfg = PVE::Storage::storage_config ($cfg, $storeid);
+
+	my $res = [];
+	foreach my $ct (@$cts) {
+	    my $data;
+	    if ($ct eq 'images') {
+		$data = PVE::Storage::vdisk_list ($cfg, $storeid);
+	    } elsif ($ct eq 'iso') {
+		$data = PVE::Storage::template_list ($cfg, $storeid, 'iso');
+	    } elsif ($ct eq 'vztmpl') {
+		$data = PVE::Storage::template_list ($cfg, $storeid, 'vztmpl');
+	    } elsif ($ct eq 'backup') {
+		$data = PVE::Storage::template_list ($cfg, $storeid, 'backup');
+	    }
+
+	    next if !$data || !$data->{$storeid};
+
+	    foreach my $item (@{$data->{$storeid}}) {
+		push @$res, $item;
+	    }
+	}
+
+	return $res;    
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'upload_content', 
+    # /storage/content/{nodeid}/{storeid}
+    path => 'content/{node}/{storage}',
+    method => 'POST',
+    description => "Upload content.",
+    parameters => {
+    	additionalProperties => 0,
+	properties => { 
+	    node => {
+		type => 'string',		
+	    },
+	    storage => {
+		type => 'string',		
+	    },
+	    upload => {
+		type => 'string',		
+	    },
+	},
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($conn, $param) = @_;
+
+	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";
+
+	syslog ('info', "UPLOAD $filename to $node $storeid");
+	
+	die "upload not implemented\n";
+
+	my $buffer = "";
+	my $tmpname = "/tmp/proxmox_upload-$$.bin";
+
+	eval {
+	    open FILE, ">$tmpname" || die "can't open temporary file '$tmpname' - $!\n";
+	    while (read($fh, $buffer, 32768)) {
+		die "write failed - $!" unless print FILE $buffer;
+	    }
+	    close FILE || die " can't close temporary file '$tmpname' - $!\n";
+	};
+	my $err = $@;
+
+	if ($err) {
+	    unlink $tmpname;
+	    die $err;
+	}
+
+	unlink $tmpname; # fixme: proxy to local host import
+
+	return undef;
+    }});
+
+__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',
+	    }
+	},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => { storage => { type => 'string' } },
+	},
+	links => [ { rel => 'child', href => "{storage}" } ],
+    },
+    code => sub {
+	my ($conn, $param) = @_;
+
+	my $cts = $param->{content} ? [ $param->{content} ] : [ @ctypes ];
+	
+	my $node = $param->{node};
+
+	# fixme: verify $node
+
+	my $cfg = read_file ("storagecfg");
+
+	# fixme: connect to correct node
+
+	my $info = PVE::Storage::storage_info ($cfg);
+
+	return PVE::RESTHandler::hash_to_array($info, 'storage');
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'get_status', 
+    protected => 1,
+    # /storage/status/{nodeid}/{storeid}
+    path => 'status/{node}/{storage}',
+    method => 'GET',
+    description => "Get status for specific datastore.",
+    parameters => {
+    	additionalProperties => 0,
+	properties => {
+	    node => {
+		type => 'string',		
+	    },
+	    storage => {
+		type => 'string',		
+	    },
+	},
+    },
+    returns => {},
+    code =>  sub {
+	my ($conn, $param) = @_;
+
+	my $cts = $param->{content} ? [ $param->{content} ] : [ @ctypes ];
+
+	my $node = $param->{node};
+	my $storeid = $param->{storage};
+
+	# fixme: verify $node
+
+	my $cfg = read_file ("storagecfg");
+
+	# fixme: connect to correct node
+
+	my $info = PVE::Storage::storage_info ($cfg);
+	
+	return $info->{$storeid};
+    }});
+
+1;

Modified: pve-storage/pve2/ChangeLog
===================================================================
--- pve-storage/pve2/ChangeLog	2010-08-16 12:19:16 UTC (rev 5021)
+++ pve-storage/pve2/ChangeLog	2010-08-17 07:08:31 UTC (rev 5022)
@@ -1,3 +1,7 @@
+2010-08-17  Proxmox Support Team  <support at proxmox.com>
+
+	* API2::Storage.pm: moved from pve-manager
+
 2010-08-16  Proxmox Support Team  <support at proxmox.com>
 
 	* Storage.pm (file_read_firstline): import from PVE::Tools

Modified: pve-storage/pve2/Makefile
===================================================================
--- pve-storage/pve2/Makefile	2010-08-16 12:19:16 UTC (rev 5021)
+++ pve-storage/pve2/Makefile	2010-08-17 07:08:31 UTC (rev 5022)
@@ -24,15 +24,16 @@
 dinstall: deb
 	dpkg -i ${DEB}
 
-install: pvesm Storage.pm 
+install: pvesm Storage.pm API2Storage.pm
 	install -d ${DESTDIR}${SBINDIR}
 	install -m 0755 pvesm ${DESTDIR}${SBINDIR}
 	install -D -m 0644 Storage.pm ${DESTDIR}${PERLDIR}/PVE/Storage.pm
+	install -D -m 0644 API2Storage.pm ${DESTDIR}${PERLDIR}/PVE/API2/Storage.pm
 	install -d ${DESTDIR}/usr/share/man/man1
 	pod2man -n pvesm -s 1 -r "proxmox 1.0" -c "Proxmox Documentation" <pvesm | gzip -9 > ${DESTDIR}/usr/share/man/man1/pvesm.1.gz
 
 .PHONY: deb
-deb ${DEB}: pvesm Storage.pm control.in copyright changelog.Debian ChangeLog
+deb ${DEB}: pvesm Storage.pm API2Storage.pm control.in copyright changelog.Debian ChangeLog
 	rm -rf debian
 	mkdir debian
 	make DESTDIR=debian install



More information about the pve-devel mailing list