[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