X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/be1fa6136c72720d91f3d5d3eb32e4ef6e78b235..4fe80ef2ed1cda3a6357274eccafe5c1f21a5283:/lib/objects.py diff --git a/lib/objects.py b/lib/objects.py index 23ecfc8..43cea75 100644 --- a/lib/objects.py +++ b/lib/objects.py @@ -29,6 +29,7 @@ pass to and from external parties. import ConfigParser import re +import copy from cStringIO import StringIO from ganeti import errors @@ -49,7 +50,7 @@ class ConfigObject(object): as None instead of raising an error Classes derived from this must always declare __slots__ (we use many - config objects and the memory reduction is useful. + config objects and the memory reduction is useful) """ __slots__ = [] @@ -152,10 +153,27 @@ class ConfigObject(object): " _ContainerFromDicts" % c_type) return ret + def Copy(self): + """Makes a deep copy of the current object and its children. + + """ + dict_form = self.ToDict() + clone_obj = self.__class__.FromDict(dict_form) + return clone_obj + def __repr__(self): """Implement __repr__ for ConfigObjects.""" return repr(self.ToDict()) + def UpgradeConfig(self): + """Fill defaults for missing configuration values. + + This method will be called at configuration load time, and its + implementation will be object dependent. + + """ + pass + class TaggableObject(ConfigObject): """An generic class supporting tags. @@ -178,7 +196,7 @@ class TaggableObject(ConfigObject): constants.MAX_TAG_LEN) if not tag: raise errors.TagError("Tags cannot be empty") - if not re.match("^[ \w.+*/:-]+$", tag): + if not re.match("^[\w.+*/:-]+$", tag): raise errors.TagError("Tag contains invalid characters") def GetTags(self): @@ -237,7 +255,7 @@ class TaggableObject(ConfigObject): class ConfigData(ConfigObject): """Top-level config object.""" - __slots__ = ["cluster", "nodes", "instances", "serial_no"] + __slots__ = ["version", "cluster", "nodes", "instances", "serial_no"] def ToDict(self): """Custom function for top-level config data. @@ -264,6 +282,16 @@ class ConfigData(ConfigObject): obj.instances = cls._ContainerFromDicts(obj.instances, dict, Instance) return obj + def UpgradeConfig(self): + """Fill defaults for missing configuration values. + + """ + self.cluster.UpgradeConfig() + for node in self.nodes.values(): + node.UpgradeConfig() + for instance in self.instances.values(): + instance.UpgradeConfig() + class NIC(ConfigObject): """Config object representing a network card.""" @@ -273,7 +301,7 @@ class NIC(ConfigObject): class Disk(ConfigObject): """Config object representing a block device.""" __slots__ = ["dev_type", "logical_id", "physical_id", - "children", "iv_name", "size"] + "children", "iv_name", "size", "mode"] def CreateOnSecondary(self): """Test if this device needs to be created on a secondary node.""" @@ -387,6 +415,15 @@ class Disk(ConfigObject): raise errors.ProgrammerError("Disk.RecordGrow called for unsupported" " disk type %s" % self.dev_type) + def UnsetSize(self): + """Sets recursively the size to zero for the disk and its children. + + """ + if self.children: + for child in self.children: + child.UnsetSize() + self.size = 0 + def SetPhysicalID(self, target_node, nodes_ip): """Convert the logical ID to the physical ID. @@ -412,7 +449,7 @@ class Disk(ConfigObject): if self.logical_id is None and self.physical_id is not None: return if self.dev_type in constants.LDS_DRBD: - pnode, snode, port, pminor, sminor = self.logical_id + pnode, snode, port, pminor, sminor, secret = self.logical_id if target_node not in (pnode, snode): raise errors.ConfigurationError("DRBD device not knowing node %s" % target_node) @@ -424,9 +461,9 @@ class Disk(ConfigObject): p_data = (pnode_ip, port) s_data = (snode_ip, port) if pnode == target_node: - self.physical_id = p_data + s_data + (pminor,) + self.physical_id = p_data + s_data + (pminor, secret) else: # it must be secondary, we tested above - self.physical_id = s_data + p_data + (sminor,) + self.physical_id = s_data + p_data + (sminor, secret) else: self.physical_id = self.logical_id return @@ -458,9 +495,10 @@ class Disk(ConfigObject): obj.logical_id = tuple(obj.logical_id) if obj.physical_id and isinstance(obj.physical_id, list): obj.physical_id = tuple(obj.physical_id) - if obj.dev_type in constants.LDS_DRBD and len(obj.logical_id) == 3: - # old non-minor based disk type - obj.logical_id += (None, None) + if obj.dev_type in constants.LDS_DRBD: + # we need a tuple of length six here + if len(obj.logical_id) < 6: + obj.logical_id += (None,) * (6 - len(obj.logical_id)) return obj def __str__(self): @@ -470,6 +508,7 @@ class Disk(ConfigObject): if self.dev_type == constants.LD_LV: val = "