From 93384844b72970fc8b2c6eb2d9ada4923a457583 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Tue, 2 Dec 2008 05:03:52 +0000
Subject: [PATCH] Revert "Get rid of ssconf"

This partially reverts the "Get rid of ssconf" patch.

It adds back a simpler version of the SimpleStore class, and drops the
WritableSimpleStore class. The new version of the class also has
node_list as a new key, and increases the size of the keys so that big
clusters will fit the node list. Also, the SS_* constants are moved to
constants.py, since the ConfigWriter class will need them too in order
to generate the values dictionary.

It also changes the GetMasterAndMyself function to use the SimpleStore
by default, and the backend._GetConfig to use it too (it has all the
needed keys).

Reviewed-by: imsnah
---
 lib/backend.py   |   8 ++--
 lib/constants.py |   8 ++++
 lib/ssconf.py    | 108 ++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 119 insertions(+), 5 deletions(-)

diff --git a/lib/backend.py b/lib/backend.py
index 5d79743b0..89c1b2b9d 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 865a4be58..47adc84b8 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 9165f128b..2189382b4 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
 
 
-- 
GitLab