From ae5849b5b51b0f740d4891ed0df96e36df535ec7 Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Wed, 1 Oct 2008 17:33:52 +0000
Subject: [PATCH] Add new query to get cluster config values

This can be used to retrieve certain cluster config values from
within clients.

OpDumpClusterConfig was not used anywhere, hence I'm just reusing
it. The way ConfigWriter.DumpConfig returned the configuration
was not thread-safe, anyway (no deepcopy).

Reviewed-by: iustinp
---
 daemons/ganeti-masterd |  5 +++++
 lib/cmdlib.py          | 20 +++++++++++++++++---
 lib/config.py          |  7 -------
 lib/luxi.py            |  4 ++++
 lib/mcpu.py            |  2 +-
 lib/opcodes.py         |  8 ++++----
 6 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/daemons/ganeti-masterd b/daemons/ganeti-masterd
index a1dc48d7a..30d4861bb 100755
--- a/daemons/ganeti-masterd
+++ b/daemons/ganeti-masterd
@@ -240,6 +240,11 @@ class ClientOps:
       op = opcodes.OpQueryExports(nodes=nodes)
       return self._Query(op)
 
+    elif method == luxi.REQ_QUERY_CONFIG_VALUES:
+      fields = args
+      op = opcodes.OpQueryConfigValues(output_fields=fields)
+      return self._Query(op)
+
     else:
       raise ValueError("Invalid operation")
 
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 4822f5425..f9b09b980 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -1859,8 +1859,8 @@ class LUQueryClusterInfo(NoHooksLU):
     return result
 
 
-class LUDumpClusterConfig(NoHooksLU):
-  """Return a text-representation of the cluster-config.
+class LUQueryConfigValues(NoHooksLU):
+  """Return configuration values.
 
   """
   _OP_REQP = []
@@ -1869,6 +1869,11 @@ class LUDumpClusterConfig(NoHooksLU):
   def ExpandNames(self):
     self.needed_locks = {}
 
+    static_fields = ["cluster_name", "master_node"]
+    _CheckOutputFields(static=static_fields,
+                       dynamic=[],
+                       selected=self.op.output_fields)
+
   def CheckPrereq(self):
     """No prerequisites.
 
@@ -1879,7 +1884,15 @@ class LUDumpClusterConfig(NoHooksLU):
     """Dump a representation of the cluster config to the standard output.
 
     """
-    return self.cfg.DumpConfig()
+    values = []
+    for field in self.op.output_fields:
+      if field == "cluster_name":
+        values.append(self.cfg.GetClusterName())
+      elif field == "master_node":
+        values.append(self.cfg.GetMasterNode())
+      else:
+        raise errors.ParameterError(field)
+    return values
 
 
 class LUActivateInstanceDisks(NoHooksLU):
@@ -4271,6 +4284,7 @@ class LUQueryInstanceData(NoHooksLU):
   """
   _OP_REQP = ["instances"]
   REQ_BGL = False
+
   def ExpandNames(self):
     self.needed_locks = {}
     self.share_locks = dict(((i, 1) for i in locking.LEVELS))
diff --git a/lib/config.py b/lib/config.py
index 403137363..00e307abb 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -814,13 +814,6 @@ class ConfigWriter:
                     for node in self._UnlockedGetNodeList()])
     return my_dict
 
-  @locking.ssynchronized(_config_lock, shared=1)
-  def DumpConfig(self):
-    """Return the entire configuration of the cluster.
-    """
-    self._OpenConfig()
-    return self._config_data
-
   def _BumpSerialNo(self):
     """Bump up the serial number of the config.
 
diff --git a/lib/luxi.py b/lib/luxi.py
index f04aee76d..a0e2c1653 100644
--- a/lib/luxi.py
+++ b/lib/luxi.py
@@ -51,6 +51,7 @@ REQ_QUERY_JOBS = "QueryJobs"
 REQ_QUERY_INSTANCES = "QueryInstances"
 REQ_QUERY_NODES = "QueryNodes"
 REQ_QUERY_EXPORTS = "QueryExports"
+REQ_QUERY_CONFIG_VALUES = "QueryConfigValues"
 
 DEF_CTMO = 10
 DEF_RWTO = 60
@@ -311,4 +312,7 @@ class Client(object):
   def QueryExports(self, nodes):
     return self.CallMethod(REQ_QUERY_EXPORTS, nodes)
 
+  def QueryConfigValues(self, fields):
+    return self.CallMethod(REQ_QUERY_CONFIG_VALUES, fields)
+
 # TODO: class Server(object)
diff --git a/lib/mcpu.py b/lib/mcpu.py
index 7bb4866a3..ff5b856ac 100644
--- a/lib/mcpu.py
+++ b/lib/mcpu.py
@@ -46,7 +46,7 @@ class Processor(object):
     opcodes.OpDestroyCluster: cmdlib.LUDestroyCluster,
     opcodes.OpQueryClusterInfo: cmdlib.LUQueryClusterInfo,
     opcodes.OpVerifyCluster: cmdlib.LUVerifyCluster,
-    opcodes.OpDumpClusterConfig: cmdlib.LUDumpClusterConfig,
+    opcodes.OpQueryConfigValues: cmdlib.LUQueryConfigValues,
     opcodes.OpRenameCluster: cmdlib.LURenameCluster,
     opcodes.OpVerifyDisks: cmdlib.LUVerifyDisks,
     opcodes.OpSetClusterParams: cmdlib.LUSetClusterParams,
diff --git a/lib/opcodes.py b/lib/opcodes.py
index fda1f6d8e..b0ee9f9af 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -227,10 +227,10 @@ class OpVerifyDisks(OpCode):
   __slots__ = []
 
 
-class OpDumpClusterConfig(OpCode):
-  """Dump the cluster configuration."""
-  OP_ID = "OP_CLUSTER_DUMPCONFIG"
-  __slots__ = []
+class OpQueryConfigValues(OpCode):
+  """Query cluster configuration values."""
+  OP_ID = "OP_CLUSTER_CONFIG_QUERY"
+  __slots__ = ["output_fields"]
 
 
 class OpRenameCluster(OpCode):
-- 
GitLab