commit 0bbec3afa3443db71a0069465ff3db2229e99740
Author: Helga Velroyen <helgav@google.com>
Date:   Thu Jun 6 16:22:11 2013 +0200

    Use hvparams in GetInstanceInfo
    
    This patch extends the GetInstanceInfo function of the
    hypervisors by an hvparams parameters. This leads to
    an extension of the instance_info RPC call and the
    adjustmend of all classes using this call.
    
    Signed-off-by: Helga Velroyen <helgav@google.com>
    Reviewed-by: Thomas Thrainer <thomasth@google.com>

diff --git a/lib/backend.py b/lib/backend.py
index b950910..d2ce85a 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -1273,13 +1273,15 @@ def GetInstanceList(hypervisor_list, all_hvparams=None,
   return results
 
 
-def GetInstanceInfo(instance, hname):
+def GetInstanceInfo(instance, hname, hvparams=None):
   """Gives back the information about an instance as a dictionary.
 
   @type instance: string
   @param instance: the instance name
   @type hname: string
   @param hname: the hypervisor type of the instance
+  @type hvparams: dict of strings
+  @param hvparams: the instance's hvparams
 
   @rtype: dict
   @return: dictionary with the following keys:
@@ -1291,7 +1293,8 @@ def GetInstanceInfo(instance, hname):
   """
   output = {}
 
-  iinfo = hypervisor.GetHypervisor(hname).GetInstanceInfo(instance)
+  iinfo = hypervisor.GetHypervisor(hname).GetInstanceInfo(instance,
+                                                          hvparams=hvparams)
   if iinfo is not None:
     output["memory"] = iinfo[2]
     output["vcpus"] = iinfo[3]
diff --git a/lib/cmdlib/instance.py b/lib/cmdlib/instance.py
index f0cf2aa..d77ba68 100644
--- a/lib/cmdlib/instance.py
+++ b/lib/cmdlib/instance.py
@@ -2704,8 +2704,8 @@ class LUInstanceSetParams(LogicalUnit):
     if (self.op.pnode is not None and self.op.pnode != pnode and
         not self.op.force):
       # verify that the instance is not up
-      instance_info = self.rpc.call_instance_info(pnode, instance.name,
-                                                  instance.hypervisor)
+      instance_info = self.rpc.call_instance_info(
+          pnode, instance.name, instance.hypervisor, instance.hvparams)
       if instance_info.fail_msg:
         self.warn.append("Can't get instance runtime information: %s" %
                          instance_info.fail_msg)
@@ -2820,8 +2820,7 @@ class LUInstanceSetParams(LogicalUnit):
         # either we changed auto_balance to yes or it was from before
         mem_check_list.extend(instance.secondary_nodes)
       instance_info = self.rpc.call_instance_info(
-          pnode, instance.name, instance.hypervisor,
-          cluster.hvparams[instance.hypervisor])
+          pnode, instance.name, instance.hypervisor, instance.hvparams)
       hvspecs = [(instance.hypervisor, cluster.hvparams[instance.hypervisor])]
       nodeinfo = self.rpc.call_node_info(mem_check_list, None,
                                          hvspecs, False)
@@ -2876,9 +2875,9 @@ class LUInstanceSetParams(LogicalUnit):
                                        errors.ECODE_STATE)
 
     if self.op.runtime_mem:
