[pve-devel] r4916 - in pve-manager/pve2: . lib/PVE lib/PVE/API2

svn-commits at proxmox.com svn-commits at proxmox.com
Mon Jul 19 15:31:56 CEST 2010


Author: dietmar
Date: 2010-07-19 13:31:55 +0000 (Mon, 19 Jul 2010)
New Revision: 4916

Modified:
   pve-manager/pve2/ChangeLog
   pve-manager/pve2/lib/PVE/API2.pm
   pve-manager/pve2/lib/PVE/API2/AccessControl.pm
   pve-manager/pve2/lib/PVE/API2/Cluster.pm
   pve-manager/pve2/lib/PVE/API2/Storage.pm
   pve-manager/pve2/lib/PVE/API2/User.pm
   pve-manager/pve2/lib/PVE/API2/VM.pm
   pve-manager/pve2/lib/PVE/JSONSchema.pm
   pve-manager/pve2/lib/PVE/RESTHandler.pm
Log:
	* lib/PVE/RESTHandler.pm (AUTOLOAD): make accessors for methods

	* lib/PVE/JSONSchema.pm (check_type): implement 'coderef' type (we
	use this type to link method implementations)



Modified: pve-manager/pve2/ChangeLog
===================================================================
--- pve-manager/pve2/ChangeLog	2010-07-19 11:27:51 UTC (rev 4915)
+++ pve-manager/pve2/ChangeLog	2010-07-19 13:31:55 UTC (rev 4916)
@@ -1,5 +1,10 @@
 2010-07-19  Proxmox Support Team  <support at proxmox.com>
 
+	* lib/PVE/RESTHandler.pm (AUTOLOAD): make accessors for methods
+
+	* lib/PVE/JSONSchema.pm (check_type): implement 'coderef' type (we
+	use this type to link method implementations)
+
 	* lib/PVE/RESTHandler.pm (register_method): implement some kind of
 	uri templates. We can now use "path => 'config/{storage}'" instead
 	of clumsy "match_re" array.

Modified: pve-manager/pve2/lib/PVE/API2/AccessControl.pm
===================================================================
--- pve-manager/pve2/lib/PVE/API2/AccessControl.pm	2010-07-19 11:27:51 UTC (rev 4915)
+++ pve-manager/pve2/lib/PVE/API2/AccessControl.pm	2010-07-19 13:31:55 UTC (rev 4916)
@@ -35,23 +35,22 @@
 	},
 	links => [ { rel => 'child', href => "{subdir}" } ],
     },
-}); 
-sub index {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
     
-    my $res = [];
+	my $res = [];
 
-    my $ma = __PACKAGE__->method_attributes();
+	my $ma = __PACKAGE__->method_attributes();
 
-    foreach my $info (@$ma) {
-	next if !$info->{subclass};
+	foreach my $info (@$ma) {
+	    next if !$info->{subclass};
 
-	my $subpath = $info->{match_re}->[0];
+	    my $subpath = $info->{match_re}->[0];
 
-	push @$res, { subdir => $subpath };
-    }
+	    push @$res, { subdir => $subpath };
+	}
 
-    return $res;
-}
+	return $res;
+    }});
 
 1;

Modified: pve-manager/pve2/lib/PVE/API2/Cluster.pm
===================================================================
--- pve-manager/pve2/lib/PVE/API2/Cluster.pm	2010-07-19 11:27:51 UTC (rev 4915)
+++ pve-manager/pve2/lib/PVE/API2/Cluster.pm	2010-07-19 13:31:55 UTC (rev 4916)
@@ -20,44 +20,41 @@
     	additionalProperties => 0,
 	properties => {},
     },
