With this patch all RPC calls at runtime of masterd will show up in the
lock monitor. There is a chicken-and-egg issue with initializing the
configuration with a context since the lock manager, containing the
monitor, requires the configuration. This is worked around by setting
the config's context only once the lock monitor is available.

Example:
rpc/node19.example.com/write_ssconf_files  Jq9/Job32/N_SET_PARAMjobqueue_update 
 Jq2/Job27/C_VERIFY_CONFIG

Signed-off-by: Michael Hanselmann <[email protected]>
---
Updated after dropping the patch for a custom resolver in config.

 lib/config.py         |   17 +++++++++++++++--
 lib/rpc.py            |   10 ++++++++--
 lib/server/masterd.py |    2 ++
 3 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/lib/config.py b/lib/config.py
index 3c4d2db..1e6e706 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -164,8 +164,21 @@ class ConfigWriter:
     self._my_hostname = netutils.Hostname.GetSysName()
     self._last_cluster_serial = -1
     self._cfg_id = None
+    self._context = None
     self._OpenConfig(accept_foreign)
 
+  def _GetRpc(self, address_list):
+    """Returns RPC runner for configuration.
+
+    """
+    return rpc.ConfigRunner(self._context, address_list)
+
+  def SetContext(self, context):
+    """Sets Ganeti context.
+
+    """
+    self._context = context
+
   # this method needs to be static, so that we can call it on the class
   @staticmethod
   def IsCluster():
@@ -1748,7 +1761,7 @@ class ConfigWriter:
 
     # TODO: Use dedicated resolver talking to config writer for name resolution
     result = \
-      rpc.ConfigRunner(addr_list).call_upload_file(node_list, self._cfg_file)
+      self._GetRpc(addr_list).call_upload_file(node_list, self._cfg_file)
     for to_node, to_result in result.items():
       msg = to_result.fail_msg
       if msg:
@@ -1807,7 +1820,7 @@ class ConfigWriter:
     # Write ssconf files on all nodes (including locally)
     if self._last_cluster_serial < self._config_data.cluster.serial_no:
       if not self._offline:
-        result = rpc.ConfigRunner(None).call_write_ssconf_files(
+        result = self._GetRpc(None).call_write_ssconf_files(
           self._UnlockedGetOnlineNodeList(),
           self._UnlockedGetSsconfValues())
 
diff --git a/lib/rpc.py b/lib/rpc.py
index ca48478..9626501 100644
--- a/lib/rpc.py
+++ b/lib/rpc.py
@@ -723,15 +723,21 @@ class ConfigRunner(_RpcClientBase, 
_generated_rpc.RpcClientConfig):
   """RPC wrappers for L{config}.
 
   """
-  def __init__(self, address_list):
+  def __init__(self, context, address_list):
     """Initializes this class.
 
     """
+    if context:
+      lock_monitor_cb = context.glm.AddToLockMonitor
+    else:
+      lock_monitor_cb = None
+
     if address_list is None:
       resolver = _SsconfResolver
     else:
       # Caller provided an address list
       resolver = _StaticResolver(address_list)
 
-    _RpcClientBase.__init__(self, resolver, _ENCODERS.get)
+    _RpcClientBase.__init__(self, resolver, _ENCODERS.get,
+                            lock_monitor_cb=lock_monitor_cb)
     _generated_rpc.RpcClientConfig.__init__(self)
diff --git a/lib/server/masterd.py b/lib/server/masterd.py
index cc86d8a..6c32a64 100644
--- a/lib/server/masterd.py
+++ b/lib/server/masterd.py
@@ -401,6 +401,8 @@ class GanetiContext(object):
                 self.cfg.GetNodeGroupList(),
                 self.cfg.GetInstanceList())
 
+    self.cfg.SetContext(self)
+
     # Job queue
     self.jobqueue = jqueue.JobQueue(self)
 
-- 
1.7.6

Reply via email to