Implement BuildHooksEnv for NoHooksLU
[ganeti-local] / lib / rpc.py
index 461c1c8..b1054ca 100644 (file)
@@ -31,7 +31,6 @@
 # R0904: Too many public methods
 
 import os
 # R0904: Too many public methods
 
 import os
-import socket
 import logging
 import zlib
 import base64
 import logging
 import zlib
 import base64
@@ -43,7 +42,8 @@ from ganeti import serializer
 from ganeti import constants
 from ganeti import errors
 
 from ganeti import constants
 from ganeti import errors
 
-import ganeti.http.client
+# pylint has a bug here, doesn't see this import
+import ganeti.http.client  # pylint: disable-msg=W0611
 
 
 # Module level variable
 
 
 # Module level variable
@@ -56,7 +56,7 @@ def Init():
   Must be called before using any RPC function.
 
   """
   Must be called before using any RPC function.
 
   """
-  global _http_manager
+  global _http_manager # pylint: disable-msg=W0603
 
   assert not _http_manager, "RPC module initialized more than once"
 
 
   assert not _http_manager, "RPC module initialized more than once"
 
@@ -69,7 +69,7 @@ def Shutdown():
   Must be called before quitting the program.
 
   """
   Must be called before quitting the program.
 
   """
-  global _http_manager
+  global _http_manager # pylint: disable-msg=W0603
 
   if _http_manager:
     _http_manager.Shutdown()
 
   if _http_manager:
     _http_manager.Shutdown()
@@ -83,7 +83,7 @@ class RpcResult(object):
   calls we can't raise an exception just because one one out of many
   failed, and therefore we use this class to encapsulate the result.
 
   calls we can't raise an exception just because one one out of many
   failed, and therefore we use this class to encapsulate the result.
 
-  @ivar data: the data payload, for successfull results, or None
+  @ivar data: the data payload, for successful results, or None
   @type failed: boolean
   @ivar failed: whether the operation failed at RPC level (not
       application level on the remote node)
   @type failed: boolean
   @ivar failed: whether the operation failed at RPC level (not
       application level on the remote node)
@@ -104,13 +104,17 @@ class RpcResult(object):
     if offline:
       self.failed = True
       self.error = "Node is marked offline"
     if offline:
       self.failed = True
       self.error = "Node is marked offline"
-      self.data = None
+      self.data = self.payload = None
     elif failed:
       self.error = data
     elif failed:
       self.error = data
