Disable synchronous (locking) queries
[ganeti-local] / lib / rpc.py
index 05613ef..70dd312 100644 (file)
@@ -104,13 +104,17 @@ class RpcResult(object):
     if offline:
       self.failed = True
       self.error = "Node is marked offline"
-      self.data = None
+      self.data = self.payload = None
     elif failed:
       self.error = data
-      self.data = None
+      self.data = self.payload = None
     else:
       self.data = data
       self.error = None
+      if isinstance(data, (tuple, list)) and len(data) == 2:
+        self.payload = data[1]
+      else:
+        self.payload = None
 
   def Raise(self):
     """If the result has failed, raise an OpExecError.
@@ -213,7 +217,7 @@ class Client:
     """Call nodes and return results.
 
     @rtype: list
-    @returns: List of RPC results
+    @return: List of RPC results
 
     """
     assert _http_manager, "RPC module not intialized"
@@ -275,13 +279,16 @@ class RpcRunner(object):
     idict["beparams"] = cluster.FillBE(instance)
     return idict
 
-  def _ConnectList(self, client, node_list):
+  def _ConnectList(self, client, node_list, call):
     """Helper for computing node addresses.
 
     @type client: L{Client}
     @param client: a C{Client} instance
     @type node_list: list
     @param node_list: the node list we should connect
+    @type call: string
+    @param call: the name of the remote procedure call, for filling in
+        correctly any eventual offline nodes' results
 
     """
     all_nodes = self._cfg.GetAllNodesInfo()
@@ -291,7 +298,7 @@ class RpcRunner(object):
     for node in node_list:
       if node in all_nodes:
         if all_nodes[node].offline:
-          skip_dict[node] = RpcResult(node=node, offline=True)
+          skip_dict[node] = RpcResult(node=node, offline=True, call=call)
           continue
         val = all_nodes[node].primary_ip
       else:
@@ -302,19 +309,22 @@ class RpcRunner(object):
       client.ConnectList(name_list, address_list=addr_list)
     return skip_dict
 
-  def _ConnectNode(self, client, node):
+  def _ConnectNode(self, client, node, call):
     """Helper for computing one node's address.
 
     @type client: L{Client}
     @param client: a C{Client} instance
     @type node: str
     @param node: the node we should connect
+    @type call: string
+    @param call: the name of the remote procedure call, for filling in
+        correctly any eventual offline nodes' results
 
     """
     node_info = self._cfg.GetNodeInfo(node)
     if node_info is not None:
       if node_info.offline:
-        return RpcResult(node=node, offline=True)
+        return RpcResult(node=node, offline=True, call=call)
       addr = node_info.primary_ip
     else:
       addr = None
@@ -326,7 +336,7 @@ class RpcRunner(object):
     """
     body = serializer.DumpJson(args, indent=False)
     c = Client(procedure, body, self.port)
-    skip_dict = self._ConnectList(c, node_list)
+    skip_dict = self._ConnectList(c, node_list, procedure)
     skip_dict.update(c.GetResults())
     return skip_dict
 
@@ -347,7 +357,7 @@ class RpcRunner(object):
     """
     body = serializer.DumpJson(args, indent=False)
     c = Client(procedure, body, self.port)
-    result = self._ConnectNode(c, node)
+    result = self._ConnectNode(c, node, procedure)
     if result is None:
       # we did connect, node is not offline
       result = c.GetResults()[node]
@@ -415,14 +425,14 @@ class RpcRunner(object):
     """
     return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
 
-  def call_instance_start(self, node, instance, extra_args):
+  def call_instance_start(self, node, instance):
     """Starts an instance.
 
     This is a single-node call.
 
     """
     return self._SingleNodeCall(node, "instance_start",
-                                [self._InstDict(instance), extra_args])
+                                [self._InstDict(instance)])
 
   def call_instance_shutdown(self, node, instance):
     """Stops an instance.
@@ -505,15 +515,14 @@ class RpcRunner(object):
     return self._SingleNodeCall(node, "instance_migrate",
                                 [self._InstDict(instance), target, live])
 
-  def call_instance_reboot(self, node, instance, reboot_type, extra_args):
+  def call_instance_reboot(self, node, instance, reboot_type):
     """Reboots an instance.
 
     This is a single-node call.
 
     """
     return self._SingleNodeCall(node, "instance_reboot",
-                                [self._InstDict(instance), reboot_type,
-                                 extra_args])
+                                [self._InstDict(instance), reboot_type])
 
   def call_instance_os_add(self, node, inst):
     """Installs an OS on the given instance.