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
