From 702abcf921610e953c710a8c0c01c8dd1eb18568 Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Thu, 3 Nov 2011 20:05:42 +0100
Subject: [PATCH] rpc: Use definitions directly instead of via generated code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Until now β€œautotools/build-rpc” would read the definition of all RPCs
and write them to a new file, β€œlib/_generated_rpc.py” with some
modifications. With this patch the generated code loads the definitions
and, at module load time, gets references to the actual definitions.
Further patches will even remove the calls to the post-processing
functions from the generated code.

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>
---
 autotools/build-rpc | 18 +++++++++++-------
 lib/rpc.py          |  7 ++++---
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/autotools/build-rpc b/autotools/build-rpc
index a80491189..0e8d5b93e 100755
--- a/autotools/build-rpc
+++ b/autotools/build-rpc
@@ -52,6 +52,8 @@ def _WritePreamble(sw):
   sw.Write("")
   sw.Write("\"\"\"")
   sw.Write("")
+  sw.Write("from ganeti import rpc_defs")
+  sw.Write("")
 
 
 def _WrapCode(line):
@@ -112,6 +114,9 @@ def _WriteBaseClass(sw, clsname, calls):
       sw.Write("pass")
       return
 
+    sw.Write("_CALLS = rpc_defs.CALLS[%r]", clsname)
+    sw.Write("")
+
     for (name, kind, timeout, args, postproc, desc) in calls:
       funcargs = ["self"]
 
@@ -127,6 +132,8 @@ def _WriteBaseClass(sw, clsname, calls):
       assert "read_timeout" not in funcargs
       funcargs.append("read_timeout=%s" % timeout)
 
+      funcargs.append("_def=_CALLS[%r]" % name)
+
       funcdef = "def call_%s(%s):" % (name, utils.CommaJoin(funcargs))
       for line in _WrapCode(funcdef):
         sw.Write(line)
@@ -143,18 +150,15 @@ def _WriteBaseClass(sw, clsname, calls):
 
         if postproc:
           buf.write("%s(" % postproc)
-        buf.write("self._Call(")
+        buf.write("self._Call(_def, ")
         if kind == _SINGLE:
           buf.write("[node]")
         else:
           buf.write("node_list")
 
-        buf.write(", \"%s\", read_timeout, [%s], [%s])" %
-                  (name,
-                   # Argument definitions
-                   utils.CommaJoin(map(compat.snd, args)),
-                   # Function arguments
-                   utils.CommaJoin(map(compat.fst, args))))
+        buf.write(", read_timeout, [%s])" %
+                  # Function arguments
+                  utils.CommaJoin(map(compat.fst, args)))
 
         if kind == _SINGLE:
           buf.write("[node]")
diff --git a/lib/rpc.py b/lib/rpc.py
index c117f0cfa..74c924f40 100644
--- a/lib/rpc.py
+++ b/lib/rpc.py
@@ -430,13 +430,14 @@ class _RpcClientBase:
     else:
       return encoder_fn(argkind)(value)
 
-  def _Call(self, node_list, procedure, timeout, argdefs, args):
+  def _Call(self, cdef, node_list, timeout, args):
     """Entry point for automatically generated RPC wrappers.
 
     """
-    assert len(args) == len(argdefs), "Wrong number of arguments"
+    (procedure, _, _, argdefs, _, _) = cdef
 
-    body = serializer.DumpJson(map(self._encoder, zip(argdefs, args)),
+    body = serializer.DumpJson(map(self._encoder,
+                                   zip(map(compat.snd, argdefs), args)),
                                indent=False)
 
     return self._proc(node_list, procedure, body, read_timeout=timeout)
-- 
GitLab