-     returns => {
+    returns => {
 	type => 'array',
 	items => {
 	    type => "object",
 	    properties => {},
 	},
-	links => [
-	    { rel => 'child', href => "{name}" }, 
-	    ],
+	links => [ { rel => 'child', href => "{name}" } ],
     },
-});
-sub index {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
     
-    # fixme: this is just some test code
+	# fixme: this is just some test code
 
-    my $ctime = int(time()/1);
-    $ctime = 0;
+	my $ctime = int(time()/1);
+	$ctime = 0;
 
-    #my $count = 30 + ($ctime % 10);
-    my $count = 4;
+	#my $count = 30 + ($ctime % 10);
+	my $count = 4;
 
-    my $result = [];
-    for (my $i = 0; $i < $count; $i++) {
-	my $tag = int($i / 4);
-	my $store = int($i / 2);
-	push @$result, { 
-	    name => "node-$i",
+	my $result = [];
+	for (my $i = 0; $i < $count; $i++) {
+	    my $tag = int($i / 4);
+	    my $store = int($i / 2);
+	    push @$result, { 
+		name => "node-$i",
 #	    storage => "store-$store",
-	    cpu => 0.5,
-	    maxcpu => 16,
-	    uptime => 20*3600*24,
-	    mem => 0,
-	    maxmem => 10
-	};
-    }
+		cpu => 0.5,
+		maxcpu => 16,
+		uptime => 20*3600*24,
+		mem => 0,
+		maxmem => 10
+	    };
+	}
 
-    return $result;
-}
+	return $result;
+    }});
 
 1;

Modified: pve-manager/pve2/lib/PVE/API2/Storage.pm
===================================================================
--- pve-manager/pve2/lib/PVE/API2/Storage.pm	2010-07-19 11:27:51 UTC (rev 4915)
+++ pve-manager/pve2/lib/PVE/API2/Storage.pm	2010-07-19 13:31:55 UTC (rev 4916)
@@ -56,22 +56,19 @@
 	},
 	links => [ { rel => 'child', href => "{subdir}" } ],
     },
-});
-sub index {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    my $res = [
-	{ subdir => 'config' },
-	{ subdir => 'status' },
-	{ subdir => 'content' },
-	{ subdir => 'index' },
-	{ subdir => 'scan' },
-	];
+	my $res = [
+	    { subdir => 'config' },
+	    { subdir => 'status' },
+	    { subdir => 'content' },
+	    { subdir => 'index' },
+	    { subdir => 'scan' },
+	    ];
+	return $res;
+    }});
 
-    return $res;
-
-}
-
 __PACKAGE__->register_method ({
     name => 'read_config', 
     path => 'config/{storage}', 
@@ -84,27 +81,25 @@
 	},
     },
     returns => {},
-});
-sub read_config {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    my $cfg = PVE::Config::read_file ("storagecfg");
+	my $cfg = PVE::Config::read_file ("storagecfg");
 
-    my $scfg = PVE::Storage::storage_config ($cfg, $param->{storage});
+	my $scfg = PVE::Storage::storage_config ($cfg, $param->{storage});
 
-    $scfg->{digest} = $cfg->{digest};
-    $scfg->{time} = time(); # fixme: remove
+	$scfg->{digest} = $cfg->{digest};
+	$scfg->{time} = time(); # fixme: remove
 
-   
-    my @cta;
-    foreach my $ct (keys %{$scfg->{content}}) {
-	push @cta, $ct if $scfg->{content}->{$ct};
-    } 
+	my @cta;
+	foreach my $ct (keys %{$scfg->{content}}) {
+	    push @cta, $ct if $scfg->{content}->{$ct};
+	} 
 
-    $scfg->{content} =  join(',', @cta);
+	$scfg->{content} =  join(',', @cta);
  
-    return $scfg;
-}
+	return $scfg;
+    }});
 
 __PACKAGE__->register_method ({
     name => 'update_config',
@@ -141,20 +136,19 @@
 	},
     },
     returns => { type => 'null' },
-});
-sub update_config {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    my $storeid = $param->{storage};
-    delete($param->{storage});
+	my $storeid = $param->{storage};
+	delete($param->{storage});
  
-    my $digest = $param->{digest};
-    delete($param->{digest});
+	my $digest = $param->{digest};
+	delete($param->{digest});
 
-    PVE::Storage::storage_set($storeid, $param, $digest);
+	PVE::Storage::storage_set($storeid, $param, $digest);
 
-    return undef;
-}
+	return undef;
+    }});
 
 __PACKAGE__->register_method ({
     name => 'list_storage_config', 
@@ -173,23 +167,22 @@
 	},
 	links => [ { rel => 'child', href => "{storage}" } ],
     },
