X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/52f93ffde5e02c090c8de6a221278186dfe1083b..7ec2f76bf6519ad4a49f6049e5b49da71f4c2d4c:/lib/objects.py diff --git a/lib/objects.py b/lib/objects.py index 4be25ab..2a0b8bd 100644 --- a/lib/objects.py +++ b/lib/objects.py @@ -51,7 +51,7 @@ from socket import AF_INET __all__ = ["ConfigObject", "ConfigData", "NIC", "Disk", "Instance", - "OS", "Node", "NodeGroup", "Cluster", "FillDict"] + "OS", "Node", "NodeGroup", "Cluster", "FillDict", "Network"] _TIMESTAMPS = ["ctime", "mtime"] _UUID = ["uuid"] @@ -420,7 +420,7 @@ class MasterNetworkParameters(ConfigObject): "ip", "netmask", "netdev", - "ip_family" + "ip_family", ] @@ -432,6 +432,7 @@ class ConfigData(ConfigObject): "nodes", "nodegroups", "instances", + "networks", "serial_no", ] + _TIMESTAMPS @@ -444,7 +445,7 @@ class ConfigData(ConfigObject): """ mydict = super(ConfigData, self).ToDict() mydict["cluster"] = mydict["cluster"].ToDict() - for key in "nodes", "instances", "nodegroups": + for key in "nodes", "instances", "nodegroups", "networks": mydict[key] = self._ContainerToDicts(mydict[key]) return mydict @@ -459,6 +460,7 @@ class ConfigData(ConfigObject): obj.nodes = cls._ContainerFromDicts(obj.nodes, dict, Node) obj.instances = cls._ContainerFromDicts(obj.instances, dict, Instance) obj.nodegroups = cls._ContainerFromDicts(obj.nodegroups, dict, NodeGroup) + obj.networks = cls._ContainerFromDicts(obj.networks, dict, Network) return obj def HasAnyDiskOfType(self, dev_type): @@ -495,11 +497,13 @@ class ConfigData(ConfigObject): # gives a good approximation. if self.HasAnyDiskOfType(constants.LD_DRBD8): self.cluster.drbd_usermode_helper = constants.DEFAULT_DRBD_HELPER + if self.networks is None: + self.networks = {} class NIC(ConfigObject): """Config object representing a network card.""" - __slots__ = ["mac", "ip", "nicparams"] + __slots__ = ["mac", "ip", "network", "nicparams", "netinfo"] @classmethod def CheckParameterSyntax(cls, nicparams): @@ -510,15 +514,14 @@ class NIC(ConfigObject): @raise errors.ConfigurationError: when a parameter is not valid """ - if (nicparams[constants.NIC_MODE] not in constants.NIC_VALID_MODES and - nicparams[constants.NIC_MODE] != constants.VALUE_AUTO): - err = "Invalid nic mode: %s" % nicparams[constants.NIC_MODE] - raise errors.ConfigurationError(err) + mode = nicparams[constants.NIC_MODE] + if (mode not in constants.NIC_VALID_MODES and + mode != constants.VALUE_AUTO): + raise errors.ConfigurationError("Invalid NIC mode '%s'" % mode) - if (nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED and + if (mode == constants.NIC_MODE_BRIDGED and not nicparams[constants.NIC_LINK]): - err = "Missing bridged nic link" - raise errors.ConfigurationError(err) + raise errors.ConfigurationError("Missing bridged NIC link") class Disk(ConfigObject): @@ -598,7 +601,8 @@ class Disk(ConfigObject): """ if self.dev_type in [constants.LD_LV, constants.LD_FILE, - constants.LD_BLOCKDEV, constants.LD_RBD]: + constants.LD_BLOCKDEV, constants.LD_RBD, + constants.LD_EXT]: result = [node] elif self.dev_type in constants.LDS_DRBD: result = [self.logical_id[0], self.logical_id[1]] @@ -674,7 +678,7 @@ class Disk(ConfigObject): """ if self.dev_type in (constants.LD_LV, constants.LD_FILE, - constants.LD_RBD): + constants.LD_RBD, constants.LD_EXT): self.size += amount elif self.dev_type == constants.LD_DRBD8: if self.children: @@ -901,9 +905,12 @@ class Disk(ConfigObject): elif disk_template == constants.DT_RBD: result.append(FillDict(constants.DISK_LD_DEFAULTS[constants.LD_RBD], { - constants.LDP_POOL: dt_params[constants.RBD_POOL] + constants.LDP_POOL: dt_params[constants.RBD_POOL], })) + elif disk_template == constants.DT_EXT: + result.append(constants.DISK_LD_DEFAULTS[constants.LD_EXT]) + return result @@ -1019,7 +1026,7 @@ class Instance(TaggableObject): return tuple(all_nodes) secondary_nodes = property(_ComputeSecondaryNodes, None, None, - "List of secondary nodes") + "List of names of secondary nodes") def _ComputeAllNodes(self): """Compute the list of all nodes. @@ -1047,7 +1054,7 @@ class Instance(TaggableObject): return tuple(all_nodes) all_nodes = property(_ComputeAllNodes, None, None, - "List of all nodes of the instance") + "List of names of all the nodes of the instance") def MapLVsByNode(self, lvmap=None, devs=None, node=None): """Provide a mapping of nodes to LVs this instance owns. @@ -1231,6 +1238,24 @@ class OS(ConfigObject): return cls.SplitNameVariant(name)[1] +class ExtStorage(ConfigObject): + """Config object representing an External Storage Provider. + + """ + __slots__ = [ + "name", + "path", + "create_script", + "remove_script", + "grow_script", + "attach_script", + "detach_script", + "setinfo_script", + "verify_script", + "supported_parameters", + ] + + class NodeHvState(ConfigObject): """Hypvervisor state on a node. @@ -1359,6 +1384,7 @@ class NodeGroup(TaggableObject): "hv_state_static", "disk_state_static", "alloc_policy", + "networks", ] + _TIMESTAMPS + _UUID def ToDict(self): @@ -1406,6 +1432,9 @@ class NodeGroup(TaggableObject): if self.ipolicy is None: self.ipolicy = MakeEmptyIPolicy() + if self.networks is None: + self.networks = {} + def FillND(self, node): """Return filled out ndparams for L{objects.Node} @@ -1989,6 +2018,26 @@ class InstanceConsole(ConfigObject): return True +class Network(TaggableObject): + """Object representing a network definition for ganeti. + + """ + __slots__ = [ + "name", + "serial_no", + "network_type", + "mac_prefix", + "family", + "network", + "network6", + "gateway", + "gateway6", + "size", + "reservations", + "ext_reservations", + ] + _TIMESTAMPS + _UUID + + class SerializableConfigParser(ConfigParser.SafeConfigParser): """Simple wrapper over ConfigParse that allows serialization. @@ -2010,3 +2059,38 @@ class SerializableConfigParser(ConfigParser.SafeConfigParser): cfp = cls() cfp.readfp(buf) return cfp + + +class LvmPvInfo(ConfigObject): + """Information about an LVM physical volume (PV). + + @type name: string + @ivar name: name of the PV + @type vg_name: string + @ivar vg_name: name of the volume group containing the PV + @type size: float + @ivar size: size of the PV in MiB + @type free: float + @ivar free: free space in the PV, in MiB + @type attributes: string + @ivar attributes: PV attributes + """ + __slots__ = [ + "name", + "vg_name", + "size", + "free", + "attributes", + ] + + def IsEmpty(self): + """Is this PV empty? + + """ + return self.size <= (self.free + 1) + + def IsAllocatable(self): + """Is this PV allocatable? + + """ + return ("a" in self.attributes)