-      remote_info = self.rpc.call_instance_info(instance.primary_node,
-                                                instance.name,
-                                                instance.hypervisor)
+      remote_info = self.rpc.call_instance_info(
+         instance.primary_node, instance.name, instance.hypervisor,
+         instance.hvparams)
       remote_info.Raise("Error checking node %s" % instance.primary_node)
       if not remote_info.payload: # not running already
         raise errors.OpPrereqError("Instance %s is not running" %
diff --git a/lib/cmdlib/instance_migration.py b/lib/cmdlib/instance_migration.py
index 04edbec..8af6ae8 100644
--- a/lib/cmdlib/instance_migration.py
+++ b/lib/cmdlib/instance_migration.py
@@ -427,9 +427,9 @@ class TLMigrateInstance(Tasklet):
       self.live = False
 
     if not (self.failover or self.cleanup):
-      remote_info = self.rpc.call_instance_info(instance.primary_node,
-                                                instance.name,
-                                                instance.hypervisor)
+      remote_info = self.rpc.call_instance_info(
+          instance.primary_node, instance.name, instance.hypervisor,
+          cluster.hvparams[instance.hypervisor])
       remote_info.Raise("Error checking instance on node %s" %
                         instance.primary_node)
       instance_running = bool(remote_info.payload)
diff --git a/lib/cmdlib/instance_operation.py b/lib/cmdlib/instance_operation.py
index b24d220..e9e5eb2 100644
--- a/lib/cmdlib/instance_operation.py
+++ b/lib/cmdlib/instance_operation.py
@@ -98,10 +98,10 @@ class LUInstanceStartup(LogicalUnit):
     assert self.instance is not None, \
       "Cannot retrieve locked instance %s" % self.op.instance_name
 
+    cluster = self.cfg.GetClusterInfo()
     # extra hvparams
     if self.op.hvparams:
       # check hypervisor parameter syntax (locally)
-      cluster = self.cfg.GetClusterInfo()
       utils.ForceDictType(self.op.hvparams, constants.HVS_PARAMETER_TYPES)
       filled_hvp = cluster.FillHV(instance)
       filled_hvp.update(self.op.hvparams)
@@ -127,9 +127,9 @@ class LUInstanceStartup(LogicalUnit):
       # check bridges existence
       CheckInstanceBridgesExist(self, instance)
 
-      remote_info = self.rpc.call_instance_info(instance.primary_node,
-                                                instance.name,
-                                                instance.hypervisor)
+      remote_info = self.rpc.call_instance_info(
+          instance.primary_node, instance.name, instance.hypervisor,
+          cluster.hvparams[instance.hypervisor])
       remote_info.Raise("Error checking node %s" % instance.primary_node,
                         prereq=True, ecode=errors.ECODE_ENVIRON)
       if not remote_info.payload: # not running already
@@ -392,9 +392,10 @@ class LUInstanceReboot(LogicalUnit):
     reboot_type = self.op.reboot_type
     reason = self.op.reason
 
-    remote_info = self.rpc.call_instance_info(instance.primary_node,
-                                              instance.name,
-                                              instance.hypervisor)
+    cluster = self.cfg.GetClusterInfo()
+    remote_info = self.rpc.call_instance_info(
+        instance.primary_node, instance.name, instance.hypervisor,
+        cluster.hvparams[instance.hypervisor])
     remote_info.Raise("Error checking node %s" % instance.primary_node)
     instance_running = bool(remote_info.payload)
 
diff --git a/lib/cmdlib/instance_query.py b/lib/cmdlib/instance_query.py
index 24b5613..13923cd 100644
--- a/lib/cmdlib/instance_query.py
+++ b/lib/cmdlib/instance_query.py
@@ -383,9 +383,9 @@ class LUInstanceQueryData(NoHooksLU):
                           " information only for instance %s" %
                           (pnode.name, instance.name))
       else:
-        remote_info = self.rpc.call_instance_info(instance.primary_node,
-                                                  instance.name,
-                                                  instance.hypervisor)
+        remote_info = self.rpc.call_instance_info(
+            instance.primary_node, instance.name, instance.hypervisor,
+            cluster.hvparams[instance.hypervisor])
         remote_info.Raise("Error checking node %s" % instance.primary_node)
         remote_info = remote_info.payload
         if remote_info and "state" in remote_info:
diff --git a/lib/hypervisor/hv_base.py b/lib/hypervisor/hv_base.py
index 2ca422d..451a452 100644
--- a/lib/hypervisor/hv_base.py
+++ b/lib/hypervisor/hv_base.py
@@ -210,11 +210,13 @@ class BaseHypervisor(object):
     """Get the list of running instances."""
     raise NotImplementedError
 