-});
-sub list_storage_config {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    my $cfg = PVE::Config::read_file ("storagecfg");
+	my $cfg = PVE::Config::read_file ("storagecfg");
 
-    my @sids =  PVE::Storage::storage_ids ($cfg);
+	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;
-    }
+	my $res = [];
+	foreach my $storeid (@sids) {
+	    my $scfg = PVE::Storage::storage_config ($cfg, $storeid);
+	    $scfg->{storage} = $storeid;
+	    push @$res, $scfg;
+	}
 
-    return $res;
-}
+	return $res;
+    }});
 
 __PACKAGE__->register_method ({
     name => 'scan_index', 
@@ -208,18 +201,17 @@
 	},
 	links => [ { rel => 'child', href => "{method}" } ],
     },
-});
-sub scan_index {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    my $res = [ 
-	{ method => 'lvm' },
-	{ method => 'iscsi' },
-	{ method => 'nfs' },
-	];
+	my $res = [ 
+	    { method => 'lvm' },
+	    { method => 'iscsi' },
+	    { method => 'nfs' },
+	    ];
 
-    return $res;
-};
+	return $res;
+    }});
 
 __PACKAGE__->register_method ({
     name => 'scan_server', 
@@ -236,12 +228,11 @@
 	},
     },
     returns => {},
-});
-sub scan_server {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    return [];
-};
+	return [];
+    }});
 
 # fixme: move to somewhere else
 __PACKAGE__->register_method ({
@@ -261,36 +252,35 @@
 	},
 #	links => [ { rel => 'child', href => "{storage}" } ],
     },
-});
-sub cluster_index {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    my $nodes = [ 'node-0', 'node-1', 'node-2', 'node-3' ]; # fixme: use the real list
+	my $nodes = [ 'node-0', 'node-1', 'node-2', 'node-3' ]; # fixme: use the real list
 
-    my $cfg = PVE::Config::read_file ("storagecfg");
+	my $cfg = PVE::Config::read_file ("storagecfg");
 
-    my @sids =  PVE::Storage::storage_ids ($cfg);
+	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};
+	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
+	# $resp->{digest} = $cfg->{digest}; # fixme: how do we handle that
 
-    return $res;
-}
+	return $res;
+    }});
 
 __PACKAGE__->register_method ({
     name => 'list_nodes', 
@@ -313,24 +303,21 @@
 	    type => "object",
 	    properties => { node => { type => 'string' } },
 	},
-	links => [
-	    { rel => 'child', href => "{node}" }, 
-	    ],
+	links => [ { rel => 'child', href => "{node}" } ],
     },
-});
-sub list_nodes {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    # fixme: use the real list
-    my $nodes = [ 
-	{ node => 'node-0'},
-	{ node => 'node-1'},
-	{ node => 'node-2'},
-	{ node => 'node-3'},
-	];
+	# fixme: use the real list
+	my $nodes = [ 
+	    { node => 'node-0'},
+	    { node => 'node-1'},
+	    { node => 'node-2'},
+	    { node => 'node-3'},
+	    ];
 
-    return $nodes;
-}
+	return $nodes;
+    }});
 
 __PACKAGE__->register_method ({
     name => 'list_store_ids', 
@@ -352,32 +339,28 @@
 	    type => "object",
 	    properties => { storage => { type => 'string' } },
 	},
-	links => [
-	    { rel => 'child', href => "{storage}" }, 
-	    ],
+	links => [ { rel => 'child', href => "{storage}" } ],
     },
-});
-sub list_store_ids {
-   my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    my $cfg = PVE::Config::read_file ("storagecfg");
+	my $cfg = PVE::Config::read_file ("storagecfg");
 
-   my $node = $param->{node};
+	my $node = $param->{node};
 
-    # fixme: verify node (node exists)?
+	# fixme: verify node (node exists)?
 
-    my @sids =  PVE::Storage::storage_ids ($cfg);
+	my @sids =  PVE::Storage::storage_ids ($cfg);
 
-    my $res = [];
-    foreach my $storeid (@sids) {
-	# fixme: check if storeage exists on node ?
-	push @$res, { storage => $storeid };
-    }
+	my $res = [];
+	foreach my $storeid (@sids) {
+	    # fixme: check if storeage exists on node ?
+	    push @$res, { storage => $storeid };
+	}
 
-    return $res;
-}
+	return $res;
+    }});
 
