X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/58d38b02328fcbfc0c1f1637c6084006f5400023..8a53b55f3a83f3bdf3b231f90e766fc15ec51895:/lib/hypervisor/hv_base.py diff --git a/lib/hypervisor/hv_base.py b/lib/hypervisor/hv_base.py index 45316e0..ec47400 100644 --- a/lib/hypervisor/hv_base.py +++ b/lib/hypervisor/hv_base.py @@ -1,7 +1,7 @@ # # -# Copyright (C) 2006, 2007, 2008 Google Inc. +# Copyright (C) 2006, 2007, 2008, 2009, 2010 Google Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -44,6 +44,15 @@ import logging from ganeti import errors from ganeti import utils +from ganeti import constants + + +def _IsCpuMaskWellFormed(cpu_mask): + try: + cpu_list = utils.ParseCpuMask(cpu_mask) + except errors.ParseError, _: + return False + return isinstance(cpu_list, list) and len(cpu_list) > 0 # Read the BaseHypervisor.PARAMETERS docstring for the syntax of the @@ -57,11 +66,21 @@ _FILE_CHECK = (utils.IsNormAbsPath, "must be an absolute normalized path", _DIR_CHECK = (utils.IsNormAbsPath, "must be an absolute normalized path", os.path.isdir, "not found or not a directory") +# CPU mask must be well-formed +# TODO: implement node level check for the CPU mask +_CPU_MASK_CHECK = (_IsCpuMaskWellFormed, + "CPU mask definition is not well-formed", + None, None) + # nice wrappers for users REQ_FILE_CHECK = (True, ) + _FILE_CHECK OPT_FILE_CHECK = (False, ) + _FILE_CHECK REQ_DIR_CHECK = (True, ) + _DIR_CHECK OPT_DIR_CHECK = (False, ) + _DIR_CHECK +NET_PORT_CHECK = (True, lambda x: x > 0 and x < 65535, "invalid port number", + None, None) +OPT_CPU_MASK_CHECK = (False, ) + _CPU_MASK_CHECK +REQ_CPU_MASK_CHECK = (True, ) + _CPU_MASK_CHECK # no checks at all NO_CHECK = (False, None, None, None, None) @@ -69,6 +88,10 @@ NO_CHECK = (False, None, None, None, None) # required, but no other checks REQUIRED_CHECK = (True, None, None, None, None) +# migration type +MIGRATION_MODE_CHECK = (True, lambda x: x in constants.HT_MIGRATION_MODES, + "invalid migration mode", None, None) + def ParamInSet(required, my_set): """Builds parameter checker for set membership. @@ -80,7 +103,7 @@ def ParamInSet(required, my_set): """ fn = lambda x: x in my_set - err = ("The value must be one of: %s" % " ,".join(my_set)) + err = ("The value must be one of: %s" % utils.CommaJoin(my_set)) return (required, fn, err, None, None) @@ -99,10 +122,14 @@ class BaseHypervisor(object): - a function to check for parameter validity on the remote node, in the L{ValidateParameters} function - an error message for the above function + @type CAN_MIGRATE: boolean + @cvar CAN_MIGRATE: whether this hypervisor can do migration (either + live or non-live) """ PARAMETERS = {} ANCILLARY_FILES = [] + CAN_MIGRATE = False def __init__(self): pass @@ -111,7 +138,7 @@ class BaseHypervisor(object): """Start an instance.""" raise NotImplementedError - def StopInstance(self, instance, force=False, retry=False): + def StopInstance(self, instance, force=False, retry=False, name=None): """Stop an instance @type instance: L{objects.Instance} @@ -120,10 +147,26 @@ class BaseHypervisor(object): @param force: whether to do a "hard" stop (destroy) @type retry: boolean @param retry: whether this is just a retry call + @type name: string or None + @param name: if this parameter is passed, the the instance object + should not be used (will be passed as None), and the shutdown + must be done by name only """ raise NotImplementedError + def CleanupInstance(self, instance_name): + """Cleanup after a stopped instance + + This is an optional method, used by hypervisors that need to cleanup after + an instance has been stopped. + + @type instance_name: string + @param instance_name: instance name to cleanup after + + """ + pass + def RebootInstance(self, instance): """Reboot an instance.""" raise NotImplementedError @@ -163,8 +206,8 @@ class BaseHypervisor(object): raise NotImplementedError @classmethod - def GetShellCommandForConsole(cls, instance, hvparams, beparams): - """Return a command for connecting to the console of an instance. + def GetInstanceConsole(cls, instance, hvparams, beparams): + """Return information for connecting to the console of an instance. """ raise NotImplementedError @@ -188,7 +231,7 @@ class BaseHypervisor(object): """ raise NotImplementedError - def MigrationInfo(self, instance): + def MigrationInfo(self, instance): # pylint: disable-msg=R0201,W0613 """Get instance information to perform a migration. By default assume no information is needed. @@ -223,7 +266,7 @@ class BaseHypervisor(object): Since by default we do no preparation, we also don't have anything to do @type instance: L{objects.Instance} - @param instance: instance whose migration is being aborted + @param instance: instance whose migration is being finalized @type info: string/data (opaque) @param info: migration information, from the source node @type success: boolean @@ -235,8 +278,8 @@ class BaseHypervisor(object): def MigrateInstance(self, instance, target, live): """Migrate an instance. - @type instance: L{object.Instance} - @param name: the instance to be migrated + @type instance: L{objects.Instance} + @param instance: the instance to be migrated @type target: string @param target: hostname (usually ip) of the target node @type live: boolean @@ -308,8 +351,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