[pve-devel] [PATCH qemu-server 1/1] api2: qemu: add proxyto_callback to find node if not defined

Alexandre Derumier aderumier at odiso.com
Thu Jun 1 00:28:34 CEST 2023


Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/API2/Qemu.pm | 157 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 109 insertions(+), 48 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 587bb22..52daf5a 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -59,6 +59,19 @@ use base qw(PVE::RESTHandler);
 
 my $opt_force_description = "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.";
 
+my $find_vm_node = sub {
+	my ($rpcenv, $proxyto, $param) = @_;
+	return $param->{node} if $param->{node};
+	# proxy to the node where the guest resides
+	my $vmid = $param->{vmid};
+	return 'localhost' if !$vmid;
+
+	my $vms = PVE::Cluster::get_vmlist();
+
+	return 'localhost' if !$vms->{ids}->{$vmid};
+	return $vms->{ids}->{$vmid}->{node};
+};
+
 my $resolve_cdrom_alias = sub {
     my $param = shift;
 
@@ -659,11 +672,12 @@ __PACKAGE__->register_method({
 	user => 'all',
     },
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     protected => 1, # qemu pid files are only readable by root
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    full => {
 		type => 'boolean',
 		optional => 1,
@@ -684,8 +698,20 @@ __PACKAGE__->register_method({
 
 	my $rpcenv = PVE::RPCEnvironment::get();
 	my $authuser = $rpcenv->get_user();
+	my $vmstatus = undef;
 
-	my $vmstatus = PVE::QemuServer::vmstatus(undef, $param->{full});
+	if (!$param->{node}) {
+	    my $vmlist = PVE::Cluster::get_vmlist()->{ids};
+	    my $rrd = PVE::Cluster::rrd_dump();
+	    for my $vmid (sort keys %$vmlist) {
+		my $data = $vmlist->{$vmid};
+		next if $data->{type} ne 'qemu';
+		my $entry = PVE::API2Tools::extract_vm_stats($vmid, $data, $rrd);
+		$vmstatus->{$vmid} = $entry;
+	    }
+	} else {
+	    $vmstatus = PVE::QemuServer::vmstatus(undef, $param->{full});
+	}
 
 	my $res = [];
 	foreach my $vmid (keys %$vmstatus) {
@@ -733,11 +759,12 @@ __PACKAGE__->register_method({
     },
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     parameters => {
 	additionalProperties => 0,
 	properties => PVE::QemuServer::json_config_properties(
 	    {
-		node => get_standard_option('pve-node'),
+		node => get_standard_option('pve-node', { optional => 1}),
 		vmid => get_standard_option('pve-vmid', { completion => \&PVE::Cluster::complete_next_vmid }),
 		archive => {
 		    description => "The backup archive. Either the file system path to a .tar or .vma file (use '-' to pipe data from stdin) or a proxmox storage backup volume identifier.",
@@ -878,7 +905,6 @@ __PACKAGE__->register_method({
 
 	    &$check_vm_create_serial_perm($rpcenv, $authuser, $vmid, $pool, $param);
 	    &$check_vm_create_usb_perm($rpcenv, $authuser, $vmid, $pool, $param);
-
 	    &$check_cpu_model_access($rpcenv, $authuser, $param);
 
 	    $check_drive_param->($param, $storecfg);
@@ -1053,6 +1079,7 @@ __PACKAGE__->register_method({
     path => '{vmid}',
     method => 'GET',
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Directory index",
     permissions => {
 	user => 'all',
@@ -1060,7 +1087,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	},
     },
@@ -1125,7 +1152,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	    timeframe => {
 		description => "Specify the time frame you are interested in.",
@@ -1171,7 +1198,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	    timeframe => {
 		description => "Specify the time frame you are interested in.",
@@ -1200,12 +1227,12 @@ __PACKAGE__->register_method({
 	    "pve2-vm/$param->{vmid}", $param->{timeframe}, $param->{cf});
     }});
 
-
 __PACKAGE__->register_method({
     name => 'vm_config',
     path => '{vmid}/config',
     method => 'GET',
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Get the virtual machine configuration with pending configuration " .
 	"changes applied. Set the 'current' parameter to get the current configuration instead.",
     permissions => {
@@ -1214,7 +1241,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	    current => {
 		description => "Get current values (instead of pending values).",
@@ -1265,6 +1292,7 @@ __PACKAGE__->register_method({
     path => '{vmid}/pending',
     method => 'GET',
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Get the virtual machine configuration with both current and pending values.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
@@ -1272,7 +1300,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	},
     },
@@ -1324,6 +1352,7 @@ __PACKAGE__->register_method({
     path => '{vmid}/cloudinit',
     method => 'GET',
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Get the cloudinit configuration with both current and pending values.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
@@ -1331,7 +1360,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	},
     },
@@ -1396,6 +1425,7 @@ __PACKAGE__->register_method({
     method => 'PUT',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Regenerate and change cloudinit config drive.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', 'VM.Config.Cloudinit'],
@@ -1403,7 +1433,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	},
     },
@@ -1873,6 +1903,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Set virtual machine options (asynchrounous API).",
     permissions => {
 	check => ['perm', '/vms/{vmid}', $vm_config_perm_list, any => 1],
@@ -1881,7 +1912,7 @@ __PACKAGE__->register_method({
 	additionalProperties => 0,
 	properties => PVE::QemuServer::json_config_properties(
 	    {
-		node => get_standard_option('pve-node'),
+		node => get_standard_option('pve-node', { optional => 1}),
 		vmid => get_standard_option('pve-vmid'),
 		skiplock => get_standard_option('skiplock'),
 		delete => {
@@ -1930,6 +1961,7 @@ __PACKAGE__->register_method({
     method => 'PUT',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Set virtual machine options (synchrounous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', $vm_config_perm_list, any => 1],
@@ -1938,7 +1970,7 @@ __PACKAGE__->register_method({
 	additionalProperties => 0,
 	properties => PVE::QemuServer::json_config_properties(
 	    {
-		node => get_standard_option('pve-node'),
+		node => get_standard_option('pve-node', { optional => 1}),
 		vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 		skiplock => get_standard_option('skiplock'),
 		delete => {
@@ -1981,6 +2013,7 @@ __PACKAGE__->register_method({
     method => 'DELETE',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Destroy the VM and  all used/owned volumes. Removes any VM specific permissions"
 	." and firewall rules",
     permissions => {
@@ -1989,7 +2022,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid_stopped }),
 	    skiplock => get_standard_option('skiplock'),
 	    purge => {
@@ -2089,6 +2122,7 @@ __PACKAGE__->register_method({
     method => 'PUT',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Unlink/delete disk images.",
     permissions => {
 	check => [ 'perm', '/vms/{vmid}', ['VM.Config.Disk']],
@@ -2096,7 +2130,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	    idlist => {
 		type => 'string', format => 'pve-configid-list',
@@ -2151,7 +2185,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	    websocket => {
 		optional => 1,
@@ -2313,7 +2347,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	    serial=> {
 		optional => 1,
@@ -2409,7 +2443,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	    vncticket => {
 		description => "Ticket from previous call to vncproxy.",
@@ -2461,6 +2495,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.Console' ]],
     },
@@ -2468,7 +2503,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	    proxy => get_standard_option('spice-proxy', { optional => 1 }),
 	},
@@ -2505,6 +2540,7 @@ __PACKAGE__->register_method({
     path => '{vmid}/status',
     method => 'GET',
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Directory index",
     permissions => {
 	user => 'all',
@@ -2512,7 +2548,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	},
     },
@@ -2550,6 +2586,7 @@ __PACKAGE__->register_method({
     path => '{vmid}/status/current',
     method => 'GET',
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     protected => 1, # qemu pid files are only readable by root
     description => "Get virtual machine status.",
     permissions => {
@@ -2558,7 +2595,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	},
     },
@@ -2610,6 +2647,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Start virtual machine.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
@@ -2617,7 +2655,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid',
 					{ completion => \&PVE::QemuServer::complete_vmid_stopped }),
 	    skiplock => get_standard_option('skiplock'),
@@ -2775,6 +2813,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Stop virtual machine. The qemu process will exit immediately. This" .
 	"is akin to pulling the power plug of a running computer and may damage the VM data",
     permissions => {
@@ -2783,7 +2822,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid',
 					{ completion => \&PVE::QemuServer::complete_vmid_running }),
 	    skiplock => get_standard_option('skiplock'),
@@ -2864,6 +2903,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Reset virtual machine.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
@@ -2871,7 +2911,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid',
 					{ completion => \&PVE::QemuServer::complete_vmid_running }),
 	    skiplock => get_standard_option('skiplock'),
@@ -2914,6 +2954,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Shutdown virtual machine. This is similar to pressing the power button on a physical machine." .
 	"This will send an ACPI event for the guest OS, which should then proceed to a clean shutdown.",
     permissions => {
@@ -2922,7 +2963,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid',
 					{ completion => \&PVE::QemuServer::complete_vmid_running }),
 	    skiplock => get_standard_option('skiplock'),
@@ -3022,6 +3063,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Reboot the VM by shutting it down, and starting it again. Applies pending changes.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
@@ -3029,7 +3071,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid',
 					{ completion => \&PVE::QemuServer::complete_vmid_running }),
 	    timeout => {
@@ -3073,6 +3115,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Suspend virtual machine.",
     permissions => {
 	description => "You need 'VM.PowerMgmt' on /vms/{vmid}, and if you have set 'todisk',".
@@ -3083,7 +3126,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid',
 					{ completion => \&PVE::QemuServer::complete_vmid_running }),
 	    skiplock => get_standard_option('skiplock'),
@@ -3167,6 +3210,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Resume virtual machine.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
@@ -3174,7 +3218,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid',
 					{ completion => \&PVE::QemuServer::complete_vmid_running }),
 	    skiplock => get_standard_option('skiplock'),
@@ -3241,6 +3285,7 @@ __PACKAGE__->register_method({
     method => 'PUT',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Send key event to virtual machine.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.Console' ]],
@@ -3248,7 +3293,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid',
 					{ completion => \&PVE::QemuServer::complete_vmid_running }),
 	    skiplock => get_standard_option('skiplock'),
@@ -3284,6 +3329,7 @@ __PACKAGE__->register_method({
     path => '{vmid}/feature',
     method => 'GET',
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     protected => 1,
     description => "Check if feature for virtual machine is available.",
     permissions => {
@@ -3292,7 +3338,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
             feature => {
                 description => "Feature to check.",
@@ -3351,6 +3397,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Create a copy of virtual machine/template.",
     permissions => {
 	description => "You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions " .
@@ -3368,7 +3415,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	    newid => get_standard_option('pve-vmid', {
 		completion => \&PVE::Cluster::complete_next_vmid,
@@ -3708,6 +3755,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Move volume to different storage or to a different VM.",
     permissions => {
 	description => "You need 'VM.Config.Disk' permissions on /vms/{vmid}, " .
@@ -3718,7 +3766,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	    'target-vmid' => get_standard_option('pve-vmid', {
 		completion => \&PVE::QemuServer::complete_vmid,
@@ -4170,6 +4218,7 @@ __PACKAGE__->register_method({
     method => 'GET',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Get preconditions for migration.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.Migrate' ]],
@@ -4177,7 +4226,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	    target => get_standard_option('pve-node', {
 		description => "Target node.",
@@ -4271,6 +4320,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Migrate virtual machine. Creates a new migration task.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.Migrate' ]],
@@ -4278,7 +4328,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	    target => get_standard_option('pve-node', {
 		description => "Target node.",
@@ -4436,6 +4486,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Migrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature!",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.Migrate' ]],
@@ -4443,7 +4494,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	    'target-vmid' => get_standard_option('pve-vmid', { optional => 1 }),
 	    'target-endpoint' => get_standard_option('proxmox-remote', {
@@ -4601,6 +4652,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Execute QEMU monitor commands.",
     permissions => {
 	description => "Sys.Modify is required for (sub)commands which are not read-only ('info *' and 'help')",
@@ -4609,7 +4661,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	    command => {
 		type => 'string',
@@ -4652,6 +4704,7 @@ __PACKAGE__->register_method({
     method => 'PUT',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Extend volume size.",
     permissions => {
         check => ['perm', '/vms/{vmid}', [ 'VM.Config.Disk' ]],
@@ -4659,7 +4712,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	    skiplock => get_standard_option('skiplock'),
 	    disk => {
@@ -4780,12 +4833,13 @@ __PACKAGE__->register_method({
 	check => ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
     },
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     protected => 1, # qemu pid files are only readable by root
     parameters => {
 	additionalProperties => 0,
 	properties => {
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	},
     },
     returns => {
@@ -4864,6 +4918,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Snapshot a VM.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.Snapshot' ]],
@@ -4871,7 +4926,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	    snapname => get_standard_option('pve-snapshot-name'),
 	    vmstate => {
@@ -4930,7 +4985,7 @@ __PACKAGE__->register_method({
 	additionalProperties => 0,
 	properties => {
 	    vmid => get_standard_option('pve-vmid'),
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    snapname => get_standard_option('pve-snapshot-name'),
 	},
     },
@@ -4959,6 +5014,7 @@ __PACKAGE__->register_method({
     method => 'PUT',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Update snapshot metadata.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.Snapshot' ]],
@@ -4966,7 +5022,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	    snapname => get_standard_option('pve-snapshot-name'),
 	    description => {
@@ -5015,6 +5071,7 @@ __PACKAGE__->register_method({
     path => '{vmid}/snapshot/{snapname}/config',
     method => 'GET',
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Get snapshot configuration",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.Snapshot', 'VM.Snapshot.Rollback', 'VM.Audit' ], any => 1],
@@ -5022,7 +5079,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	    snapname => get_standard_option('pve-snapshot-name'),
 	},
@@ -5054,6 +5111,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Rollback VM state to specified snapshot.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.Snapshot', 'VM.Snapshot.Rollback' ], any => 1],
@@ -5061,7 +5119,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	    snapname => get_standard_option('pve-snapshot-name'),
 	    start => {
@@ -5113,6 +5171,7 @@ __PACKAGE__->register_method({
     method => 'DELETE',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Delete a VM snapshot.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.Snapshot' ]],
@@ -5120,7 +5179,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	    snapname => get_standard_option('pve-snapshot-name'),
 	    force => {
@@ -5175,6 +5234,7 @@ __PACKAGE__->register_method({
     method => 'POST',
     protected => 1,
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Create a Template.",
     permissions => {
 	description => "You need 'VM.Allocate' permissions on /vms/{vmid}",
@@ -5183,7 +5243,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid_stopped }),
 	    disk => {
 		optional => 1,
@@ -5249,6 +5309,7 @@ __PACKAGE__->register_method({
     path => '{vmid}/cloudinit/dump',
     method => 'GET',
     proxyto => 'node',
+    proxyto_callback => \&$find_vm_node,
     description => "Get automatically generated cloudinit config.",
     permissions => {
 	check => ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
@@ -5256,7 +5317,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::QemuServer::complete_vmid }),
 	    type => {
 		description => 'Config type.',
@@ -5294,7 +5355,7 @@ __PACKAGE__->register_method({
     parameters => {
 	additionalProperties => 0,
 	properties => {
-	    node => get_standard_option('pve-node'),
+	    node => get_standard_option('pve-node', { optional => 1}),
 	    vmid => get_standard_option('pve-vmid'),
 	    storages => {
 		type => 'string',
-- 
2.30.2





More information about the pve-devel mailing list