-
 __PACKAGE__->register_method ({
     name => 'list_content', 
     protected => 1,
@@ -411,47 +394,44 @@
 		} 
 	    },
 	},
-	links => [
-	    { rel => 'child', href => "{volname}" }, 
-	    ],
+	links => [ { rel => 'child', href => "{volname}" } ],
     },
-});
-sub list_content {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    my $cts = $param->{content} ? [ $param->{content} ] : [ @ctypes ];
+	my $cts = $param->{content} ? [ $param->{content} ] : [ @ctypes ];
 
-    my $node = $param->{node};
-    my $storeid = $param->{storage};
+	my $node = $param->{node};
+	my $storeid = $param->{storage};
 
-    # fixme: verify $node
+	# fixme: verify $node
 
-    my $cfg = PVE::Config::read_file ("storagecfg");
+	my $cfg = PVE::Config::read_file ("storagecfg");
 
-    my $scfg = PVE::Storage::storage_config ($cfg, $storeid);
+	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');
-	}
+	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};
+	    next if !$data || !$data->{$storeid};
 
-	foreach my $item (@{$data->{$storeid}}) {
-	    push @$res, $item;
+	    foreach my $item (@{$data->{$storeid}}) {
+		push @$res, $item;
+	    }
 	}
-    }
 
-    return $res;    
-}
+	return $res;    
+    }});
 
 __PACKAGE__->register_method ({
     name => 'list_status', 
@@ -474,30 +454,26 @@
 	    type => "object",
 	    properties => { storage => { type => 'string' } },
 	},
-	links => [
-	    { rel => 'child', href => "{storage}" }, 
-	    ],
+	links => [ { rel => 'child', href => "{storage}" } ],
     },
-});
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-sub list_status {
-    my ($conn, $resp, $param) = @_;
+	my $cts = $param->{content} ? [ $param->{content} ] : [ @ctypes ];
+	
+	my $node = $param->{node};
 
-    my $cts = $param->{content} ? [ $param->{content} ] : [ @ctypes ];
+	# fixme: verify $node
 
-    my $node = $param->{node};
+	my $cfg = PVE::Config::read_file ("storagecfg");
 
-    # fixme: verify $node
+	# fixme: connect to correct node
 
-    my $cfg = PVE::Config::read_file ("storagecfg");
+	my $info = PVE::Storage::storage_info ($cfg);
 
-    # fixme: connect to correct node
+	return PVE::RESTHandler::hash_to_array($info, 'storage');
+    }});
 
-    my $info = PVE::Storage::storage_info ($cfg);
-
-    return PVE::RESTHandler::hash_to_array($info, 'storage');
-}
-
 __PACKAGE__->register_method ({
     name => 'get_status', 
     protected => 1,
@@ -517,25 +493,23 @@
 	},
     },
     returns => {},
-});
+    code =>  sub {
+	my ($conn, $resp, $param) = @_;
 
-sub get_status {
-    my ($conn, $resp, $param) = @_;
+	my $cts = $param->{content} ? [ $param->{content} ] : [ @ctypes ];
 
-    my $cts = $param->{content} ? [ $param->{content} ] : [ @ctypes ];
+	my $node = $param->{node};
+	my $storeid = $param->{storage};
 
-    my $node = $param->{node};
-    my $storeid = $param->{storage};
+	# fixme: verify $node
 
-    # fixme: verify $node
+	my $cfg = PVE::Config::read_file ("storagecfg");
 
-    my $cfg = PVE::Config::read_file ("storagecfg");
+	# fixme: connect to correct node
 
-    # fixme: connect to correct node
+	my $info = PVE::Storage::storage_info ($cfg);
+	
+	return $info->{$storeid};
+    }});
 
