[pve-devel] [PATCH] Add CT suspend/resume to PVE API
Daniel Hunsaker
danhunsaker at gmail.com
Mon Mar 3 22:19:12 CET 2014
Rebased on latest public master.
- Daniel Hunsaker
Owner / Developer
Lei's Genesis Experiment: Code For The Future!
On Mon, Mar 3, 2014 at 2:16 PM, Daniel Hunsaker <danhunsaker at gmail.com>wrote:
> As discussed in a previous thread, following is a patch to support
> container
> suspend (via vzctl chkpnt) and resume (via vzctl restore).
>
> - Added /nodes/{node}/openvz/{vmid}/status/suspend to API
> - Added /nodes/{node}/openvz/{vmid}/status/resume to API
> - Adapted vm_suspend/vm_resume from PVE/QemuServer.pm into PVE/OpenVZ.pm
> - Removed locking since vzctl already does this for us, and the locks
> conflict with each other (container already locked)
> - Changed monitor commands to run_command(vzctl) calls
> - Refuse to suspend if CT is offline
> - Refuse to resume if CT is online
> - vzctl does these checks as well, but it doesn't really hurt to have
> them
>
> This was great, but there were artifacts in the web UI - specifically, the
> task descriptions were unformatted. So, I moved over to the web UI code...
>
> - Added descriptions for vzsuspend and vzresume tasks in web UI
>
> And while I was there anyway...
>
> - Added suspend/resume options to CmdMenu for both OpenVZ and QEMU guests
> - Confirm suspend before proceeding
> - No confirm on resume, since it's a startup action
> - Fixed OpenVZ CmdMenu shutdown and stop confirmation prompts to refer to
> CTs
>
> I considered adding these options to the toolbar, but there are enough
> options
> there already that it can get crowded quick in smaller browser windows
> (such
> as the ones I tend to use, for screen real estate purposes), so I opted
> against that.
>
> Signed-off-by: Daniel Hunsaker <danhunsaker at gmail.com>
> ---
> PVE/API2/OpenVZ.pm | 97
> +++++++++++++++++++++++++++++++++++++++++++
> PVE/OpenVZ.pm | 26 +++++++++++-
> www/manager/Utils.js | 2 +
> www/manager/openvz/CmdMenu.js | 25 ++++++++++-
> www/manager/qemu/CmdMenu.js | 21 ++++++++++
> 5 files changed, 168 insertions(+), 3 deletions(-)
>
> diff --git a/PVE/API2/OpenVZ.pm b/PVE/API2/OpenVZ.pm
> index d9993fd..31f1b73 100644
> --- a/PVE/API2/OpenVZ.pm
> +++ b/PVE/API2/OpenVZ.pm
> @@ -1391,6 +1391,103 @@ __PACKAGE__->register_method({
> }});
>
> __PACKAGE__->register_method({
> + name => 'vm_suspend',
> + path => '{vmid}/status/suspend',
> + method => 'POST',
> + protected => 1,
> + proxyto => 'node',
> + description => "Suspend the container.",
> + permissions => {
> + check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
> + },
> + parameters => {
> + additionalProperties => 0,
> + properties => {
> + node => get_standard_option('pve-node'),
> + vmid => get_standard_option('pve-vmid'),
> + },
> + },
> + 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');
> +
> + die "CT $vmid not running\n" if
> !PVE::OpenVZ::check_running($vmid);
> +
> + my $realcmd = sub {
> + my $upid = shift;
> +
> + syslog('info', "suspend CT $vmid: $upid\n");
> +
> + PVE::OpenVZ::vm_suspend($vmid);
> +
> + return;
> + };
> +
> + my $upid = $rpcenv->fork_worker('vzsuspend', $vmid,
> $authuser, $realcmd);
> +
> + return $upid;
> + }});
> +
> +__PACKAGE__->register_method({
> + name => 'vm_resume',
> + path => '{vmid}/status/resume',
> + method => 'POST',
> + protected => 1,
> + proxyto => 'node',
> + description => "Resume the container.",
> + permissions => {
> + check => ['perm', '/vms/{vmid}', [ 'VM.PowerMgmt' ]],
> + },
> + parameters => {
> + additionalProperties => 0,
> + properties => {
> + node => get_standard_option('pve-node'),
> + vmid => get_standard_option('pve-vmid'),
> + },
> + },
> + 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');
> +
> + die "CT $vmid already running\n" if
> PVE::OpenVZ::check_running($vmid);
> +
> + my $realcmd = sub {
> + my $upid = shift;
> +
> + syslog('info', "resume CT $vmid: $upid\n");
> +
> + PVE::OpenVZ::vm_resume($vmid);
> +
> + return;
> + };
> +
> + my $upid = $rpcenv->fork_worker('vzresume', $vmid,
> $authuser, $realcmd);
> +
> + return $upid;
> + }});
> +
> +
> +__PACKAGE__->register_method({
> name => 'migrate_vm',
> path => '{vmid}/migrate',
> method => 'POST',
> diff --git a/PVE/OpenVZ.pm b/PVE/OpenVZ.pm
> index 2b92979..eee7ca3 100644
> --- a/PVE/OpenVZ.pm
> +++ b/PVE/OpenVZ.pm
> @@ -6,7 +6,7 @@ use File::stat qw();
> use POSIX qw (LONG_MAX);
> use IO::Dir;
> use IO::File;
> -use PVE::Tools qw(extract_param $IPV6RE $IPV4RE);
> +use PVE::Tools qw(run_command extract_param $IPV6RE $IPV4RE);
> use PVE::ProcFSTools;
> use PVE::Cluster qw(cfs_register_file cfs_read_file);
> use PVE::SafeSyslog;
> @@ -1205,6 +1205,30 @@ sub lock_container {
> return $res;
> }
>
> +sub vm_suspend {
> + my ($vmid) = @_;
> +
> + my $cmd = ['vzctl', 'chkpnt', $vmid];
> +
> + eval { run_command($cmd); };
> + if (my $err = $@) {
> + syslog("err", "CT $vmid suspend failed - $err");
> + die $err;
> + }
> +}
> +
> +sub vm_resume {
> + my ($vmid) = @_;
> +
> + my $cmd = ['vzctl', 'restore', $vmid];
> +
> + eval { run_command($cmd); };
> + if (my $err = $@) {
> + syslog("err", "CT $vmid resume failed - $err");
> + die $err;
> + }
> +}
> +
> sub replacepw {
> my ($file, $epw) = @_;
>
> diff --git a/www/manager/Utils.js b/www/manager/Utils.js
> index 88ba93d..2463fee 100644
> --- a/www/manager/Utils.js
> +++ b/www/manager/Utils.js
> @@ -567,6 +567,8 @@ Ext.define('PVE.Utils', { statics: {
> vzmount: ['CT', gettext('Mount') ],
> vzumount: ['CT', gettext('Unmount') ],
> vzshutdown: ['CT', gettext('Shutdown') ],
> + vzsuspend: [ 'CT', gettext('Suspend') ],
> + vzresume: [ 'CT', gettext('Resume') ],
> hamigrate: [ 'HA', gettext('Migrate') ],
> hastart: [ 'HA', gettext('Start') ],
> hastop: [ 'HA', gettext('Stop') ],
> diff --git a/www/manager/openvz/CmdMenu.js b/www/manager/openvz/CmdMenu.js
> index 14774a4..d4c5f40 100644
> --- a/www/manager/openvz/CmdMenu.js
> +++ b/www/manager/openvz/CmdMenu.js
> @@ -50,10 +50,31 @@ Ext.define('PVE.openvz.CmdMenu', {
> }
> },
> {
> + text: gettext('Suspend'),
> + icon: '/pve2/images/forward.png',
> + handler: function() {
> + var msg = Ext.String.format(gettext("Do you really
> want to suspend CT {0}?"), vmid);
> + Ext.Msg.confirm(gettext('Confirm'), msg, function(btn)
> {
> + if (btn !== 'yes') {
> + return;
> + }
> +
> + vm_command('suspend');
> + });
> + }
> + },
> + {
> + text: gettext('Resume'),
> + icon: '/pve2/images/forward.png',
> + handler: function() {
> + vm_command('resume');
> + }
> + },
> + {
> text: gettext('Shutdown'),
> icon: '/pve2/images/stop.png',
> handler: function() {
> - var msg = Ext.String.format(gettext("Do you really
> want to shutdown VM {0}?"), vmid);
> + var msg = Ext.String.format(gettext("Do you really
> want to shutdown CT {0}?"), vmid);
> Ext.Msg.confirm(gettext('Confirm'), msg, function(btn)
> {
> if (btn !== 'yes') {
> return;
> @@ -67,7 +88,7 @@ Ext.define('PVE.openvz.CmdMenu', {
> text: gettext('Stop'),
> icon: '/pve2/images/gtk-stop.png',
> handler: function() {
> - var msg = Ext.String.format(gettext("Do you really
> want to stop VM {0}?"), vmid);
> + var msg = Ext.String.format(gettext("Do you really
> want to stop CT {0}?"), vmid);
> Ext.Msg.confirm(gettext('Confirm'), msg, function(btn)
> {
> if (btn !== 'yes') {
> return;
> diff --git a/www/manager/qemu/CmdMenu.js b/www/manager/qemu/CmdMenu.js
> index 30fd82c..8c46b86 100644
> --- a/www/manager/qemu/CmdMenu.js
> +++ b/www/manager/qemu/CmdMenu.js
> @@ -50,6 +50,27 @@ Ext.define('PVE.qemu.CmdMenu', {
> }
> },
> {
> + text: gettext('Suspend'),
> + icon: '/pve2/images/forward.png',
> + handler: function() {
> + var msg = Ext.String.format(gettext("Do you really
> want to suspend VM {0}?"), vmid);
> + Ext.Msg.confirm(gettext('Confirm'), msg, function(btn)
> {
> + if (btn !== 'yes') {
> + return;
> + }
> +
> + vm_command('suspend');
> + });
> + }
> + },
> + {
> + text: gettext('Resume'),
> + icon: '/pve2/images/forward.png',
> + handler: function() {
> + vm_command('resume');
> + }
> + },
> + {
> text: gettext('Shutdown'),
> icon: '/pve2/images/stop.png',
> handler: function() {
> --
> 1.8.3.2
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.proxmox.com/pipermail/pve-devel/attachments/20140303/ff0f2082/attachment.htm>
More information about the pve-devel
mailing list