rapi.testutils: Add exported functions to verify opcode input/result
[ganeti-local] / lib / objects.py
index d844628..db4e12e 100644 (file)
@@ -98,13 +98,16 @@ def FillIPolicy(default_ipolicy, custom_ipolicy, skip_keys=None):
   """
   assert frozenset(default_ipolicy.keys()) == constants.IPOLICY_ALL_KEYS
   ret_dict = {}
-  for key in constants.IPOLICY_PARAMETERS:
+  for key in constants.IPOLICY_ISPECS:
     ret_dict[key] = FillDict(default_ipolicy[key],
                              custom_ipolicy.get(key, {}),
                              skip_keys=skip_keys)
   # list items
-  for key in [constants.ISPECS_DTS]:
+  for key in [constants.IPOLICY_DTS]:
     ret_dict[key] = list(custom_ipolicy.get(key, default_ipolicy[key]))
+  # other items which we know we can directly copy (immutables)
+  for key in constants.IPOLICY_PARAMETERS:
+    ret_dict[key] = custom_ipolicy.get(key, default_ipolicy[key])
 
   return ret_dict
 
@@ -182,7 +185,8 @@ def CreateIPolicyFromOpts(ispecs_mem_size=None,
                           ispecs_disk_count=None,
                           ispecs_disk_size=None,
                           ispecs_nic_count=None,
-                          ispecs_disk_templates=None,
+                          ipolicy_disk_templates=None,
+                          ipolicy_vcpu_ratio=None,
                           group_ipolicy=False,
                           allowed_values=None,
                           fill_all=False):
@@ -218,11 +222,17 @@ def CreateIPolicyFromOpts(ispecs_mem_size=None,
     for key, val in specs.items(): # {min: .. ,max: .., std: ..}
       ipolicy_out[key][name] = val
 
-  # no filldict for lists
-  if not group_ipolicy and fill_all and ispecs_disk_templates is None:
-    ispecs_disk_templates = constants.DISK_TEMPLATES
-  if ispecs_disk_templates is not None:
-    ipolicy_out[constants.ISPECS_DTS] = list(ispecs_disk_templates)
+  # no filldict for non-dicts
+  if not group_ipolicy and fill_all:
+    if ipolicy_disk_templates is None:
+      ipolicy_disk_templates = constants.DISK_TEMPLATES
+    if ipolicy_vcpu_ratio is None:
+      ipolicy_vcpu_ratio = \
+        constants.IPOLICY_DEFAULTS[constants.IPOLICY_VCPU_RATIO]
+  if ipolicy_disk_templates is not None:
+    ipolicy_out[constants.IPOLICY_DTS] = list(ipolicy_disk_templates)
+  if ipolicy_vcpu_ratio is not None:
+    ipolicy_out[constants.IPOLICY_VCPU_RATIO] = ipolicy_vcpu_ratio
 
   assert not (frozenset(ipolicy_out.keys()) - constants.IPOLICY_ALL_KEYS)
 
@@ -599,6 +609,8 @@ class Disk(ConfigObject):
       return "/dev/%s/%s" % (self.logical_id[0], self.logical_id[1])
     elif self.dev_type == constants.LD_BLOCKDEV:
       return self.logical_id[1]
+    elif self.dev_type == constants.LD_RBD:
+      return "/dev/%s/%s" % (self.logical_id[0], self.logical_id[1])
     return None
 
   def ChildrenNeeded(self):
@@ -642,7 +654,7 @@ class Disk(ConfigObject):
 
     """
     if self.dev_type in [constants.LD_LV, constants.LD_FILE,
-                         constants.LD_BLOCKDEV]:
+                         constants.LD_BLOCKDEV, constants.LD_RBD]:
       result = [node]
     elif self.dev_type in constants.LDS_DRBD:
       result = [self.logical_id[0], self.logical_id[1]]
@@ -717,7 +729,8 @@ class Disk(ConfigObject):
     actual algorithms from bdev.
 
     """
-    if self.dev_type in (constants.LD_LV, constants.LD_FILE):
+    if self.dev_type in (constants.LD_LV, constants.LD_FILE,
+                         constants.LD_RBD):
       self.size += amount
     elif self.dev_type == constants.LD_DRBD8:
       if self.children:
@@ -727,6 +740,21 @@ class Disk(ConfigObject):
       raise errors.ProgrammerError("Disk.RecordGrow called for unsupported"
                                    " disk type %s" % self.dev_type)
 
+  def Update(self, size=None, mode=None):
+    """Apply changes to size and mode.
+
+    """
+    if self.dev_type == constants.LD_DRBD8:
+      if self.children:
+        self.children[0].Update(size=size, mode=mode)
+    else:
+      assert not self.children
+
+    if size is not None:
+      self.size = size
+    if mode is not None:
+      self.mode = mode
+
   def UnsetSize(self):
     """Sets recursively the size to zero for the disk and its children.
 
@@ -874,9 +902,13 @@ class Disk(ConfigObject):
 
 
 class InstancePolicy(ConfigObject):
-  """Config object representing instance policy limits dictionary."""
-  __slots__ = ["min", "max", "std", "disk_templates"]
+  """Config object representing instance policy limits dictionary.
 
+
+  Note that this object is not actually used in the config, it's just
+  used as a placeholder for a few functions.
+
+  """
   @classmethod
   def CheckParameterSyntax(cls, ipolicy):
     """ Check the instance policy for validity.
@@ -884,8 +916,11 @@ class InstancePolicy(ConfigObject):
     """
     for param in constants.ISPECS_PARAMETERS:
       InstancePolicy.CheckISpecSyntax(ipolicy, param)
-    if constants.ISPECS_DTS in ipolicy:
-      InstancePolicy.CheckDiskTemplates(ipolicy[constants.ISPECS_DTS])
+    if constants.IPOLICY_DTS in ipolicy:
+      InstancePolicy.CheckDiskTemplates(ipolicy[constants.IPOLICY_DTS])
+    for key in constants.IPOLICY_PARAMETERS:
+      if key in ipolicy:
+        InstancePolicy.CheckParameter(key, ipolicy[key])
     wrong_keys = frozenset(ipolicy.keys()) - constants.IPOLICY_ALL_KEYS
     if wrong_keys:
       raise errors.ConfigurationError("Invalid keys in ipolicy: %s" %
@@ -926,6 +961,19 @@ class InstancePolicy(ConfigObject):
       raise errors.ConfigurationError("Invalid disk template(s) %s" %
                                       utils.CommaJoin(wrong))
 
+  @classmethod
+  def CheckParameter(cls, key, value):
+    """Checks a parameter.
+
+    Currently we expect all parameters to be float values.
+
+    """
+    try:
+      float(value)
+    except (TypeError, ValueError), err:
+      raise errors.ConfigurationError("Invalid value for key" " '%s':"
+                                      " '%s', error: %s" % (key, value, err))
+
 
 class Instance(TaggableObject):
   """Config object representing an instance."""