-    my $info = PVE::Storage::storage_info ($cfg);
-
-    return $info->{$storeid};
-}
-
 1;

Modified: pve-manager/pve2/lib/PVE/API2/User.pm
===================================================================
--- pve-manager/pve2/lib/PVE/API2/User.pm	2010-07-19 11:27:51 UTC (rev 4915)
+++ pve-manager/pve2/lib/PVE/API2/User.pm	2010-07-19 13:31:55 UTC (rev 4916)
@@ -32,22 +32,21 @@
 	},
 	links => [ { rel => 'child', href => "{id}" } ],
     },
-}); 
-sub index {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
     
-    my $res = [];
+	my $res = [];
 
-    my $usercfg = PVE::Config::read_file("usercfg");
+	my $usercfg = PVE::Config::read_file("usercfg");
  
-    foreach my $user (keys %{$usercfg->{users}}) {
-	next if $user eq 'root';
+	foreach my $user (keys %{$usercfg->{users}}) {
+	    next if $user eq 'root';
 
-	push @$res, { id => $user };
-    }
+	    push @$res, { id => $user };
+	}
 
-    return $res;
-}
+	return $res;
+    }});
 
 __PACKAGE__->register_method ({
     name => 'create_user', 
@@ -64,17 +63,16 @@
 	},
     },
     returns => { type => 'null' },
-}); 
-sub create_user {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    $param->{create} = 1;
-    PVE::AccessControl::modify_user($param->{userid}, $param);
+	$param->{create} = 1;
+	PVE::AccessControl::modify_user($param->{userid}, $param);
 
-    # fixme: maybe it is better to return the user data ?
+	# fixme: maybe it is better to return the user data ?
 
-    return undef;
-}
+	return undef;
+    }});
 
 __PACKAGE__->register_method ({
     name => 'get_user', 
@@ -88,17 +86,16 @@
 	},
     },
     returns => {},
-}); 
-sub get_user {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    my $usercfg = PVE::Config::read_file("usercfg");
+	my $usercfg = PVE::Config::read_file("usercfg");
  
-    my $data = $usercfg->{users}->{$param->{userid}};
-    die "no such user\n" if !$data;
+	my $data = $usercfg->{users}->{$param->{userid}};
+	die "no such user\n" if !$data;
 
-    return $data;
-}
+	return $data;
+    }});
 
 __PACKAGE__->register_method ({
     name => 'update_user', 
@@ -124,16 +121,15 @@
 	},
     },
     returns => { type => 'null' },
-}); 
-sub update_user {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    PVE::AccessControl::modify_user($param->{userid}, $param);
+	PVE::AccessControl::modify_user($param->{userid}, $param);
 
-    # fixme: maybe it is better to return the user data ?
+	# fixme: maybe it is better to return the user data ?
 
-    return undef;
-}
+	return undef;
+    }});
 
 __PACKAGE__->register_method ({
     name => 'delete_user', 
@@ -148,13 +144,12 @@
 	}
     },
     returns => { type => 'null' },
-}); 
-sub delete_user {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    PVE::AccessControl::delete_user($param->{userid});  
+	PVE::AccessControl::delete_user($param->{userid});  
+	
+	return undef;
+    }});
 
-    return undef;
-}
-
 1;

Modified: pve-manager/pve2/lib/PVE/API2/VM.pm
===================================================================
--- pve-manager/pve2/lib/PVE/API2/VM.pm	2010-07-19 11:27:51 UTC (rev 4915)
+++ pve-manager/pve2/lib/PVE/API2/VM.pm	2010-07-19 13:31:55 UTC (rev 4916)
@@ -26,38 +26,34 @@
 	    type => "object",
 	    properties => {},
 	},
-	links => [
-	    { rel => 'child', href => "{id}" }, 
-	    ],
+	links => [ { rel => 'child', href => "{id}" } ],
     },
