[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