Refactor storage of runtime exclusive storage flag in QA
[ganeti-local] / autotools / build-rpc
index 96007c5..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))
 
@@ -96,16 +101,6 @@ def _WriteDocstring(sw, name, timeout, kind, args, desc):
   sw.Write("\"\"\"")
 
 
-def _MakeArgument((argname, wrapper, _)):
-  """Format argument for function call.
-
-  """
-  if wrapper:
-    return wrapper % argname
-  else:
-    return argname
-
-
 def _WriteBaseClass(sw, clsname, calls):
   """Write RPC wrapper class.
 
@@ -122,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:
@@ -134,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):
@@ -149,21 +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])" %
-                  (name, utils.CommaJoin(map(_MakeArgument, 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()):
@@ -194,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()