commit 93384844b72970fc8b2c6eb2d9ada4923a457583
Author: Iustin Pop <iustin@google.com>
Date:   Tue Dec 2 05:03:52 2008 +0000

    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

diff --git a/lib/backend.py b/lib/backend.py
index 5d79743..89c1b2b 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 865a4be..47adc84 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 9165f12..2189382 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
 
 