-});
-sub index {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
 
-    my $ctime = int(time()/3);
-    $ctime = 0;
+	my $ctime = int(time()/3);
+	$ctime = 0;
 
-    my $result = [];
+	my $result = [];
 
-    for (my $i = 0; $i < 4; $i++) {
-	for (my $j = 0; $j < 1; $j++) {
-	    my $vmid = $i*100+$j;
-	    my $cpu = (($ctime + $vmid) % 100)/100;
-	    #  storage => "local (node-$i)",
-	    push @$result, { id => $vmid, name => "VM $vmid", node => "node-$i" , cpu => $cpu, maxcpu => 1, mem => 1024*1024*1024*6, maxmem => 1024*1024*1024*24, disk => 1024*1024*1024*1024*6, maxdisk => 1024*1024*1024*1024*32, uptime => 2*3600 };
+	for (my $i = 0; $i < 4; $i++) {
+	    for (my $j = 0; $j < 1; $j++) {
+		my $vmid = $i*100+$j;
+		my $cpu = (($ctime + $vmid) % 100)/100;
+		#  storage => "local (node-$i)",
+		push @$result, { id => $vmid, name => "VM $vmid", node => "node-$i" , cpu => $cpu, maxcpu => 1, mem => 1024*1024*1024*6, maxmem => 1024*1024*1024*24, disk => 1024*1024*1024*1024*6, maxdisk => 1024*1024*1024*1024*32, uptime => 2*3600 };
+	    }
 	}
-    }
 
- 
-    my $count = ($ctime % 10);
+	my $count = ($ctime % 10);
 
-    for (my $i = 0; $i < $count; $i++) {
-	my $vmid = 50+$i;
-	my $cpu = (($ctime + $vmid) % 100)/100;
-	push @$result, { id => $vmid, name => "VM $vmid", node => "node-$i" , storage => "store-$i", cpu => $cpu, maxcpu => 2};
-    }
+	for (my $i = 0; $i < $count; $i++) {
+	    my $vmid = 50+$i;
+	    my $cpu = (($ctime + $vmid) % 100)/100;
+	    push @$result, { id => $vmid, name => "VM $vmid", node => "node-$i" , storage => "store-$i", cpu => $cpu, maxcpu => 2};
+	}
     
-    return $result;
-}
+	return $result;
+    }});
 
 1;

Modified: pve-manager/pve2/lib/PVE/API2.pm
===================================================================
--- pve-manager/pve2/lib/PVE/API2.pm	2010-07-19 11:27:51 UTC (rev 4915)
+++ pve-manager/pve2/lib/PVE/API2.pm	2010-07-19 13:31:55 UTC (rev 4916)
@@ -53,23 +53,22 @@
 	},
 	links => [ { rel => 'child', href => "{subdir}" } ],
     },
-}); 
-sub index {
-    my ($conn, $resp, $param) = @_;
+    code => sub {
+	my ($conn, $resp, $param) = @_;
     
-    my $res = [];
+	my $res = [];
 
-    my $ma = PVE::API2->method_attributes();
+	my $ma = PVE::API2->method_attributes();
 
-    foreach my $info (@$ma) {
-	next if !$info->{subclass};
+	foreach my $info (@$ma) {
+	    next if !$info->{subclass};
 
-	my $subpath = $info->{match_re}->[0];
+	    my $subpath = $info->{match_re}->[0];
 
-	push @$res, { subdir => $subpath };
-    }
+	    push @$res, { subdir => $subpath };
+	}
 
-    return $res;
-}
+	return $res;
+    }});
 
 1;

Modified: pve-manager/pve2/lib/PVE/JSONSchema.pm
===================================================================
--- pve-manager/pve2/lib/PVE/JSONSchema.pm	2010-07-19 11:27:51 UTC (rev 4915)
+++ pve-manager/pve2/lib/PVE/JSONSchema.pm	2010-07-19 13:31:55 UTC (rev 4916)
@@ -3,7 +3,7 @@
 use warnings;
 use strict;
 use Storable; # for dclone
-use Devel::Cycle;
+use Devel::Cycle -quiet; # fixme: remove?
 use Data::Dumper; # fixme: remove
 
 # Note: This class implements something similar to JSON schema, but it is not 100% complete. 
@@ -95,6 +95,12 @@
 		return undef;
 	    }
 	    return 1;
