[pve-devel] [RFC] Adding PVECT resource class so that CT can be HA managed
Thomas Lamprecht
t.lamprecht at proxmox.com
Mon Aug 31 16:40:38 CEST 2015
Adding an abstraction so that the HA manager can start, stop and
migrate services independent of the its type.
Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
---
src/PVE/HA/Config.pm | 1 +
src/PVE/HA/Env/PVE2.pm | 55 ++++++++++------------
src/PVE/HA/Resources.pm | 121 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 146 insertions(+), 31 deletions(-)
diff --git a/src/PVE/HA/Config.pm b/src/PVE/HA/Config.pm
index 58f5b58..b860abc 100644
--- a/src/PVE/HA/Config.pm
+++ b/src/PVE/HA/Config.pm
@@ -14,6 +14,7 @@ PVE::HA::Groups->register();
PVE::HA::Groups->init();
PVE::HA::Resources::PVEVM->register();
+PVE::HA::Resources::PVECT->register();
#PVE::HA::Resources::IPAddr->register();
PVE::HA::Resources->init();
diff --git a/src/PVE/HA/Env/PVE2.pm b/src/PVE/HA/Env/PVE2.pm
index 4193f49..1da6253 100644
--- a/src/PVE/HA/Env/PVE2.pm
+++ b/src/PVE/HA/Env/PVE2.pm
@@ -16,8 +16,6 @@ use PVE::HA::Tools;
use PVE::HA::Env;
use PVE::HA::Config;
-use PVE::QemuServer;
-use PVE::API2::Qemu;
my $lockdir = "/etc/pve/priv/lock";
@@ -99,7 +97,7 @@ sub read_service_config {
my $d = $res->{ids}->{$sid};
my (undef, undef, $name) = PVE::HA::Tools::parse_sid($sid);
$d->{state} = 'enabled' if !defined($d->{state});
- if ($d->{type} eq 'vm') {
+ if (PVE::HA::Resources->lookup($d->{type})) {
if (my $vmd = $vmlist->{ids}->{$name}) {
if (!$vmd) {
warn "no such VM '$name'\n";
@@ -125,9 +123,9 @@ sub change_service_location {
my (undef, $type, $name) = PVE::HA::Tools::parse_sid($sid);
- if ($type eq 'vm') {
- my $old = PVE::QemuServer::config_file($name, $current_node);
- my $new = PVE::QemuServer::config_file($name, $new_node);
+ if(my $plugin = PVE::HA::Resources->lookup($type)) {
+ my $old = $plugin->config_file($name, $current_node);
+ my $new = $plugin->config_file($name, $current_node);
rename($old, $new) ||
die "rename '$old' to '$new' failed - $!\n";
} else {
@@ -382,16 +380,18 @@ sub exec_resource_agent {
my (undef, $service_type, $service_name) = PVE::HA::Tools::parse_sid($sid);
- die "service type '$service_type'not implemented" if $service_type ne 'vm';
+ #die "service type '$service_type'not implemented" if $service_type ne 'vm';
+ my $plugin = PVE::HA::Resources->lookup($service_type);
+ die "service type '$service_type' not implemented" if !$plugin;
+
+ # fixme: return valid_exit code
+ die "service '$sid' not on this node" if $service_config->{node} ne $nodename;
my $vmid = $service_name;
- my $running = PVE::QemuServer::check_running($vmid, 1);
-
- if ($cmd eq 'started') {
+ my $running = $plugin->check_running($vmid);
- # fixme: return valid_exit code
- die "service '$sid' not on this node" if $service_config->{node} ne $nodename;
+ if ($cmd eq 'started') {
# fixme: count failures
@@ -399,10 +399,10 @@ sub exec_resource_agent {
$self->log("info", "starting service $sid");
- my $upid = PVE::API2::Qemu->vm_start({node => $nodename, vmid => $vmid});
- $self->upid_wait($upid);
+ my $param = {node => $nodename, vmid => $vmid};
+ $plugin->start($self, $param);
- $running = PVE::QemuServer::check_running($vmid, 1);
+ $running = $plugin->check_running($vmid);
if ($running) {
$self->log("info", "service status $sid started");
@@ -414,26 +414,22 @@ sub exec_resource_agent {
} elsif ($cmd eq 'request_stop' || $cmd eq 'stopped') {
- # fixme: return valid_exit code
- die "service '$sid' not on this node" if $service_config->{node} ne $nodename;
-
return 0 if !$running;
$self->log("info", "stopping service $sid");
my $timeout = 60; # fixme: make this configurable
-
+
my $param = {
- node => $nodename,
- vmid => $vmid,
+ node => $nodename,
+ vmid => $vmid,
timeout => $timeout,
forceStop => 1,
};
- my $upid = PVE::API2::Qemu->vm_shutdown($param);
- $self->upid_wait($upid);
+ $plugin->shutdown($self, $param);
- $running = PVE::QemuServer::check_running($vmid, 1);
+ $running = $plugin->check_running($vmid);
if (!$running) {
$self->log("info", "service status $sid stopped");
@@ -447,9 +443,6 @@ sub exec_resource_agent {
my $target = $params[0];
die "$cmd '$sid' failed - missing target\n" if !defined($target);
- # fixme: return valid_exit code
- die "service '$sid' not on this node" if $service_config->{node} ne $nodename;
-
if ($service_config->{node} eq $target) {
# already there
return 0;
@@ -460,7 +453,8 @@ sub exec_resource_agent {
$self->log("info", "service $sid moved to node '$target'");
return 0;
} else {
- # we alwas do live migration if VM is online
+ # we always do live migration if it's a VM and it's online
+ # container get stopped, migrated and then started again
my $params = {
node => $nodename,
@@ -469,10 +463,9 @@ sub exec_resource_agent {
online => 1,
};
- my $oldconfig = PVE::QemuServer::config_file($vmid, $nodename);
+ my $oldconfig = $plugin->config_file($vmid, $nodename);
- my $upid = PVE::API2::Qemu->migrate_vm($params);
- $self->upid_wait($upid);
+ $plugin->migrate($params);
# something went wrong if old config file is still there
if (-f $oldconfig) {
diff --git a/src/PVE/HA/Resources.pm b/src/PVE/HA/Resources.pm
index 099280d..9828e22 100644
--- a/src/PVE/HA/Resources.pm
+++ b/src/PVE/HA/Resources.pm
@@ -8,6 +8,12 @@ use PVE::JSONSchema qw(get_standard_option);
use PVE::SectionConfig;
use PVE::HA::Tools;
+use PVE::QemuServer;
+use PVE::API2::Qemu;
+
+use PVE::LXC;
+use PVE::API2::LXC::Status;
+
use base qw(PVE::SectionConfig);
my $defaultData = {
@@ -69,6 +75,26 @@ sub parse_section_header {
return undef;
}
+sub start {
+ die "implement in subclass";
+}
+
+sub shutdown {
+ die "implement in subclass";
+}
+
+sub migrate {
+ die "implement in subclass";
+}
+
+sub config_file {
+ die "implement in subclass"
+}
+
+sub check_running {
+ die "implement in subclass";
+}
+
package PVE::HA::Resources::PVEVM;
use strict;
@@ -94,6 +120,101 @@ sub options {
};
}
+sub config_file {
+ my ($class, $vmid, $nodename);
+
+ return PVE::QemuServer::config_file($vmid, $nodename);
+}
+
+sub start {
+ my ($class, $haenv, $param) = @_;
+
+ my $upid = PVE::API2::Qemu->vm_start($param);
+ $haenv->upid_wait($upid);
+}
+
+sub shutdown {
+ my ($class, $haenv, $param) = @_;
+
+ my $upid = PVE::API2::Qemu->vm_shutdown($param);
+ $haenv->upid_wait($upid);
+}
+
+
+sub migrate {
+ my ($class, $haenv, $params) = @_;
+
+ my $upid = PVE::API2::Qemu->migrate_vm($params);
+ $haenv->upid_wait($upid);
+}
+
+sub check_running {
+ my ($class, $vmid) = @_;
+
+ return PVE::QemuServer::check_running($vmid, 1);
+}
+
+
+package PVE::HA::Resources::PVECT;
+
+use strict;
+use warnings;
+
+use base qw(PVE::HA::Resources);
+
+sub type {
+ return 'ct';
+}
+
+sub verify_name {
+ my ($class, $name) = @_;
+
+ die "invalid VMID\n" if $name !~ m/^[1-9][0-9]+$/;
+}
+
+sub options {
+ return {
+ state => { optional => 1 },
+ group => { optional => 1 },
+ comment => { optional => 1 },
+ };
+}
+
+sub config_file {
+ my ($class, $vmid, $nodename);
+
+ return PVE::LXC::config_file($vmid, $nodename);
+}
+
+sub start {
+ my ($class, $haenv, $param) = @_;
+
+ my $upid = PVE::API2::LXC::Status->vm_start($param);
+ $haenv->upid_wait($upid);
+}
+
+sub shutdown {
+ my ($class, $haenv, $params) = @_;
+
+ my $upid = PVE::API2::LXC::Status->vm_shutdown($params);
+ $haenv->upid_wait($upid);
+}
+
+# no live migration for LXC
+# so we die for now
+sub migrate {
+ my ($class, $haenv, $params) = @_;
+
+ die "no live migration for LXC - stop it then migrate it";
+
+}
+
+sub check_running {
+ my ($class, $vmid) = @_;
+
+ return PVE::LXC::check_running($vmid);
+}
+
# package PVE::HA::Resources::IPAddr;
# use strict;
--
2.1.4
More information about the pve-devel
mailing list