Set watcher pause on all nodes
[ganeti-local] / lib / hypervisor / hv_base.py
index 824842c..bb0da91 100644 (file)
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2006, 2007, 2008, 2009, 2010 Google Inc.
+# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2012 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
@@ -81,11 +81,11 @@ def _IsMultiCpuMaskWellFormed(cpu_mask):
 
 # must be afile
 _FILE_CHECK = (utils.IsNormAbsPath, "must be an absolute normalized path",
-              os.path.isfile, "not found or not a file")
+               os.path.isfile, "not found or not a file")
 
 # must be a directory
 _DIR_CHECK = (utils.IsNormAbsPath, "must be an absolute normalized path",
-             os.path.isdir, "not found or not a directory")
+              os.path.isdir, "not found or not a directory")
 
 # CPU mask must be well-formed
 # TODO: implement node level check for the CPU mask
@@ -161,6 +161,7 @@ class BaseHypervisor(object):
   """
   PARAMETERS = {}
   ANCILLARY_FILES = []
+  ANCILLARY_FILES_OPT = []
   CAN_MIGRATE = False
 
   def __init__(self):
@@ -249,13 +250,16 @@ class BaseHypervisor(object):
     """Return a list of ancillary files to be copied to all nodes as ancillary
     configuration files.
 
-    @rtype: list of strings
-    @return: list of absolute paths of files to ship cluster-wide
+    @rtype: (list of absolute paths, list of absolute paths)
+    @return: (all files, optional files)
 
     """
     # By default we return a member variable, so that if an hypervisor has just
     # a static list of files it doesn't have to override this function.
-    return cls.ANCILLARY_FILES
+    assert set(cls.ANCILLARY_FILES).issuperset(cls.ANCILLARY_FILES_OPT), \
+      "Optional ancillary files must be a subset of ancillary files"
+
+    return (cls.ANCILLARY_FILES, cls.ANCILLARY_FILES_OPT)
 
   def Verify(self):
     """Verify the hypervisor.
@@ -291,6 +295,17 @@ class BaseHypervisor(object):
     """
     pass
 
+  def BalloonInstanceMemory(self, instance, mem):
+    """Balloon an instance memory to a certain value.
+
+    @type instance: L{objects.Instance}
+    @param instance: instance to be accepted
+    @type mem: int
+    @param mem: actual memory size to use for instance runtime
+
+    """
+    raise NotImplementedError
+
   def FinalizeMigrationDst(self, instance, info, success):
     """Finalize the instance migration on the target node.
 
@@ -346,6 +361,24 @@ class BaseHypervisor(object):
     """
     raise NotImplementedError
 
+  def _InstanceStartupMemory(self, instance):
+    """Get the correct startup memory for an instance
+
+    This function calculates how much memory an instance should be started
+    with, making sure it's a value between the minimum and the maximum memory,
+    but also trying to use no more than the current free memory on the node.
+
+    @type instance: L{objects.Instance}
+    @param instance: the instance that is being started
+    @rtype: integer
+    @return: memory the instance should be started with
+
+    """
+    free_memory = self.GetNodeInfo()["memory_free"]
+    max_start_mem = min(instance.beparams[constants.BE_MAXMEM], free_memory)
+    start_mem = max(instance.beparams[constants.BE_MINMEM], max_start_mem)
+    return start_mem
+
   @classmethod
   def CheckParameterSyntax(cls, hvparams):
     """Check the given parameters for validity.