api: add reboot api call

this creates a reboot request file (inspired by pve-container)
and relies on the 'qm cleanup' call by the qmeventd to detect
and restart the vm afterwards

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
Dominik Csapak 2019-09-11 14:07:45 +02:00 committed by Thomas Lamprecht
parent 575d19dab5
commit 165411f0c2
3 changed files with 77 additions and 0 deletions

View File

@ -1910,6 +1910,7 @@ __PACKAGE__->register_method({
{ subdir => 'reset' }, { subdir => 'reset' },
{ subdir => 'shutdown' }, { subdir => 'shutdown' },
{ subdir => 'suspend' }, { subdir => 'suspend' },
{ subdir => 'reboot' },
]; ];
return $res; return $res;
@ -2333,6 +2334,64 @@ __PACKAGE__->register_method({
} }
}}); }});
__PACKAGE__->register_method({
name => 'vm_reboot',
path => '{vmid}/status/reboot',
method => 'POST',
protected => 1,
proxyto => 'node',
description => "Reboot the VM by shutting it down, and starting it again. Applies pending changes.",
permissions => {
check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
},
parameters => {
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
vmid => get_standard_option('pve-vmid',
{ completion => \&PVE::QemuServer::complete_vmid_running }),
timeout => {
description => "Wait maximal timeout seconds for the shutdown.",
type => 'integer',
minimum => 0,
optional => 1,
},
},
},
returns => {
type => 'string',
},
code => sub {
my ($param) = @_;
my $rpcenv = PVE::RPCEnvironment::get();
my $authuser = $rpcenv->get_user();
my $node = extract_param($param, 'node');
my $vmid = extract_param($param, 'vmid');
my $qmpstatus = eval {
PVE::QemuServer::vm_qmp_command($vmid, { execute => "query-status" }, 0);
};
my $err = $@ if $@;
if (!$err && $qmpstatus->{status} eq "paused") {
die "VM is paused - cannot shutdown\n";
}
die "VM $vmid not running\n" if !PVE::QemuServer::check_running($vmid);
my $realcmd = sub {
my $upid = shift;
syslog('info', "requesting reboot of VM $vmid: $upid\n");
PVE::QemuServer::vm_reboot($vmid, $param->{timeout});
return;
};
return $rpcenv->fork_worker('qmreboot', $vmid, $authuser, $realcmd);
}});
__PACKAGE__->register_method({ __PACKAGE__->register_method({
name => 'vm_suspend', name => 'vm_suspend',
path => '{vmid}/status/suspend', path => '{vmid}/status/suspend',

View File

@ -998,6 +998,8 @@ our $cmddef = {
shutdown => [ "PVE::API2::Qemu", 'vm_shutdown', ['vmid'], { node => $nodename }, $upid_exit ], shutdown => [ "PVE::API2::Qemu", 'vm_shutdown', ['vmid'], { node => $nodename }, $upid_exit ],
reboot => [ "PVE::API2::Qemu", 'vm_reboot', ['vmid'], { node => $nodename }, $upid_exit ],
suspend => [ "PVE::API2::Qemu", 'vm_suspend', ['vmid'], { node => $nodename }, $upid_exit ], suspend => [ "PVE::API2::Qemu", 'vm_suspend', ['vmid'], { node => $nodename }, $upid_exit ],
resume => [ "PVE::API2::Qemu", 'vm_resume', ['vmid'], { node => $nodename }, $upid_exit ], resume => [ "PVE::API2::Qemu", 'vm_resume', ['vmid'], { node => $nodename }, $upid_exit ],

View File

@ -5870,6 +5870,22 @@ sub vm_stop {
}); });
} }
sub vm_reboot {
my ($vmid, $timeout) = @_;
PVE::QemuConfig->lock_config($vmid, sub {
# only reboot if running, as qmeventd starts it again on a stop event
return if !check_running($vmid);
create_reboot_request($vmid);
my $storecfg = PVE::Storage::config();
_do_vm_stop($storecfg, $vmid, undef, undef, $timeout, 1);
});
}
sub vm_suspend { sub vm_suspend {
my ($vmid, $skiplock, $includestate, $statestorage) = @_; my ($vmid, $skiplock, $includestate, $statestorage) = @_;