+	} elsif ($type eq 'coderef') {
+	    if (!$vt || $vt ne 'CODE') {
+		add_error($errors, $path, "type check ('$type') failed");
+		return undef;
+	    }
+	    return 1;
 	} else {
 	    if ($vt) {
 		add_error($errors, $path, "type check ('$type') failed - got $vt");
@@ -319,7 +325,7 @@
     return {valid => !scalar(%$errors), errors => $errors};
 }
 
-my $schema_valid_types = ["string", "object", "array", "boolean", "number", "integer", "null", "any"];
+my $schema_valid_types = ["string", "object", "coderef", "array", "boolean", "number", "integer", "null", "any"];
 my $default_schema_noref = {
     description => "This is the JSON Schema for JSON Schemas.",
     type => [ "object" ],
@@ -483,6 +489,7 @@
 		properties => {
                     name => {},
                     description => {},
+                    code => {},
  	            method => {},
                     parameters => {},
                     path => {},
@@ -516,6 +523,11 @@
 	    description => "JSON Schema for return value.",
 	    optional => 1,
 	},
+        code => {
+	    type => 'coderef',
+	    description => "method implementaion (code reference)",
+	    optional => 1,
+        },
 	subclass => {
 	    type => 'string',
 	    description => "Delegate call to this class (perl class string).",

Modified: pve-manager/pve2/lib/PVE/RESTHandler.pm
===================================================================
--- pve-manager/pve2/lib/PVE/RESTHandler.pm	2010-07-19 11:27:51 UTC (rev 4915)
+++ pve-manager/pve2/lib/PVE/RESTHandler.pm	2010-07-19 13:31:55 UTC (rev 4916)
@@ -5,10 +5,13 @@
 use PVE::SafeSyslog;
 use PVE::JSONSchema;
 use Data::Dumper; # fixme: remove
-use HTTP::Status qw(:constants :is);
+use HTTP::Status qw(:constants :is status_message);
 
 my $method_registry = {};
+my $method_by_name = {};
 
+our $AUTOLOAD;  # it's a package global
+
 sub register_method {
     my ($self, $info) = @_;
 
@@ -32,8 +35,56 @@
     $info->{match_re} = $match_re;
     $info->{match_name} = $match_name;
 
+    $method_by_name->{$self} = {} if !defined($method_by_name->{$self});
+
+    if ($info->{name}) {
+	die "method '${self}::$info->{name}' already defined\n"
+	    if defined($method_by_name->{$self}->{$info->{name}});
+
+	$method_by_name->{$self}->{$info->{name}} = $info;
+    }
+
     push @{$method_registry->{$self}}, $info;
+}
 
+sub AUTOLOAD {
+    my $self = shift;
+
+
+    my $method = $AUTOLOAD;
+
+    $method =~ s/.*:://;
+   
+    my $info = $method_by_name->{$self}->{$method};
+    
+    die "no such method '${self}::$method'\n" if !$info;
+
+    # fixme: how do we handle this here?
+    # fixme: language ?
+    my $conn = {
+#	abs_uri => $abs_uri,
+#	rel_uri => $rel_uri,
+#	user => $username,
+	params => shift || {},
+    };
+
+    my $res = {};
+    $res->{status} = $self->handle($info, $conn, $res);
+ 
+    my $status = $res->{status};
+    if (!is_success($status)) {
+	my $msg = $res->{message} || status_message($status);
+	chomp $msg;
+	$msg .= "\n";
+	if ($res->{errors}) {
+	    foreach my $e (keys %{$res->{errors}}) {
+		$msg .= "$e: $res->{errors}->{$e}\n";
+	    }
+	}
+	die $msg;
+    }
+
+    return $res->{data};
 }
 
 sub method_attributes {
@@ -123,7 +174,7 @@
 sub handle {
     my ($self, $info, $conn, $resp) = @_;
 
-    my $func = $info->{name} ? $self->can($info->{name}) : undef;
+    my $func = $info->{code};
 
     if (!($info->{name} && $func)) {
 	$resp->{message} = "Method lookup failed ('$info->{name}')";



More information about the pve-devel mailing list