mrc0mmand / rpms / libguestfs

Forked from rpms/libguestfs 3 years ago
Clone

Blame SOURCES/0003-v2v-i-ova-Allow-directories-and-ZIP-files-to-be-used.patch

0d20ef
From 2837977b1ff0955a61c93593620f682a2473df0c Mon Sep 17 00:00:00 2001
0d20ef
From: "Richard W.M. Jones" <rjones@redhat.com>
0d20ef
Date: Sat, 18 Oct 2014 18:41:43 +0100
0d20ef
Subject: [PATCH] v2v: -i ova: Allow directories and ZIP files to be used as
0d20ef
 input (RHBZ#1152998).
0d20ef
0d20ef
OVA is not a particularly well-specified format.  The specification
0d20ef
allows a directory to be an OVA, so enable that.  The spec doesn't
0d20ef
mention that ZIP can be used in place of tar, but since we have seen
0d20ef
these in the wild, allow that too.
0d20ef
0d20ef
(cherry picked from commit 60405e5aa1b89ce4ad8b27efb992e82e38d6dbeb)
0d20ef
---
0d20ef
 README           |  2 ++
0d20ef
 configure.ac     |  7 +++++++
0d20ef
 v2v/input_ova.ml | 44 ++++++++++++++++++++++++++++++++++----------
0d20ef
 3 files changed, 43 insertions(+), 10 deletions(-)
0d20ef
0d20ef
diff --git a/README b/README
0d20ef
index b88a67d..30e241a 100644
0d20ef
--- a/README
0d20ef
+++ b/README
0d20ef
@@ -179,6 +179,8 @@ The full requirements are described below.
0d20ef
 +--------------+-------------+---+-----------------------------------------+
0d20ef
 | gtk2         |             | O | Used by virt-p2v user interface.        |
0d20ef
 +--------------+-------------+---+-----------------------------------------+
0d20ef
+| zip, unzip   |             | O | Used by virt-v2v for OVA files.         |
0d20ef
++--------------+-------------+---+-----------------------------------------+
0d20ef
 | python-evtx  |             | O | Used by virt-log to parse Windows       |
0d20ef
 |              |             |   | Event Log files.                        |
0d20ef
 +--------------+-------------+---+-----------------------------------------+
0d20ef
diff --git a/configure.ac b/configure.ac
0d20ef
index e11739d..74c72a1 100644
0d20ef
--- a/configure.ac
0d20ef
+++ b/configure.ac
0d20ef
@@ -720,6 +720,13 @@ if test "x$YACC" = "xyacc"; then
0d20ef
     AC_MSG_FAILURE([GNU 'bison' is required (yacc won't work).])
0d20ef
 fi
0d20ef
 
0d20ef
+dnl zip/unzip, used by virt-v2v
0d20ef
+AC_PATH_PROGS([ZIP],[zip],[no])
0d20ef
+AC_DEFINE_UNQUOTED([ZIP],["$ZIP"],[Name of zip program.])
0d20ef
+AM_CONDITIONAL([HAVE_ZIP],[test "x$ZIP" != "xno"])
0d20ef
+AC_PATH_PROGS([UNZIP],[unzip],[no])
0d20ef
+AC_DEFINE_UNQUOTED([UNZIP],["$UNZIP"],[Name of unzip program.])
0d20ef
+
0d20ef
 dnl Check for QEMU for running binaries on this $host_cpu, fall
0d20ef
 dnl back to basic 'qemu'.  Allow the user to override it.
0d20ef
 qemu_system="$(
0d20ef
diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml
0d20ef
index 7088e32..4ad38a0 100644
0d20ef
--- a/v2v/input_ova.ml
0d20ef
+++ b/v2v/input_ova.ml
0d20ef
@@ -36,13 +36,37 @@ object
0d20ef
   method as_options = "-i ova " ^ ova
0d20ef
 
0d20ef
   method source () =
0d20ef
-    (* Extract ova (tar) file. *)
0d20ef
-    let cmd = sprintf "tar -xf %s -C %s" (quote ova) (quote tmpdir) in
0d20ef
-    if verbose then printf "%s\n%!" cmd;
0d20ef
-    if Sys.command cmd <> 0 then
0d20ef
-      error (f_"error unpacking %s, see earlier error messages") ova;
0d20ef
+    (* Extract ova file. *)
0d20ef
+    let exploded =
0d20ef
+      (* The spec allows a directory to be specified as an ova.  This
0d20ef
+       * is also pretty convenient.
0d20ef
+       *)
0d20ef
+      if is_directory ova then ova
0d20ef
+      else (
0d20ef
+        match detect_file_type ova with
0d20ef
+        | `Tar ->
0d20ef
+          (* Normal ovas are tar file (not compressed). *)
0d20ef
+          let cmd = sprintf "tar -xf %s -C %s" (quote ova) (quote tmpdir) in
0d20ef
+          if verbose then printf "%s\n%!" cmd;
0d20ef
+          if Sys.command cmd <> 0 then
0d20ef
+            error (f_"error unpacking %s, see earlier error messages") ova;
0d20ef
+          tmpdir
0d20ef
+        | `Zip ->
0d20ef
+          (* However, although not permitted by the spec, people ship
0d20ef
+           * zip files as ova too.
0d20ef
+           *)
0d20ef
+          let cmd = sprintf "unzip%s -j -d %s %s"
0d20ef
+            (if verbose then "" else " -q")
0d20ef
+            (quote tmpdir) (quote ova) in
0d20ef
+          if verbose then printf "%s\n%!" cmd;
0d20ef
+          if Sys.command cmd <> 0 then
0d20ef
+            error (f_"error unpacking %s, see earlier error messages") ova;
0d20ef
+          tmpdir
0d20ef
+        | `GZip | `XZ | `Unknown ->
0d20ef
+          error (f_"%s: unsupported file format") ova
0d20ef
+      ) in
0d20ef
 
0d20ef
-    let files = Sys.readdir tmpdir in
0d20ef
+    let files = Sys.readdir exploded in
0d20ef
     let ovf = ref "" in
0d20ef
     (* Search for the ovf file. *)
0d20ef
     Array.iter (
0d20ef
@@ -58,13 +82,13 @@ object
0d20ef
     Array.iter (
0d20ef
       fun mf ->
0d20ef
         if Filename.check_suffix mf ".mf" then (
0d20ef
-          let chan = open_in (tmpdir // mf) in
0d20ef
+          let chan = open_in (exploded // mf) in
0d20ef
           let rec loop () =
0d20ef
             let line = input_line chan in
0d20ef
             if Str.string_match rex line 0 then (
0d20ef
               let disk = Str.matched_group 1 line in
0d20ef
               let expected = Str.matched_group 2 line in
0d20ef
-              let cmd = sprintf "sha1sum %s" (quote (tmpdir // disk)) in
0d20ef
+              let cmd = sprintf "sha1sum %s" (quote (exploded // disk)) in
0d20ef
               let out = external_command ~prog cmd in
0d20ef
               match out with
0d20ef
               | [] ->
0d20ef
@@ -86,7 +110,7 @@ object
0d20ef
     ) files;
0d20ef
 
0d20ef
     (* Parse the ovf file. *)
0d20ef
-    let xml = read_whole_file (tmpdir // ovf) in
0d20ef
+    let xml = read_whole_file (exploded // ovf) in
0d20ef
     let doc = Xml.parse_memory xml in
0d20ef
 
0d20ef
     (* Handle namespaces. *)
0d20ef
@@ -164,7 +188,7 @@ object
0d20ef
           let expr = sprintf "/ovf:Envelope/ovf:References/ovf:File[@ovf:id='%s']/@ovf:href" file_ref in
0d20ef
           let file_name = xpath_to_string expr "" in
0d20ef
           let disk = {
0d20ef
-            s_qemu_uri= tmpdir // file_name;
0d20ef
+            s_qemu_uri= exploded // file_name;
0d20ef
             s_format = Some "vmdk";
0d20ef
             s_target_dev = Some target_dev;
0d20ef
           } in
0d20ef
-- 
0d20ef
1.8.3.1
0d20ef