From 94fed7dabe521ca18aa9aaa47f22d744b05ee8cc Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Tue, 29 Dec 2009 11:23:32 +0100 Subject: [PATCH] Implement all hv functions in hv_chroot/hv_fake The chroot and fake hypervisors were missing: - the powercycle node functionality - proper handling of migration requests The powercycle was just used as in the other hypervisors (use the standard linux powercycle). The migration for chroot was disabled explicitly, whereas for the fake one it was implemented to simulate correctly. This required some work on the fake hypervisor, but now the implementation of start/stop/etc. is much more clean. Signed-off-by: Iustin Pop <iustin@google.com> Reviewed-by: Olivier Tharan <olive@google.com> --- lib/hypervisor/hv_base.py | 4 +- lib/hypervisor/hv_chroot.py | 20 ++++++++ lib/hypervisor/hv_fake.py | 100 +++++++++++++++++++++++++++++++----- 3 files changed, 110 insertions(+), 14 deletions(-) diff --git a/lib/hypervisor/hv_base.py b/lib/hypervisor/hv_base.py index eacc0ecd1..cdef0d02e 100644 --- a/lib/hypervisor/hv_base.py +++ b/lib/hypervisor/hv_base.py @@ -310,8 +310,8 @@ class BaseHypervisor(object): """ raise NotImplementedError - - def GetLinuxNodeInfo(self): + @staticmethod + def GetLinuxNodeInfo(): """For linux systems, return actual OS information. This is an abstraction for all non-hypervisor-based classes, where diff --git a/lib/hypervisor/hv_chroot.py b/lib/hypervisor/hv_chroot.py index 69b9fe21e..1a9e4a31b 100644 --- a/lib/hypervisor/hv_chroot.py +++ b/lib/hypervisor/hv_chroot.py @@ -255,3 +255,23 @@ class ChrootManager(hv_base.BaseHypervisor): """ if not os.path.exists(self._ROOT_DIR): return "The required directory '%s' does not exist." % self._ROOT_DIR + + @classmethod + def PowercycleNode(cls): + """Chroot powercycle, just a wrapper over Linux powercycle. + + """ + cls.LinuxPowercycle() + + def MigrateInstance(self, instance, target, live): + """Migrate an instance. + + @type instance: L{object.Instance} + @param instance: the instance to be migrated + @type target: string + @param target: hostname (usually ip) of the target node + @type live: boolean + @param live: whether to do a live or non-live migration + + """ + raise HypervisorError("Migration not supported by the chroot hypervisor") diff --git a/lib/hypervisor/hv_fake.py b/lib/hypervisor/hv_fake.py index 632ff401d..bf4a654a8 100644 --- a/lib/hypervisor/hv_fake.py +++ b/lib/hypervisor/hv_fake.py @@ -25,6 +25,7 @@ import os import os.path +import logging from ganeti import utils from ganeti import constants @@ -106,6 +107,44 @@ class FakeHypervisor(hv_base.BaseHypervisor): raise errors.HypervisorError("Failed to list instances: %s" % err) return data + + def _InstanceFile(self, instance_name): + """Compute the instance file for an instance name. + + """ + return self._ROOT_DIR + "/%s" % instance_name + + def _IsAlive(self, instance_name): + """Checks if an instance is alive. + + """ + file_name = self._InstanceFile(instance_name) + return os.path.exists(file_name) + + def _MarkUp(self, instance): + """Mark the instance as running. + + This does no checks, which should be done by its callers. + + """ + file_name = self._InstanceFile(instance.name) + fh = file(file_name, "w") + try: + fh.write("0\n%d\n%d\n" % + (instance.beparams[constants.BE_MEMORY], + instance.beparams[constants.BE_VCPUS])) + finally: + fh.close() + + def _MarkDown(self, instance): + """Mark the instance as running. + + This does no checks, which should be done by its callers. + + """ + file_name = self._InstanceFile(instance.name) + utils.RemoveFile(file_name) + def StartInstance(self, instance, block_devices): """Start an instance. @@ -114,18 +153,11 @@ class FakeHypervisor(hv_base.BaseHypervisor): handle race conditions properly, since these are *FAKE* instances. """ - file_name = self._ROOT_DIR + "/%s" % instance.name - if os.path.exists(file_name): + if self._IsAlive(instance.name): raise errors.HypervisorError("Failed to start instance %s: %s" % (instance.name, "already running")) try: - fh = file(file_name, "w") - try: - fh.write("0\n%d\n%d\n" % - (instance.beparams[constants.BE_MEMORY], - instance.beparams[constants.BE_VCPUS])) - finally: - fh.close() + self._MarkUp(instance) except IOError, err: raise errors.HypervisorError("Failed to start instance %s: %s" % (instance.name, err)) @@ -137,11 +169,10 @@ class FakeHypervisor(hv_base.BaseHypervisor): dir, if it exist, otherwise we raise an exception. """ - file_name = self._ROOT_DIR + "/%s" % instance.name - if not os.path.exists(file_name): + if not self._IsAlive(instance.name): raise errors.HypervisorError("Failed to stop instance %s: %s" % (instance.name, "not running")) - utils.RemoveFile(file_name) + self._MarkDown(instance) def RebootInstance(self, instance): """Reboot an instance. @@ -192,3 +223,48 @@ class FakeHypervisor(hv_base.BaseHypervisor): """ cls.LinuxPowercycle() + + def AcceptInstance(self, instance, info, target): + """Prepare to accept an instance. + + @type instance: L{objects.Instance} + @param instance: instance to be accepted + @type info: string + @param info: instance info, not used + @type target: string + @param target: target host (usually ip), on this node + + """ + if self._IsAlive(instance.name): + raise errors.HypervisorError("Can't accept instance, already running") + + def MigrateInstance(self, instance, target, live): + """Migrate an instance. + + @type instance: L{object.Instance} + @param instance: the instance to be migrated + @type target: string + @param target: hostname (usually ip) of the target node + @type live: boolean + @param live: whether to do a live or non-live migration + + """ + logging.debug("Fake hypervisor migrating %s to %s (live=%s)", + instance, target, live) + + self._MarkDown(instance) + + def FinalizeMigration(self, instance, info, success): + """Finalize an instance migration. + + For the fake hv, this just marks the instance up. + + @type instance: L{objects.Instance} + @param instance: instance whose migration is being finalized + + """ + if success: + self._MarkUp(instance) + else: + # ensure it's down + self._MarkDown(instance) -- GitLab