-  def GetInstanceInfo(self, instance_name):
+  def GetInstanceInfo(self, instance_name, hvparams=None):
     """Get instance properties.
 
     @type instance_name: string
     @param instance_name: the instance name
+    @type hvparams: dict of strings
+    @param hvparams: hvparams to be used with this instance
 
     @return: tuple (name, id, memory, vcpus, state, times)
 
@@ -371,7 +373,7 @@ class BaseHypervisor(object):
     """
     raise NotImplementedError
 
-  def _InstanceStartupMemory(self, instance):
+  def _InstanceStartupMemory(self, instance, hvparams=None):
     """Get the correct startup memory for an instance
 
     This function calculates how much memory an instance should be started
@@ -384,7 +386,7 @@ class BaseHypervisor(object):
     @return: memory the instance should be started with
 
     """
-    free_memory = self.GetNodeInfo()["memory_free"]
+    free_memory = self.GetNodeInfo(hvparams=hvparams)["memory_free"]
     max_start_mem = min(instance.beparams[constants.BE_MAXMEM], free_memory)
     start_mem = max(instance.beparams[constants.BE_MINMEM], max_start_mem)
     return start_mem
diff --git a/lib/hypervisor/hv_chroot.py b/lib/hypervisor/hv_chroot.py
index 5d6c21c..c6a4112 100644
--- a/lib/hypervisor/hv_chroot.py
+++ b/lib/hypervisor/hv_chroot.py
@@ -109,11 +109,13 @@ class ChrootManager(hv_base.BaseHypervisor):
     return [name for name in os.listdir(self._ROOT_DIR)
             if self._IsDirLive(utils.PathJoin(self._ROOT_DIR, name))]
 
-  def GetInstanceInfo(self, instance_name):
+  def GetInstanceInfo(self, instance_name, hvparams=None):
     """Get instance properties.
 
     @type instance_name: string
     @param instance_name: the instance name
+    @type hvparams: dict of strings
+    @param hvparams: hvparams to be used with this instance
 
     @return: (name, id, memory, vcpus, stat, times)
 
diff --git a/lib/hypervisor/hv_fake.py b/lib/hypervisor/hv_fake.py
index e939f68..34f8cf8 100644
--- a/lib/hypervisor/hv_fake.py
+++ b/lib/hypervisor/hv_fake.py
@@ -56,10 +56,13 @@ class FakeHypervisor(hv_base.BaseHypervisor):
     """
     return os.listdir(self._ROOT_DIR)
 
-  def GetInstanceInfo(self, instance_name):
+  def GetInstanceInfo(self, instance_name, hvparams=None):
     """Get instance properties.
 
+    @type instance_name: string
     @param instance_name: the instance name
+    @type hvparams: dict of strings
+    @param hvparams: hvparams to be used with this instance
 
     @return: tuple of (name, id, memory, vcpus, stat, times)
 
diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index 057df47..d804cd4 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -974,11 +974,13 @@ class KVMHypervisor(hv_base.BaseHypervisor):
         result.append(name)
     return result
 
-  def GetInstanceInfo(self, instance_name):
+  def GetInstanceInfo(self, instance_name, hvparams=None):
     """Get instance properties.
 
     @type instance_name: string
     @param instance_name: the instance name
+    @type hvparams: dict of strings
+    @param hvparams: hvparams to be used with this instance
     @rtype: tuple of strings
     @return: (name, id, memory, vcpus, stat, times)
 
diff --git a/lib/hypervisor/hv_lxc.py b/lib/hypervisor/hv_lxc.py
index 12d48ee..b9200f8 100644
--- a/lib/hypervisor/hv_lxc.py
+++ b/lib/hypervisor/hv_lxc.py
@@ -163,11 +163,13 @@ class LXCHypervisor(hv_base.BaseHypervisor):
     """
     return [iinfo[0] for iinfo in self.GetAllInstancesInfo()]
 
-  def GetInstanceInfo(self, instance_name):
+  def GetInstanceInfo(self, instance_name, hvparams=None):
     """Get instance properties.
 
     @type instance_name: string
     @param instance_name: the instance name
