diff --git a/lib/backend.py b/lib/backend.py index 5d79743b02c56f0da1ff9ae71b95a8e92e749d80..89c1b2b9db115236250cba3ad3ae92a747ea8bf1 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -45,13 +45,13 @@ from ganeti import ssconf def _GetConfig(): - """Simple wrapper to return a ConfigReader. + """Simple wrapper to return a SimpleStore. - @rtype: L{ssconf.SimpleConfigReader} - @return: a SimpleConfigReader instance + @rtype: L{ssconf.SimpleStore} + @return: a SimpleStore instance """ - return ssconf.SimpleConfigReader() + return ssconf.SimpleStore() def _GetSshRunner(cluster_name): diff --git a/lib/constants.py b/lib/constants.py index 865a4be5832a372b11ee393f28caf9cebe282295..47adc84b8a5105558c01770b28a020034f5704f5 100644 --- a/lib/constants.py +++ b/lib/constants.py @@ -379,6 +379,14 @@ RAPI_PORT = 5080 MAX_NICS = 8 MAX_DISKS = 16 +# SSCONF keys +SS_CLUSTER_NAME = "cluster_name" +SS_FILE_STORAGE_DIR = "file_storage_dir" +SS_MASTER_IP = "master_ip" +SS_MASTER_NETDEV = "master_netdev" +SS_MASTER_NODE = "master_node" +SS_NODE_LIST = "node_list" + # cluster wide default parameters DEFAULT_ENABLED_HYPERVISOR = HT_XEN_PVM diff --git a/lib/ssconf.py b/lib/ssconf.py index 9165f128b2effbfdd7a695a1b53c29e84217b21a..2189382b412a85e7dfb22ccdde3df2ee7aaa266f 100644 --- a/lib/ssconf.py +++ b/lib/ssconf.py @@ -112,6 +112,112 @@ class SimpleConfigWriter(SimpleConfigReader): mode=0600) +class SimpleStore(object): + """Interface to static cluster data. + + This is different that the config.ConfigWriter and + SimpleConfigReader classes in that it holds data that will always be + present, even on nodes which don't have all the cluster data. + + Other particularities of the datastore: + - keys are restricted to predefined values + + """ + _SS_FILEPREFIX = "ssconf_" + _VALID_KEYS = ( + constants.SS_CLUSTER_NAME, + constants.SS_FILE_STORAGE_DIR, + constants.SS_MASTER_IP, + constants.SS_MASTER_NETDEV, + constants.SS_MASTER_NODE, + constants.SS_NODE_LIST, + ) + _MAX_SIZE = 131072 + + def __init__(self, cfg_location=None): + if cfg_location is None: + self._cfg_dir = constants.DATA_DIR + else: + self._cfg_dir = cfg_location + + def KeyToFilename(self, key): + """Convert a given key into filename. + + """ + if key not in self._VALID_KEYS: + raise errors.ProgrammerError("Invalid key requested from SSConf: '%s'" + % str(key)) + + filename = self._cfg_dir + '/' + self._SS_FILEPREFIX + key + return filename + + def _ReadFile(self, key): + """Generic routine to read keys. + + This will read the file which holds the value requested. Errors + will be changed into ConfigurationErrors. + + """ + filename = self.KeyToFilename(key) + try: + fh = file(filename, 'r') + try: + data = fh.read(self._MAX_SIZE) + data = data.rstrip('\n') + finally: + fh.close() + except EnvironmentError, err: + raise errors.ConfigurationError("Can't read from the ssconf file:" + " '%s'" % str(err)) + return data + + def GetFileList(self): + """Return the list of all config files. + + This is used for computing node replication data. + + """ + return [self.KeyToFilename(key) for key in self._VALID_KEYS] + + def GetClusterName(self): + """Get the cluster name. + + """ + return self._ReadFile(constants.SS_CLUSTER_NAME) + + def GetFileStorageDir(self): + """Get the file storage dir. + + """ + return self._ReadFile(constants.SS_FILE_STORAGE_DIR) + + def GetMasterIP(self): + """Get the IP of the master node for this cluster. + + """ + return self._ReadFile(constants.SS_MASTER_IP) + + def GetMasterNetdev(self): + """Get the netdev to which we'll add the master ip. + + """ + return self._ReadFile(constants.SS_MASTER_NETDEV) + + def GetMasterNode(self): + """Get the hostname of the master node for this cluster. + + """ + return self._ReadFile(constants.SS_MASTER_NODE) + + def GetNodeList(self): + """Return the list of cluster nodes. + + """ + data = self._ReadFile(constants.SS_NODE_LIST) + nl = data.splitlines(False) + return nl + + def _SsconfPath(name): if not RE_VALID_SSCONF_NAME.match(name): raise errors.ParameterError("Invalid ssconf name: %s" % name) @@ -150,7 +256,7 @@ def GetMasterAndMyself(ss=None): """ if ss is None: - ss = SimpleConfigReader() + ss = SimpleStore() return ss.GetMasterNode(), utils.HostInfo().name