Make migration RPC non-blocking
[ganeti-local] / lib / hypervisor / hv_base.py
index 698eed0..824842c 100644 (file)
@@ -48,6 +48,12 @@ from ganeti import constants
 
 
 def _IsCpuMaskWellFormed(cpu_mask):
+  """Verifies if the given single CPU mask is valid
+
+  The single CPU mask should be in the form "a,b,c,d", where each
+  letter is a positive number or range.
+
+  """
   try:
     cpu_list = utils.ParseCpuMask(cpu_mask)
   except errors.ParseError, _:
@@ -55,6 +61,21 @@ def _IsCpuMaskWellFormed(cpu_mask):
   return isinstance(cpu_list, list) and len(cpu_list) > 0
 
 
+def _IsMultiCpuMaskWellFormed(cpu_mask):
+  """Verifies if the given multiple CPU mask is valid
+
+  A valid multiple CPU mask is in the form "a:b:c:d", where each
+  letter is a single CPU mask.
+
+  """
+  try:
+    utils.ParseMultiCpuMask(cpu_mask)
+  except errors.ParseError, _:
+    return False
+
+  return True
+
+
 # Read the BaseHypervisor.PARAMETERS docstring for the syntax of the
 # _CHECK values
 
@@ -72,15 +93,26 @@ _CPU_MASK_CHECK = (_IsCpuMaskWellFormed,
                    "CPU mask definition is not well-formed",
                    None, None)
 
+# Multiple CPU mask must be well-formed
+_MULTI_CPU_MASK_CHECK = (_IsMultiCpuMaskWellFormed,
+                         "Multiple CPU mask definition is not well-formed",
+                         None, None)
+
+# Check for validity of port number
+_NET_PORT_CHECK = (lambda x: 0 < x < 65535, "invalid port number",
+                   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_NET_PORT_CHECK = (True, ) + _NET_PORT_CHECK
+OPT_NET_PORT_CHECK = (False, ) + _NET_PORT_CHECK
 REQ_CPU_MASK_CHECK = (True, ) + _CPU_MASK_CHECK
+OPT_CPU_MASK_CHECK = (False, ) + _CPU_MASK_CHECK
+REQ_MULTI_CPU_MASK_CHECK = (True, ) + _MULTI_CPU_MASK_CHECK
+OPT_MULTI_CPU_MASK_CHECK = (False, ) + _MULTI_CPU_MASK_CHECK
 
 # no checks at all
 NO_CHECK = (False, None, None, None, None)
@@ -231,7 +263,7 @@ class BaseHypervisor(object):
     """
     raise NotImplementedError
 
-  def MigrationInfo(self, instance): # pylint: disable-msg=R0201,W0613
+  def MigrationInfo(self, instance): # pylint: disable=R0201,W0613
     """Get instance information to perform a migration.
 
     By default assume no information is needed.
@@ -259,8 +291,8 @@ class BaseHypervisor(object):
     """
     pass
 
-  def FinalizeMigration(self, instance, info, success):
-    """Finalized an instance migration.
+  def FinalizeMigrationDst(self, instance, info, success):
+    """Finalize the instance migration on the target node.
 
     Should finalize or revert any preparation done to accept the instance.
     Since by default we do no preparation, we also don't have anything to do
@@ -288,6 +320,32 @@ class BaseHypervisor(object):
     """
     raise NotImplementedError
 
+  def FinalizeMigrationSource(self, instance, success, live):
+    """Finalize the instance migration on the source node.
+
+    @type instance: L{objects.Instance}
+    @param instance: the instance that was migrated
+    @type success: bool
+    @param success: whether the migration succeeded or not
+    @type live: bool
+    @param live: whether the user requested a live migration or not
+
+    """
+    pass
+
+  def GetMigrationStatus(self, instance):
+    """Get the migration status
+
+    @type instance: L{objects.Instance}
+    @param instance: the instance that is being migrated
+    @rtype: L{objects.MigrationStatus}
+    @return: the status of the current migration (one of
+             L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
+             progress info that can be retrieved from the hypervisor
+
+    """
+    raise NotImplementedError
+
   @classmethod
   def CheckParameterSyntax(cls, hvparams):
     """Check the given parameters for validity.
@@ -382,11 +440,11 @@ class BaseHypervisor(object):
           key = splitfields[0].strip()
           val = splitfields[1].strip()
           if key == "MemTotal":
-            result["memory_total"] = int(val.split()[0])/1024
+            result["memory_total"] = int(val.split()[0]) / 1024
           elif key in ("MemFree", "Buffers", "Cached"):
-            sum_free += int(val.split()[0])/1024
+            sum_free += int(val.split()[0]) / 1024
           elif key == "Active":
-            result["memory_dom0"] = int(val.split()[0])/1024
+            result["memory_dom0"] = int(val.split()[0]) / 1024
     except (ValueError, TypeError), err:
       raise errors.HypervisorError("Failed to compute memory usage: %s" %
                                    (err,))