-      self.data = None
+      self.data = self.payload = None
     else:
       self.data = data
       self.error = 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.
 
   def Raise(self):
     """If the result has failed, raise an OpExecError.
@@ -157,7 +161,7 @@ class Client:
   list of nodes, will contact (in parallel) all nodes, and return a
   dict of results (key: node name, value: result).
 
   list of nodes, will contact (in parallel) all nodes, and return a
   dict of results (key: node name, value: result).
 
-  One current bug is that generic failure is still signalled by
+  One current bug is that generic failure is still signaled by
   'False' result, which is not good. This overloading of values can
   cause bugs.
 
   'False' result, which is not good. This overloading of values can
   cause bugs.
 
@@ -213,10 +217,10 @@ class Client:
     """Call nodes and return results.
 
     @rtype: list
     """Call nodes and return results.
 
     @rtype: list
-    @returns: List of RPC results
+    @return: List of RPC results
 
     """
 
     """
-    assert _http_manager, "RPC module not intialized"
+    assert _http_manager, "RPC module not initialized"
 
     _http_manager.ExecRequests(self.nc.values())
 
 
     _http_manager.ExecRequests(self.nc.values())
 
@@ -256,7 +260,7 @@ class RpcRunner(object):
     self._cfg = cfg
     self.port = utils.GetNodeDaemonPort()
 
     self._cfg = cfg
     self.port = utils.GetNodeDaemonPort()
 
-  def _InstDict(self, instance):
+  def _InstDict(self, instance, hvp=None, bep=None):
     """Convert the given instance to a dict.
 
     This is done via the instance's ToDict() method and additionally
     """Convert the given instance to a dict.
 
     This is done via the instance's ToDict() method and additionally
@@ -264,6 +268,10 @@ class RpcRunner(object):
 
     @type instance: L{objects.Instance}
     @param instance: an Instance object
 
     @type instance: L{objects.Instance}
     @param instance: an Instance object
+    @type hvp: dict or None
+    @param hvp: a dictionary with overridden hypervisor parameters
+    @type bep: dict or None
+    @param bep: a dictionary with overridden backend parameters
     @rtype: dict
     @return: the instance dict, with the hvparams filled with the
         cluster defaults
     @rtype: dict
     @return: the instance dict, with the hvparams filled with the
         cluster defaults
@@ -272,13 +280,17 @@ class RpcRunner(object):
     idict = instance.ToDict()
     cluster = self._cfg.GetClusterInfo()
     idict["hvparams"] = cluster.FillHV(instance)
     idict = instance.ToDict()
     cluster = self._cfg.GetClusterInfo()
     idict["hvparams"] = cluster.FillHV(instance)
+    if hvp is not None:
+      idict["hvparams"].update(hvp)
     idict["beparams"] = cluster.FillBE(instance)
     idict["beparams"] = cluster.FillBE(instance)
+    if bep is not None:
+      idict["beparams"].update(bep)
     return idict
 
   def _ConnectList(self, client, node_list, call):
     """Helper for computing node addresses.
 
     return idict
 
   def _ConnectList(self, client, node_list, call):
     """Helper for computing node addresses.
 
-    @type client: L{Client}
+    @type client: L{ganeti.rpc.Client}
     @param client: a C{Client} instance
     @type node_list: list
     @param node_list: the node list we should connect
     @param client: a C{Client} instance
     @type node_list: list
     @param node_list: the node list we should connect
@@ -308,7 +320,7 @@ class RpcRunner(object):
   def _ConnectNode(self, client, node, call):
     """Helper for computing one node's address.
 
   def _ConnectNode(self, client, node, call):
     """Helper for computing one node's address.
 
-    @type client: L{Client}
+    @type client: L{ganeti.rpc.Client}
     @param client: a C{Client} instance
     @type node: str
     @param node: the node we should connect
     @param client: a C{Client} instance
     @type node: str
     @param node: the node we should connect
@@ -421,14 +433,14 @@ class RpcRunner(object):
     """
     return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
 
     """
     return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
 
-  def call_instance_start(self, node, instance, extra_args):
+  def call_instance_start(self, node, instance, hvp, bep):
     """Starts an instance.
 
     This is a single-node call.
 
     """
     """Starts an instance.
 
     This is a single-node call.
 
     """
-    return self._SingleNodeCall(node, "instance_start",
-                                [self._InstDict(instance), extra_args])
+    idict = self._InstDict(instance, hvp=hvp, bep=bep)
+    return self._SingleNodeCall(node, "instance_start", [idict])
 
   def call_instance_shutdown(self, node, instance):
     """Stops an instance.
 
   def call_instance_shutdown(self, node, instance):
     """Stops an instance.
@@ -511,15 +523,14 @@ class RpcRunner(object):
     return self._SingleNodeCall(node, "instance_migrate",
                                 [self._InstDict(instance), target, live])
 
     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",
     """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.
 
   def call_instance_os_add(self, node, inst):
     """Installs an OS on the given instance.
@@ -671,14 +682,14 @@ class RpcRunner(object):
                                [checkdict, cluster_name])
 
   @classmethod
                                [checkdict, cluster_name])
 
   @classmethod
-  def call_node_start_master(cls, node, start_daemons):
+  def call_node_start_master(cls, node, start_daemons, no_voting):
     """Tells a node to activate itself as a master.
 
     This is a single-node call.
 
     """
     return cls._StaticSingleNodeCall(node, "node_start_master",
     """Tells a node to activate itself as a master.
 
     This is a single-node call.
 
     """
     return cls._StaticSingleNodeCall(node, "node_start_master",
-                                     [start_daemons])
+                                     [start_daemons, no_voting])
 
   @classmethod
   def call_node_stop_master(cls, node, stop_daemons):
 
   @classmethod
   def call_node_stop_master(cls, node, stop_daemons):
@@ -796,6 +807,15 @@ class RpcRunner(object):
     params = [instance_name, [cf.ToDict() for cf in disks]]
     return self._SingleNodeCall(node, "blockdev_close", params)
 
     params = [instance_name, [cf.ToDict() for cf in disks]]
     return self._SingleNodeCall(node, "blockdev_close", params)
 
+  def call_blockdev_getsizes(self, node, disks):
+    """Returns the size of the given disks.
+
+    This is a single-node call.
+
+    """
+    params = [[cf.ToDict() for cf in disks]]
+    return self._SingleNodeCall(node, "blockdev_getsize", params)
+
   def call_drbd_disconnect_net(self, node_list, nodes_ip, disks):
     """Disconnects the network of the given drbd devices.
 
   def call_drbd_disconnect_net(self, node_list, nodes_ip, disks):
     """Disconnects the network of the given drbd devices.
 
@@ -948,7 +968,10 @@ class RpcRunner(object):
     """
     flat_disks = []
     for disk in snap_disks:
     """
     flat_disks = []
     for disk in snap_disks:
-      flat_disks.append(disk.ToDict())
+      if isinstance(disk, bool):
+        flat_disks.append(disk)
+      else:
+        flat_disks.append(disk.ToDict())
 
     return self._SingleNodeCall(node, "finalize_export",
                                 [self._InstDict(instance), flat_disks])
 
     return self._SingleNodeCall(node, "finalize_export",
                                 [self._InstDict(instance), flat_disks])