diff --git a/PVE/API2/OpenVZ.pm b/PVE/API2/OpenVZ.pm index 824769de..49ddfe87 100644 --- a/PVE/API2/OpenVZ.pm +++ b/PVE/API2/OpenVZ.pm @@ -254,7 +254,7 @@ __PACKAGE__->register_method({ if ($param->{force}) { die "cant overwrite mounted container\n" if PVE::OpenVZ::check_mounted($conf, $vmid); } else { - die "container $vmid already exists\n" if -f $basecfg_fn; + die "CT $vmid already exists\n" if -f $basecfg_fn; } my $ostemplate = extract_param($param, 'ostemplate'); @@ -925,10 +925,12 @@ __PACKAGE__->register_method({ 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', "starting container $vmid: $upid\n"); + syslog('info', "starting CT $vmid: $upid\n"); my $cmd = ['vzctl', 'start', $vmid]; @@ -952,10 +954,64 @@ __PACKAGE__->register_method({ properties => { node => get_standard_option('pve-node'), vmid => get_standard_option('pve-vmid'), - fast => { - type => 'boolean', - description => "This is faster but can lead to unclean container shutdown.", + }, + }, + returns => { + type => 'string', + }, + code => sub { + my ($param) = @_; + + my $rpcenv = PVE::RPCEnvironment::get(); + + my $user = $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', "stoping CT $vmid: $upid\n"); + + my $cmd = ['vzctl', 'stop', $vmid, '--fast']; + run_command($cmd); + + return; + }; + + my $upid = $rpcenv->fork_worker('vzstop', $vmid, $user, $realcmd); + + return $upid; + }}); + +__PACKAGE__->register_method({ + name => 'vm_shutdown', + path => '{vmid}/status/shutdown', + method => 'POST', + protected => 1, + proxyto => 'node', + description => "Shutdown the container.", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + vmid => get_standard_option('pve-vmid'), + timeout => { + description => "Wait maximal timeout seconds.", + type => 'integer', + minimum => 0, optional => 1, + default => 60, + }, + forceStop => { + description => "Make sure the Container stops.", + type => 'boolean', + optional => 1, + default => 0, } }, }, @@ -973,21 +1029,34 @@ __PACKAGE__->register_method({ my $vmid = extract_param($param, 'vmid'); + my $timeout = extract_param($param, 'timeout'); + + die "CT $vmid not running\n" if !PVE::OpenVZ::check_running($vmid); + my $realcmd = sub { my $upid = shift; - syslog('info', "stoping container $vmid: $upid\n"); + syslog('info', "shutdown CT $vmid: $upid\n"); my $cmd = ['vzctl', 'stop', $vmid]; - push @$cmd, '--fast' if $param->{fast}; - + $timeout = 60 if !defined($timeout); + + eval { run_command($cmd, timeout => $timeout); }; + my $err = $@; + return if !$err; + + die $err if !$param->{forceStop}; + + warn "shutdown failed - forcing stop now\n"; + + push @$cmd, '--fast'; run_command($cmd); return; }; - my $upid = $rpcenv->fork_worker('vzstop', $vmid, $user, $realcmd); + my $upid = $rpcenv->fork_worker('vzshutdown', $vmid, $user, $realcmd); return $upid; }}); diff --git a/bin/ocf/pvevm b/bin/ocf/pvevm index aa9cce08..6e2aa4f5 100755 --- a/bin/ocf/pvevm +++ b/bin/ocf/pvevm @@ -29,9 +29,19 @@ use constant OCF_FAILED_MASTER => 9; $ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin'; +my $ocf_ressource_type = $0; +my $prio_hash = { + err => 3, + note => 5, + info => 6, + debug => 7, +}; + $SIG{__DIE__} = sub { die @_ if $^S; # skip if inside eval $! = OCF_ERR_GENERIC; + ocf_log('err', @_); + exit($!); }; if ($> != 0) { @@ -55,11 +65,30 @@ my @ssh_cmd = ('ssh', @ssh_opts); sub ocf_log { my ($level, $msg) = @_; - # fixme: - - chomp $msg; - + chomp $msg; print "$level: $msg\n"; + + my $level_n = $prio_hash->{$level}; + $level_n = $prio_hash->{note} if !defined($level_n); + + my $cmd = ['clulog', '-m', $ocf_ressource_type, '-s', $level_n, $msg]; + + eval { PVE::Tools::run_command($cmd); }; # ignore errors +} + +sub get_timeout { + my $default_timeout = 60; + my $tout = $default_timeout; + + if ($ENV{OCF_RESKEY_RGMANAGER_meta_timeout}) { + $tout = $ENV{OCF_RESKEY_RGMANAGER_meta_timeout}; + } elsif ($ENV{OCF_RESKEY_CRM_meta_timeout}) { + $tout = $ENV{OCF_RESKEY_CRM_meta_timeout}; + } + + return $default_timeout if $tout <= 0; + + return $tout; } sub check_running { @@ -92,8 +121,6 @@ sub validate_all { $status->{type} = $data->{type}; $status->{node} = $data->{node}; - ocf_log('debug', "VM $vmid ($status->{type}) on node $status->{node}\n"); - check_running($status); }; if (my $err = $@) { @@ -156,7 +183,25 @@ if ($cmd eq 'start') { check_running($status); - exit($status->{running} ? OCF_SUCCESS : OCF_ERR_GENERIC); + exit(OCF_ERR_GENERIC) if !$status->{running}; + + if (my $testprog = $ENV{OCF_RESKEY_status_program}) { + + my $timeout = get_timeout(); + + my $wait_func = sub { + while (system($testprog) != 0) { sleep(3); } + }; + + eval { PVE::Tools::run_with_timeout($timeout, $wait_func); }; + if (my $err = $@) { + ocf_log('err', "Start of VM $status->{vmid} has failed"); + ocf_log('err', "error while waiting for '$testprog' - $err"); + exit(OCF_ERR_GENERIC); + } + } + + exit(OCF_SUCCESS); } elsif($cmd eq 'stop') { my $status = validate_all(); @@ -166,12 +211,21 @@ if ($cmd eq 'start') { exit(OCF_SUCCESS); } + my $timeout = get_timeout(); + my $upid; - + + my $param = { + node => $nodename, + vmid => $status->{vmid}, + timeout => $timeout, + forceStop => 1, + }; + if ($status->{type} eq 'qemu') { - $upid = PVE::API2::Qemu->vm_stop({node => $nodename, vmid => $status->{vmid}}); + $upid = PVE::API2::Qemu->vm_shutdown($param); } else { - $upid = PVE::API2::OpenVZ->vm_stop({node => $nodename, vmid => $status->{vmid}, fast => 1}); + $upid = PVE::API2::OpenVZ->vm_shutdown($param); } upid_wait($upid); @@ -187,14 +241,25 @@ if ($cmd eq 'start') { } elsif($cmd eq 'status' || $cmd eq 'monitor') { my $status = validate_all(); - if ($status->{running}) { - ocf_log('debug', "Resource is running"); - exit(OCF_SUCCESS); - } else { + + if (!$status->{running}) { ocf_log('debug', "Resource is not running"); exit(OCF_NOT_RUNNING); } + ocf_log('debug', "Resource is running"); + + my $testprog = $ENV{OCF_RESKEY_status_program}; + my $checklevel = $ENV{OCF_CHECK_LEVEL}; + + if ($testprog && $checklevel && $checklevel >= 10) { + if (system($testprog) != 0) { + exit(OCF_NOT_RUNNING); + } + } + + exit(OCF_SUCCESS); + } elsif($cmd eq 'migrate') { my $status = validate_all(); if (!$status->{running}) { @@ -208,29 +273,11 @@ if ($cmd eq 'start') { }; - # test ssh connection and try to detect node name - my @rem_ssh = (@ssh_cmd, "root\@$migratetarget"); - my $cmd = [ @rem_ssh, '/bin/hostname' ]; - my $targetnode = ''; - eval { - PVE::Tools::run_command($cmd, outfunc => sub { - $targetnode = shift if !$targetnode; - }); - }; - if (my $err = $@) { - ocf_log('err', "can't connect to target '$migratetarget' - $err"); - exit(OCF_ERR_GENERIC); - } - if (!PVE::Cluster::check_node_exists($targetnode, 1)) { - ocf_log('err', "target hostname '$targetnode' is no cluster member"); - exit(OCF_ERR_GENERIC); - } - my $upid; my $params = { node => $nodename, vmid => $status->{vmid}, - target => $targetnode, + target => $migratetarget, online => 1, }; @@ -365,6 +412,16 @@ __DATA__ + + + Migration type (live or pause, default = live). + + + Migration type (live or pause, default = live). + + + + Service dependency; will not start without the specified diff --git a/bin/pvectl b/bin/pvectl index 177f34d3..0afb3fd2 100755 --- a/bin/pvectl +++ b/bin/pvectl @@ -73,6 +73,7 @@ my $cmddef = { }], start => [ 'PVE::API2::OpenVZ', 'vm_start', ['vmid'], { node => $nodename }, $upid_exit], + shutdown => [ 'PVE::API2::OpenVZ', 'vm_shutdown', ['vmid'], { node => $nodename }, $upid_exit], stop => [ 'PVE::API2::OpenVZ', 'vm_stop', ['vmid'], { node => $nodename }, $upid_exit], migrate => [ "PVE::API2::OpenVZ", 'migrate_vm', ['vmid', 'target'], { node => $nodename }, $upid_exit], diff --git a/debian/changelog.Debian b/debian/changelog.Debian index b01503c7..146921e0 100644 --- a/debian/changelog.Debian +++ b/debian/changelog.Debian @@ -1,3 +1,11 @@ +pve-manager (2.0-16) unstable; urgency=low + + * improve OpenVZ API (impl. shutdown) + + * improve HA resource agent + + -- Proxmox Support Team Thu, 15 Dec 2011 13:48:39 +0100 + pve-manager (2.0-15) unstable; urgency=low * add HA resource agent diff --git a/defines.mk b/defines.mk index ec4d2281..e926fd32 100644 --- a/defines.mk +++ b/defines.mk @@ -2,7 +2,7 @@ RELEASE=2.0 VERSION=2.0 PACKAGE=pve-manager -PACKAGERELEASE=15 +PACKAGERELEASE=16 BINDIR=${DESTDIR}/usr/bin PERLLIBDIR=${DESTDIR}/usr/share/perl5 diff --git a/www/manager/Utils.js b/www/manager/Utils.js index effa64f9..31c6e6a8 100644 --- a/www/manager/Utils.js +++ b/www/manager/Utils.js @@ -389,6 +389,7 @@ Ext.define('PVE.Utils', { statics: { vzmigrate: [ 'CT', gettext('Migrate') ], vzstart: ['CT', gettext('Start') ], vzstop: ['CT', gettext('Stop') ], + vzshutdown: ['CT', gettext('Shutdown') ], srvstart: ['SRV', gettext('Start') ], srvstop: ['SRV', gettext('Stop') ], srvrestart: ['SRV', gettext('Restart') ], diff --git a/www/manager/openvz/CmdMenu.js b/www/manager/openvz/CmdMenu.js index cffeaf67..c250f246 100644 --- a/www/manager/openvz/CmdMenu.js +++ b/www/manager/openvz/CmdMenu.js @@ -47,7 +47,7 @@ Ext.define('PVE.openvz.CmdMenu', { return; } - vm_command('stop'); + vm_command('shutdown'); }); } }, diff --git a/www/manager/openvz/Config.js b/www/manager/openvz/Config.js index c99399f5..15f8438b 100644 --- a/www/manager/openvz/Config.js +++ b/www/manager/openvz/Config.js @@ -43,7 +43,7 @@ Ext.define('PVE.openvz.Config', { text: gettext('Stop'), confirmMsg: Ext.String.format(gettext("Do you really want to stop VM {0}?"), vmid), handler: function() { - vm_command("stop", { fast: 1 }); + vm_command("stop"); } }); @@ -51,7 +51,7 @@ Ext.define('PVE.openvz.Config', { text: gettext('Shutdown'), confirmMsg: Ext.String.format(gettext("Do you really want to shutdown VM {0}?"), vmid), handler: function() { - vm_command('stop'); + vm_command('shutdown'); } });