Commit 94fed7da authored by Iustin Pop's avatar Iustin Pop
Browse files

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: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarOlivier Tharan <olive@google.com>
parent 0a4e7f24
......@@ -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
......
......@@ -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")
......@@ -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)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment