Refactor storage of runtime exclusive storage flag in QA
[ganeti-local] / autotools / build-rpc
index e3b17da..2de71d5 100755 (executable)
@@ -40,6 +40,9 @@ from ganeti import build
 _SINGLE = "single-node"
 _MULTI = "multi-node"
 
+#: Expected length of a rpc definition
+_RPC_DEF_LEN = 8
+
 
 def _WritePreamble(sw):
   """Writes a preamble for the RPC wrapper output.
@@ -52,6 +55,8 @@ def _WritePreamble(sw):
   sw.Write("")
   sw.Write("\"\"\"")
   sw.Write("")
+  sw.Write("from ganeti import rpc_defs")
+  sw.Write("")
 
 
 def _WrapCode(line):
@@ -75,7 +80,7 @@ def _WriteDocstring(sw, name, timeout, kind, args, desc):
     sw.Write("")
 
   note = ["This is a %s call" % kind]
-  if timeout:
+  if timeout and not callable(timeout):
     note.append(" with a timeout of %s" % utils.FormatSeconds(timeout))
   sw.Write("@note: %s", "".join(note))
 
@@ -112,7 +117,15 @@ def _WriteBaseClass(sw, clsname, calls):
       sw.Write("pass")
       return
 
-    for (name, kind, timeout, args, postproc, desc) in calls:
+    sw.Write("_CALLS = rpc_defs.CALLS[%r]", clsname)
+    sw.Write("")
+
+    for v in calls:
+      if len(v) != _RPC_DEF_LEN:
+        raise ValueError("Procedure %s has only %d elements, expected %d" %
+                         (v[0], len(v), _RPC_DEF_LEN))
+
+    for (name, kind, _, timeout, args, _, _, desc) in sorted(calls):
       funcargs = ["self"]
 
       if kind == _SINGLE:
@@ -124,8 +137,7 @@ def _WriteBaseClass(sw, clsname, calls):
 
       funcargs.extend(map(compat.fst, args))
 
-      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):
@@ -139,27 +151,20 @@ def _WriteBaseClass(sw, clsname, calls):
         buf.write("return ")
 
         # In case line gets too long and is wrapped in a bad spot
-        buf.write("( ")
+        buf.write("(")
 
-        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(", [%s])" %
+                  # Function arguments
+                  utils.CommaJoin(map(compat.fst, args)))
 
         if kind == _SINGLE:
           buf.write("[node]")
-        if postproc:
-          buf.write(")")
         buf.write(")")
 
         for line in _WrapCode(buf.getvalue()):
@@ -190,8 +195,14 @@ def main():
     assert module.SINGLE == _SINGLE
     assert module.MULTI == _MULTI
 
-    for (clsname, calls) in module.CALLS.items():
-      _WriteBaseClass(sw, clsname, calls)
+    dups = utils.FindDuplicates(itertools.chain(*map(lambda value: value.keys(),
+                                                     module.CALLS.values())))
+    if dups:
+      raise Exception("Found duplicate RPC definitions for '%s'" %
+                      utils.CommaJoin(sorted(dups)))
+
+    for (clsname, calls) in sorted(module.CALLS.items()):
+      _WriteBaseClass(sw, clsname, calls.values())
 
   print buf.getvalue()