Merge branch 'stable-2.9' into stable-2.10
[ganeti-local] / lib / hypervisor / hv_kvm.py
index 48a6ab6..3b254e1 100644 (file)
@@ -188,22 +188,45 @@ def _GetExistingDeviceInfo(dev_type, device, runtime):
   return found[0]
 
 
-def _AnalyzeSerializedRuntime(serialized_runtime):
-  """Return runtime entries for a serialized runtime file
+def _UpgradeSerializedRuntime(serialized_runtime):
+  """Upgrade runtime data
+
+  Remove any deprecated fields or change the format of the data.
+  The runtime files are not upgraded when Ganeti is upgraded, so the required
+  modification have to be performed here.
 
   @type serialized_runtime: string
   @param serialized_runtime: raw text data read from actual runtime file
-  @return: (cmd, nics, hvparams, bdevs)
-  @rtype: list
+  @return: (cmd, nic dicts, hvparams, bdev dicts)
+  @rtype: tuple
 
   """
   loaded_runtime = serializer.Load(serialized_runtime)
-  if len(loaded_runtime) == 3:
-    serialized_disks = []
-    kvm_cmd, serialized_nics, hvparams = loaded_runtime
+  kvm_cmd, serialized_nics, hvparams = loaded_runtime[:3]
+  if len(loaded_runtime) >= 4:
+    serialized_disks = loaded_runtime[3]
   else:
-    kvm_cmd, serialized_nics, hvparams, serialized_disks = loaded_runtime
+    serialized_disks = []
+
+  for nic in serialized_nics:
+    # Add a dummy uuid slot if an pre-2.8 NIC is found
+    if "uuid" not in nic:
+      nic["uuid"] = utils.NewUUID()
+
+  return kvm_cmd, serialized_nics, hvparams, serialized_disks
+
 
+def _AnalyzeSerializedRuntime(serialized_runtime):
+  """Return runtime entries for a serialized runtime file
+
+  @type serialized_runtime: string
+  @param serialized_runtime: raw text data read from actual runtime file
+  @return: (cmd, nics, hvparams, bdevs)
+  @rtype: tuple
+
+  """
+  kvm_cmd, serialized_nics, hvparams, serialized_disks = \
+    _UpgradeSerializedRuntime(serialized_runtime)
   kvm_nics = [objects.NIC.FromDict(snic) for snic in serialized_nics]
   kvm_disks = [(objects.Disk.FromDict(sdisk), link, uri)
                for sdisk, link, uri in serialized_disks]
@@ -439,7 +462,6 @@ class QmpConnection(MonitorSocket):
   _RETURN_KEY = RETURN_KEY = "return"
   _ACTUAL_KEY = ACTUAL_KEY = "actual"
   _ERROR_CLASS_KEY = "class"
-  _ERROR_DATA_KEY = "data"
   _ERROR_DESC_KEY = "desc"
   _EXECUTE_KEY = "execute"
   _ARGUMENTS_KEY = "arguments"
@@ -583,11 +605,10 @@ class QmpConnection(MonitorSocket):
       err = response[self._ERROR_KEY]
       if err:
         raise errors.HypervisorError("kvm: error executing the %s"
-                                     " command: %s (%s, %s):" %
+                                     " command: %s (%s):" %
                                      (command,
                                       err[self._ERROR_DESC_KEY],
-                                      err[self._ERROR_CLASS_KEY],
-                                      err[self._ERROR_DATA_KEY]))
+                                      err[self._ERROR_CLASS_KEY]))
 
       elif not response[self._EVENT_KEY]:
         return response
@@ -1007,12 +1028,16 @@ class KVMHypervisor(hv_base.BaseHypervisor):
       "MODE": nic.nicparams[constants.NIC_MODE],
       "INTERFACE": tap,
       "INTERFACE_INDEX": str(seq),
+      "INTERFACE_UUID": nic.uuid,
       "TAGS": " ".join(instance.GetTags()),
     }
 
     if nic.ip:
       env["IP"] = nic.ip
 
+    if nic.name:
+      env["INTERFACE_NAME"] = nic.name
+
     if nic.nicparams[constants.NIC_LINK]:
       env["LINK"] = nic.nicparams[constants.NIC_LINK]
 
@@ -2182,7 +2207,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
     result = utils.RunCmd([kvm_path] + optlist)
     if result.failed and not can_fail:
       raise errors.HypervisorError("Unable to get KVM %s output" %
-                                    " ".join(cls._KVMOPTS_CMDS[option]))
+                                    " ".join(optlist))
     return result.output
 
   @classmethod
@@ -2434,10 +2459,10 @@ class KVMHypervisor(hv_base.BaseHypervisor):
 
     """
     result = self.GetLinuxNodeInfo()
-    # FIXME: this is the global kvm version, but the actual version can be
-    # customized as an hv parameter. we should use the nodegroup's default kvm
-    # path parameter here.
-    _, v_major, v_min, v_rev = self._GetKVMVersion(constants.KVM_PATH)
+    kvmpath = constants.KVM_PATH
+    if hvparams is not None:
+      kvmpath = hvparams.get(constants.HV_KVM_PATH, constants.KVM_PATH)
+    _, v_major, v_min, v_rev = self._GetKVMVersion(kvmpath)
     result[constants.HV_NODEINFO_KEY_VERSION] = (v_major, v_min, v_rev)
     return result
 
@@ -2491,11 +2516,11 @@ class KVMHypervisor(hv_base.BaseHypervisor):
 
     """
     msgs = []
-    # FIXME: this is the global kvm binary, but the actual path can be
-    # customized as an hv parameter; we should use the nodegroup's
-    # default kvm path parameter here.
-    if not os.path.exists(constants.KVM_PATH):
-      msgs.append("The KVM binary ('%s') does not exist" % constants.KVM_PATH)
+    kvmpath = constants.KVM_PATH
+    if hvparams is not None:
+      kvmpath = hvparams.get(constants.HV_KVM_PATH, constants.KVM_PATH)
+    if not os.path.exists(kvmpath):
+      msgs.append("The KVM binary ('%s') does not exist" % kvmpath)
     if not os.path.exists(constants.SOCAT_PATH):
       msgs.append("The socat binary ('%s') does not exist" %
                   constants.SOCAT_PATH)