[pve-devel] [RFC ha-manager 5/8] Add virtual resources for tests and simulation

Thomas Lamprecht t.lamprecht at proxmox.com
Fri Jan 22 17:06:39 CET 2016


Introduce a base class for Virtual Resources with almost all methods
already implemented.
Also add a class for virtual CTs and VMs, with the primary
distinction that CTs may not migrate online.

The Resource are registered in the Hardware class and overwrite
any already registered resources from the same type (e.g. VirtVM
overwrites PVEVM) so that the correct plugins are loaded for
regression tests and the simulator.

This makes the way free for adding(deterministic) 'malicious'
resources, so we can make test where, for example, a service fails
a few times to start or migrate.

Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
---
 src/PVE/HA/Sim/Hardware.pm         |   9 +++
 src/PVE/HA/Sim/Makefile            |   3 +-
 src/PVE/HA/Sim/Resources.pm        | 119 +++++++++++++++++++++++++++++++++++++
 src/PVE/HA/Sim/Resources/Makefile  |   6 ++
 src/PVE/HA/Sim/Resources/VirtCT.pm |  36 +++++++++++
 src/PVE/HA/Sim/Resources/VirtVM.pm |  20 +++++++
 6 files changed, 192 insertions(+), 1 deletion(-)
 create mode 100644 src/PVE/HA/Sim/Resources.pm
 create mode 100644 src/PVE/HA/Sim/Resources/Makefile
 create mode 100644 src/PVE/HA/Sim/Resources/VirtCT.pm
 create mode 100644 src/PVE/HA/Sim/Resources/VirtVM.pm

diff --git a/src/PVE/HA/Sim/Hardware.pm b/src/PVE/HA/Sim/Hardware.pm
index f7ad556..5b96e8a 100644
--- a/src/PVE/HA/Sim/Hardware.pm
+++ b/src/PVE/HA/Sim/Hardware.pm
@@ -17,6 +17,15 @@ use File::Copy;
 use File::Path qw(make_path remove_tree);
 use PVE::HA::Config;
 
+# virtual resource classes
+use PVE::HA::Sim::Resources::VirtVM;
+use PVE::HA::Sim::Resources::VirtCT;
+
+PVE::HA::Sim::Resources::VirtVM->register();
+PVE::HA::Sim::Resources::VirtCT->register();
+
+PVE::HA::Sim::Resources->init();
+
 my $watchdog_timeout = 60;
 
 
diff --git a/src/PVE/HA/Sim/Makefile b/src/PVE/HA/Sim/Makefile
index 13b6fdf..793f142 100644
--- a/src/PVE/HA/Sim/Makefile
+++ b/src/PVE/HA/Sim/Makefile
@@ -1,6 +1,7 @@
-SOURCES=Env.pm Hardware.pm TestEnv.pm TestHardware.pm RTEnv.pm RTHardware.pm
+SOURCES=Env.pm Hardware.pm TestEnv.pm TestHardware.pm RTEnv.pm RTHardware.pm Resources.pm
 
 .PHONY: installsim
 installsim:
 	install -d -m 0755 ${DESTDIR}${PERLDIR}/PVE/HA/Sim
 	for i in ${SOURCES}; do install -D -m 0644 $$i ${DESTDIR}${PERLDIR}/PVE/HA/Sim/$$i; done
