X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/4d4a651d785e95287f4a3107ad9c9fbf9993621f..a91143f196b00a97a7d367a09f37a00a4a44c594:/lib/ssconf.py diff --git a/lib/ssconf.py b/lib/ssconf.py index 56e89ec..966f670 100644 --- a/lib/ssconf.py +++ b/lib/ssconf.py @@ -34,6 +34,7 @@ from ganeti import errors from ganeti import constants from ganeti import utils from ganeti import serializer +from ganeti import objects SSCONF_LOCK_TIMEOUT = 10 @@ -56,6 +57,14 @@ class SimpleConfigReader(object): self._last_inode = None self._last_mtime = None self._last_size = None + + self._config_data = None + self._inst_ips_by_link = None + self._ip_to_inst_by_link = None + self._instances_ips = None + self._mc_primary_ips = None + self._nodes_primary_ips = None + # we need a forced reload at class init time, to initialize _last_* self._Load(force=True) @@ -78,16 +87,14 @@ class SimpleConfigReader(object): mtime = cfg_stat.st_mtime size = cfg_stat.st_size - reload = False - if force or inode != self._last_inode or \ - mtime > self._last_mtime or \ - size != self._last_size: + if (force or inode != self._last_inode or + mtime > self._last_mtime or + size != self._last_size): self._last_inode = inode self._last_mtime = mtime self._last_size = size - reload = True - - if not reload: + else: + # Don't reload return False try: @@ -99,12 +106,28 @@ class SimpleConfigReader(object): raise errors.ConfigurationError("Cannot load config file %s: %s" % (self._file_name, err)) - self._ip_to_instance = {} + self._ip_to_inst_by_link = {} + self._instances_ips = [] + self._inst_ips_by_link = {} + c_nparams = self._config_data['cluster']['nicparams'][constants.PP_DEFAULT] for iname in self._config_data['instances']: instance = self._config_data['instances'][iname] for nic in instance['nics']: if 'ip' in nic and nic['ip']: - self._ip_to_instance[nic['ip']] = iname + params = objects.FillDict(c_nparams, nic['nicparams']) + if not params['link'] in self._inst_ips_by_link: + self._inst_ips_by_link[params['link']] = [] + self._ip_to_inst_by_link[params['link']] = {} + self._ip_to_inst_by_link[params['link']][nic['ip']] = iname + self._inst_ips_by_link[params['link']].append(nic['ip']) + + self._nodes_primary_ips = [] + self._mc_primary_ips = [] + for node_name in self._config_data["nodes"]: + node = self._config_data["nodes"][node_name] + self._nodes_primary_ips.append(node["primary_ip"]) + if node["master_candidate"]: + self._mc_primary_ips.append(node["primary_ip"]) return True @@ -139,6 +162,12 @@ class SimpleConfigReader(object): def GetClusterSerialNo(self): return self._config_data["cluster"]["serial_no"] + def GetDefaultNicParams(self): + return self._config_data["cluster"]["nicparams"][constants.PP_DEFAULT] + + def GetDefaultNicLink(self): + return self.GetDefaultNicParams()[constants.NIC_LINK] + def GetNodeStatusFlags(self, node): """Get a node's status flags @@ -156,10 +185,24 @@ class SimpleConfigReader(object): offline = self._config_data["nodes"][node]["offline"] return master_candidate, drained, offline - def GetInstanceByIp(self, ip): - if ip not in self._ip_to_instance: + def GetInstanceByLinkIp(self, ip, link): + """Get instance name from its link and ip address. + + @type ip: string + @param ip: ip address + @type link: string + @param link: nic link + @rtype: string + @return: instance name + + """ + if not link: + link = self.GetDefaultNicLink() + if not link in self._ip_to_inst_by_link: return None - return self._ip_to_instance[ip] + if not ip in self._ip_to_inst_by_link[link]: + return None + return self._ip_to_inst_by_link[link][ip] def GetNodePrimaryIp(self, node): """Get a node's primary ip @@ -187,6 +230,29 @@ class SimpleConfigReader(object): return None return self._config_data["instances"][instance]["primary_node"] + def GetNodesPrimaryIps(self): + return self._nodes_primary_ips + + def GetMasterCandidatesPrimaryIps(self): + return self._mc_primary_ips + + def GetInstancesIps(self, link): + """Get list of nic ips connected to a certain link. + + @type link: string + @param link: nic link + @rtype: list + @return: list of ips connected to that link + + """ + if not link: + link = self.GetDefaultNicLink() + + if link in self._inst_ips_by_link: + return self._inst_ips_by_link[link] + else: + return [] + class SimpleStore(object): """Interface to static cluster data. @@ -216,6 +282,9 @@ class SimpleStore(object): constants.SS_ONLINE_NODES, constants.SS_INSTANCE_LIST, constants.SS_RELEASE_VERSION, + constants.SS_HYPERVISOR_LIST, + constants.SS_MAINTAIN_NODE_HEALTH, + constants.SS_UID_POOL, ) _MAX_SIZE = 131072 @@ -259,7 +328,7 @@ class SimpleStore(object): @param values: Dictionary of (name, value) """ - ssconf_lock = utils.FileLock(constants.SSCONF_LOCK_FILE) + ssconf_lock = utils.FileLock.Open(constants.SSCONF_LOCK_FILE) # Get lock while writing files ssconf_lock.Exclusive(blocking=True, timeout=SSCONF_LOCK_TIMEOUT) @@ -357,6 +426,36 @@ class SimpleStore(object): nl = data.splitlines(False) return nl + def GetHypervisorList(self): + """Return the list of enabled hypervisors. + + """ + data = self._ReadFile(constants.SS_HYPERVISOR_LIST) + nl = data.splitlines(False) + return nl + + def GetMaintainNodeHealth(self): + """Return the value of the maintain_node_health option. + + """ + data = self._ReadFile(constants.SS_MAINTAIN_NODE_HEALTH) + # we rely on the bool serialization here + return data == "True" + + def GetUidPool(self): + """Return the user-id pool definition string. + + The separator character is a newline. + + The return value can be parsed using uidpool.ParseUidPool():: + + ss = ssconf.SimpleStore() + uid_pool = uidpool.ParseUidPool(ss.GetUidPool(), separator="\\n") + + """ + data = self._ReadFile(constants.SS_UID_POOL) + return data + def GetMasterAndMyself(ss=None): """Get the master node and my own hostname. @@ -423,4 +522,3 @@ def CheckMasterCandidate(debug, ss=None): if debug: sys.stderr.write("Not master candidate, exiting.\n") sys.exit(constants.EXIT_NOTCANDIDATE) -