Disk paths must be overridable when running the instance inside a safe
virtualized environment because, from the host perserspective, a disk
path will look like:

  
/srv/ganeti/file-storage/<instance>/e0105543-0979-4896-95c1-d2c477fafa9b.file.disk0

but, from the virtualized environment perspesctive, the disk path will
look like:

  /dev/xvda (Xen)
  /dev/vda  (KVM)

Therefore, we must pass the correct '/dev/*' disk paths to the safe
virtualized environment when creating the environment file.

* Extend backend and RPC for export OS to allow disk paths to be
  overridden.

* Override disk paths when running OS scripts from inside the
  virtualized environment.

Signed-off-by: Jose A. Lopes <[email protected]>
---
 lib/backend.py         |  9 ++++++++-
 lib/cmdlib/instance.py | 12 +++++++++---
 lib/rpc_defs.py        |  1 +
 lib/server/noded.py    |  3 ++-
 4 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/lib/backend.py b/lib/backend.py
index f246eb6..67c06e6 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -3876,7 +3876,7 @@ def ValidateOS(required, osname, checks, osparams, 
force_variant):
   return True
 
 
-def ExportOS(instance):
+def ExportOS(instance, disk_paths):
   """Creates a GZIPed tarball with an OS definition and environment.
 
   The archive contains a file with the environment variables needed by
@@ -3885,6 +3885,9 @@ def ExportOS(instance):
   @type instance: L{objects.Instance}
   @param instance: instance for which the OS definition is exported
 
+  @type disk_paths: list of string
+  @param disk_paths: if supplied, it overrides the paths for the second disk
+
   @rtype: string
   @return: filepath of the archive
 
@@ -3902,6 +3905,10 @@ def ExportOS(instance):
           inst_os, temp_dir, result.fail_reason, result.output)
 
   env = OSEnvironment(instance, inst_os)
+
+  for idx, disk_path in enumerate(disk_paths):
+    env["DISK_%d_PATH" % idx] = disk_path
+
   with open(utils.PathJoin(temp_dir, "environment"), "w") as f:
     for var in env:
       f.write(var + "=" + env[var] + "\n")
diff --git a/lib/cmdlib/instance.py b/lib/cmdlib/instance.py
index 4b42483..5174ee7 100644
--- a/lib/cmdlib/instance.py
+++ b/lib/cmdlib/instance.py
@@ -1513,7 +1513,7 @@ class LUInstanceCreate(LogicalUnit):
           result.Warn("Failed to run rename script for %s on node %s" %
                       (self.op.instance_name, self.pnode.name), 
self.LogWarning)
 
-  def UpdateInstanceOsInstallPackage(self, feedback_fn, instance):
+  def UpdateInstanceOsInstallPackage(self, feedback_fn, instance, disk_paths):
     """Updates the OS parameter 'os-install-package' for an instance.
 
     The OS install package is an archive containing an OS definition
@@ -1536,7 +1536,8 @@ class LUInstanceCreate(LogicalUnit):
       feedback_fn("Using OS install package '%s'" %
                   instance.osparams["os-install-package"])
     else:
-      result = self.rpc.call_os_export(instance.primary_node, instance)
+      result = self.rpc.call_os_export(instance.primary_node, instance,
+                                       disk_paths)
       result.Raise("Could not export OS '%s'" % instance.os)
       instance.osparams["os-install-package"] = result.payload
 
@@ -1567,11 +1568,16 @@ class LUInstanceCreate(LogicalUnit):
 
     disk_size = DetermineImageSize(self, install_image, instance.primary_node)
 
+    if instance.hypervisor == constants.HT_KVM:
+      disk_labels = ["/dev/vda", "/dev/vdb"]
+    else:
+      disk_labels = ["/dev/xvda", "/dev/xvdb"]
+
     with TemporaryDisk(self,
                        instance,
                        [(constants.DT_PLAIN, constants.DISK_RDWR, disk_size)],
                        feedback_fn):
-      self.UpdateInstanceOsInstallPackage(feedback_fn, instance)
+      self.UpdateInstanceOsInstallPackage(feedback_fn, instance, disk_labels)
       UpdateMetadata(feedback_fn, self.rpc, instance,
                      osparams_private=self.op.osparams_private,
                      osparams_secret=self.op.osparams_secret)
diff --git a/lib/rpc_defs.py b/lib/rpc_defs.py
index 7eb53f0..7f838d0 100644
--- a/lib/rpc_defs.py
+++ b/lib/rpc_defs.py
@@ -468,6 +468,7 @@ _OS_CALLS = [
     ], None, None, "Run a validation routine for a given OS"),
   ("os_export", SINGLE, None, constants.RPC_TMO_FAST, [
     ("instance", ED_INST_DICT, None),
+    ("disk_paths", None, None),
     ], None, None, "Export an OS for a given instance"),
   ]
 
diff --git a/lib/server/noded.py b/lib/server/noded.py
index 7c11b5a..43ff8b5 100644
--- a/lib/server/noded.py
+++ b/lib/server/noded.py
@@ -1000,7 +1000,8 @@ class NodeRequestHandler(http.server.HttpServerHandler):
 
     """
     instance = objects.Instance.FromDict(params[0])
-    return backend.ExportOS(instance)
+    disk_path = params[1]
+    return backend.ExportOS(instance, disk_path)
 
   # extstorage -----------------------
 
-- 
1.9.1.423.g4596e3a

Reply via email to