+	make -C Resources installsim
diff --git a/src/PVE/HA/Sim/Resources.pm b/src/PVE/HA/Sim/Resources.pm
new file mode 100644
index 0000000..7e13483
--- /dev/null
+++ b/src/PVE/HA/Sim/Resources.pm
@@ -0,0 +1,119 @@
+package PVE::HA::Sim::Resources;
+
+use strict;
+use warnings;
+
+use base qw(PVE::HA::Resources);
+
+# provides some base methods for virtual resources (used in simulation/testing).
+# reduces code reuse and it's targeted for the main PVE service types, namely
+# virtual machines (VM) and container (CT)
+
+sub verify_name {
+    my ($class, $id) = @_;
+
+    die "invalid VMID '$id'\n" if $id !~ m/^[1-9][0-9]+$/;
+}
+
+sub options {
+    return {
+	state => { optional => 1 },
+	group => { optional => 1 },
+	comment => { optional => 1 },
+	max_restart => { optional => 1 },
+	max_relocate => { optional => 1 },
+    };
+}
+
+sub config_file {
+    my ($class, $id, $nodename) = @_;
+
+    my $service_type = $class->type();
+
+    # virtual path
+    return "$nodename/$service_type:$id";
+}
+
+sub is_on_node {
+    my ($class, $haenv, $node, $id) = @_;
+
+    my $service_type = $class->type();
+    my $hardware = $haenv->hardware();
+    my $ss = $hardware->read_service_status($node);
+
+    return defined($ss->{"$service_type:$id"}) ? 1 : 0;
+}
+
+sub start {
+    my ($class, $haenv, $id) = @_;
+
+    my $service_type = $class->type();
+    my $nodename = $haenv->nodename();
+    my $hardware = $haenv->hardware();
+    my $ss = $hardware->read_service_status($nodename);
+
+    $haenv->sleep(2);
+
+    $ss->{"$service_type:$id"} = 1;
+
+    $hardware->write_service_status($nodename, $ss);
+
+}
+
+sub shutdown {
+    my ($class, $haenv, $id) = @_;
+
+    my $service_type = $class->type();
+    my $nodename = $haenv->nodename();
+    my $hardware = $haenv->hardware();
+    my $ss = $hardware->read_service_status($nodename);
+
+    $haenv->sleep(2);
+
+    $ss->{"$service_type:$id"} = 0;
+
+    $hardware->write_service_status($nodename, $ss);
+}
+
+sub check_running {
+    my ($class, $haenv, $id) = @_;
+
+    my $service_type = $class->type();
+    my $nodename = $haenv->nodename();
+    my $hardware = $haenv->hardware();
+
+    my $ss = $hardware->read_service_status($nodename);
+
+    return ($ss->{"$service_type:$id"}) ? 1 : 0;
+}
+
+
+sub migrate {
+    my ($class, $haenv, $id, $target, $online) = @_;
+
+    my $sid = $class->type() . ":$id";
+    my $nodename = $haenv->nodename();
+    my $hardware = $haenv->hardware();
+    my $ss = $hardware->read_service_status($nodename);
+
+    my $cmd = $online ? "migrate" : "relocate";
+    $haenv->log("info", "service $sid - start $cmd to node '$target'");
+
+    # explicitly shutdown if $online isn't true (relocate)
+    if (!$online && $class->check_running($haenv, $id)) {
+	$haenv->log("info", "stopping service $sid (relocate)");
+	$class->shutdown($haenv, $id);
+	$haenv->log("info", "service status $sid stopped");
+    } else {
+	$haenv->sleep(2); # (live) migration time
+    }
+
+    $haenv->change_service_location($sid, $nodename, $target);
+    $haenv->log("info", "service $sid - end $cmd to node '$target'");
+    # ensure that the old node doesn't has the service anymore
+    delete $ss->{$sid};
+    $hardware->write_service_status($nodename, $ss);
+}
+
+
+1;
diff --git a/src/PVE/HA/Sim/Resources/Makefile b/src/PVE/HA/Sim/Resources/Makefile
new file mode 100644
index 0000000..3892258
--- /dev/null
+++ b/src/PVE/HA/Sim/Resources/Makefile
@@ -0,0 +1,6 @@
+SOURCES=VirtVM.pm VirtCT.pm
+
+.PHONY: installsim
+installsim:
+	install -d -m 0755 ${DESTDIR}${PERLDIR}/PVE/HA/Sim/Resources
+	for i in ${SOURCES}; do install -D -m 0644 $$i ${DESTDIR}${PERLDIR}/PVE/HA/Sim/Resources/$$i; done
diff --git a/src/PVE/HA/Sim/Resources/VirtCT.pm b/src/PVE/HA/Sim/Resources/VirtCT.pm
new file mode 100644
index 0000000..10515f7
--- /dev/null
+++ b/src/PVE/HA/Sim/Resources/VirtCT.pm
@@ -0,0 +1,36 @@
+package PVE::HA::Sim::Resources::VirtCT;
+
+use strict;
+use warnings;
+
+use base qw(PVE::HA::Sim::Resources);
+
+sub type {
+    return 'ct';
+}
+
+sub exists {
+    my ($class, $id, $noerr) = @_;
+
+    # in the virtual cluster every virtual CT (of this type) exists
+    return 1;
+}
+
+sub migrate {
+    my ($class, $haenv, $id, $target, $online) = @_;
+
+    my $sid = "ct:$id";
+    my $nodename = $haenv->nodename();
+    my $hardware = $haenv->hardware();
+    my $ss = $hardware->read_service_status($nodename);
+
+    if ($online && $ss->{$sid}) {
+	$haenv->log('warn', "unable to live migrate running container, fallback to relocate");
+	$online = 0;
+    }
+
+    $class->SUPER::migrate($haenv, $id, $target, $online);
+
+}
+
+1;
diff --git a/src/PVE/HA/Sim/Resources/VirtVM.pm b/src/PVE/HA/Sim/Resources/VirtVM.pm
new file mode 100644
index 0000000..48a1852
--- /dev/null
+++ b/src/PVE/HA/Sim/Resources/VirtVM.pm
@@ -0,0 +1,20 @@
+package PVE::HA::Sim::Resources::VirtVM;
+
+use strict;
+use warnings;
+
+use base qw(PVE::HA::Sim::Resources);
+
+sub type {
+    return 'vm';
+}
+
+sub exists {
+    my ($class, $id, $noerr) = @_;
+
+    # in the virtual cluster every virtual VM (of this type) exists
+    return 1;
+}
+
+
+1;
-- 
2.1.4





More information about the pve-devel mailing list