X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/b4478d3498056633aa0280ba7afcf5b52e91b2ef..18ffc0fe13aa3c58fdd6926551ebe4569fc0125f:/lib/ssconf.py diff --git a/lib/ssconf.py b/lib/ssconf.py index 07a264a..2eccc59 100644 --- a/lib/ssconf.py +++ b/lib/ssconf.py @@ -1,7 +1,7 @@ # # -# Copyright (C) 2006, 2007, 2008 Google Inc. +# Copyright (C) 2006, 2007, 2008, 2010 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 @@ -29,12 +29,14 @@ configuration data, which is mostly static and available to all nodes. import sys import re import os +import errno from ganeti import errors from ganeti import constants from ganeti import utils from ganeti import serializer from ganeti import objects +from ganeti import netutils SSCONF_LOCK_TIMEOUT = 10 @@ -186,6 +188,16 @@ class SimpleConfigReader(object): return master_candidate, drained, offline 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: @@ -227,6 +239,14 @@ class SimpleConfigReader(object): 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() @@ -262,8 +282,13 @@ class SimpleStore(object): constants.SS_NODE_SECONDARY_IPS, constants.SS_OFFLINE_NODES, constants.SS_ONLINE_NODES, + constants.SS_PRIMARY_IP_FAMILY, constants.SS_INSTANCE_LIST, constants.SS_RELEASE_VERSION, + constants.SS_HYPERVISOR_LIST, + constants.SS_MAINTAIN_NODE_HEALTH, + constants.SS_UID_POOL, + constants.SS_NODEGROUPS, ) _MAX_SIZE = 131072 @@ -284,7 +309,7 @@ class SimpleStore(object): filename = self._cfg_dir + '/' + self._SS_FILEPREFIX + key return filename - def _ReadFile(self, key): + def _ReadFile(self, key, default=None): """Generic routine to read keys. This will read the file which holds the value requested. Errors @@ -295,6 +320,8 @@ class SimpleStore(object): try: data = utils.ReadFile(filename, size=self._MAX_SIZE) except EnvironmentError, err: + if err.errno == errno.ENOENT and default is not None: + return default raise errors.ConfigurationError("Can't read from the ssconf file:" " '%s'" % str(err)) data = data.rstrip('\n') @@ -315,6 +342,9 @@ class SimpleStore(object): for name, value in values.iteritems(): if value and not value.endswith("\n"): value += "\n" + if len(value) > self._MAX_SIZE: + raise errors.ConfigurationError("ssconf file %s above maximum size" % + name) utils.WriteFile(self.KeyToFilename(name), data=value, mode=0444) finally: ssconf_lock.Unlock() @@ -397,6 +427,14 @@ class SimpleStore(object): nl = data.splitlines(False) return nl + def GetNodegroupList(self): + """Return the list of nodegroups. + + """ + data = self._ReadFile(constants.SS_NODEGROUPS) + nl = data.splitlines(False) + return nl + def GetClusterTags(self): """Return the cluster tags. @@ -405,6 +443,47 @@ 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 GetPrimaryIPFamily(self): + """Return the cluster-wide primary address family. + + """ + try: + return int(self._ReadFile(constants.SS_PRIMARY_IP_FAMILY, + default=netutils.IP4Address.family)) + except (ValueError, TypeError), err: + raise errors.ConfigurationError("Error while trying to parse primary ip" + " family: %s" % err) + def GetMasterAndMyself(ss=None): """Get the master node and my own hostname. @@ -423,7 +502,7 @@ def GetMasterAndMyself(ss=None): """ if ss is None: ss = SimpleStore() - return ss.GetMasterNode(), utils.HostInfo().name + return ss.GetMasterNode(), netutils.Hostname.GetSysName() def CheckMaster(debug, ss=None): @@ -446,28 +525,3 @@ def CheckMaster(debug, ss=None): if debug: sys.stderr.write("Not master, exiting.\n") sys.exit(constants.EXIT_NOTMASTER) - - -def CheckMasterCandidate(debug, ss=None): - """Checks the node setup. - - If this is a master candidate, the function will return. Otherwise it will - exit with an exit code based on the node status. - - """ - try: - if ss is None: - ss = SimpleStore() - myself = utils.HostInfo().name - candidates = ss.GetMasterCandidates() - except errors.ConfigurationError, err: - print "Cluster configuration incomplete: '%s'" % str(err) - sys.exit(constants.EXIT_NODESETUP_ERROR) - except errors.ResolverError, err: - sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0]) - sys.exit(constants.EXIT_NODESETUP_ERROR) - - if myself not in candidates: - if debug: - sys.stderr.write("Not master candidate, exiting.\n") - sys.exit(constants.EXIT_NOTCANDIDATE)