+    @type hvparams: dict of strings
+    @param hvparams: hvparams to be used with this instance
     @rtype: tuple of strings
     @return: (name, id, memory, vcpus, stat, times)
 
diff --git a/lib/hypervisor/hv_xen.py b/lib/hypervisor/hv_xen.py
index e0d6e7f..23ebc18 100644
--- a/lib/hypervisor/hv_xen.py
+++ b/lib/hypervisor/hv_xen.py
@@ -453,15 +453,19 @@ class XenHypervisor(hv_base.BaseHypervisor):
     names = [info[0] for info in instance_list]
     return names
 
-  def GetInstanceInfo(self, instance_name):
+  def GetInstanceInfo(self, instance_name, hvparams=None):
     """Get instance properties.
 
+    @type instance_name: string
     @param instance_name: the instance name
+    @type hvparams: dict of strings
+    @param hvparams: the instance's hypervisor params
 
     @return: tuple (name, id, memory, vcpus, stat, times)
 
     """
-    instance_list = self._GetInstanceList(instance_name == _DOM0_NAME)
+    instance_list = self._GetInstanceList(instance_name == _DOM0_NAME,
+                                          hvparams=hvparams)
     result = None
     for data in instance_list:
       if data[0] == instance_name:
@@ -495,7 +499,8 @@ class XenHypervisor(hv_base.BaseHypervisor):
     """Start an instance.
 
     """
-    startup_memory = self._InstanceStartupMemory(instance)
+    startup_memory = self._InstanceStartupMemory(instance,
+                                                 hvparams=instance.hvparams)
 
     self._MakeConfigFile(instance, startup_memory, block_devices)
 
@@ -551,7 +556,7 @@ class XenHypervisor(hv_base.BaseHypervisor):
     """Reboot an instance.
 
     """
-    ini_info = self.GetInstanceInfo(instance.name)
+    ini_info = self.GetInstanceInfo(instance.name, hvparams=instance.hvparams)
 
     if ini_info is None:
       raise errors.HypervisorError("Failed to reboot instance %s,"
@@ -564,7 +569,7 @@ class XenHypervisor(hv_base.BaseHypervisor):
                                     result.output))
 
     def _CheckInstance():
-      new_info = self.GetInstanceInfo(instance.name)
+      new_info = self.GetInstanceInfo(instance.name, hvparams=instance.hvparams)
 
       # check if the domain ID has changed or the run time has decreased
       if (new_info is not None and
diff --git a/lib/rpc_defs.py b/lib/rpc_defs.py
index 943994a..88af278 100644
--- a/lib/rpc_defs.py
+++ b/lib/rpc_defs.py
@@ -218,6 +218,7 @@ _INSTANCE_CALLS = [
   ("instance_info", SINGLE, None, constants.RPC_TMO_URGENT, [
     ("instance", None, "Instance name"),
     ("hname", None, "Hypervisor type"),
+    ("hvparams", None, "Hypervisor parameters"),
     ], None, None, "Returns information about a single instance"),
   ("all_instances_info", MULTI, None, constants.RPC_TMO_URGENT, [
     ("hypervisor_list", None, "Hypervisors to query for instances"),
diff --git a/lib/server/noded.py b/lib/server/noded.py
index 71aa741..81ebb1e 100644
--- a/lib/server/noded.py
+++ b/lib/server/noded.py
@@ -682,7 +682,8 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     """Query instance information.
 
     """
-    return backend.GetInstanceInfo(params[0], params[1])
+    (instance_name, hypervisor_name, hvparams) = params
+    return backend.GetInstanceInfo(instance_name, hypervisor_name, hvparams)
 
   @staticmethod
   def perspective_instance_migratable(params):
