[Libguestfs] [PATCH v2 2/3] v2v: allow alternative directories for distributions

Tomáš Golembiovský tgolembi at redhat.com
Fri Feb 8 10:44:42 UTC 2019


Allow multiple alternative directory names for distributions (or
distribution familiy) when installing Linux guest tools packages.
Original naming required that there is a separate directory for every
version of a distribution (e.g. fc28, fc29, ...). This is inconvenient
when users want to keep just a single version of the package for the
distribution.

For each distribution one can have either a common directory (e.g.
fedora) or a versioned directory (fedora28). This can also be combined.
I.e. one can have both `fedora` and `fedora28` in which case `fedora28`
will be used when converting Fedora 28 guest wheres `fedora` will be
used when converting guests with any other Fedora version.

To have better names for unversioned directories the original names
were changed this way:

    fc -> fedora
    el -> rhel
    lp -> suse

The original directory names are kept for backward compatibility and are
aliased to new names as described below. When both new and old name are
present on file system the new name takes precedence.

    fc28 -> fedora
    el6 -> rhel6
    el7 -> rhel7
    lp151 -> suse

Signed-off-by: Tomáš Golembiovský <tgolembi at redhat.com>
---
 v2v/windows_virtio.ml | 79 +++++++++++++++++++++++++------------------
 1 file changed, 47 insertions(+), 32 deletions(-)

diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
index a2b59d1ec..9ef4904be 100644
--- a/v2v/windows_virtio.ml
+++ b/v2v/windows_virtio.ml
@@ -184,32 +184,38 @@ let rec install_drivers ((g, _) as reg) inspect rcaps =
   )
 
 and install_linux_tools g inspect =
-  let os =
+  let oses =
     match inspect.i_distro with
-    | "fedora" -> Some "fc28"
+    | "fedora" -> [
+      sprintf "fedora%d" inspect.i_major_version; "fedora"; "fc28"]
     | "rhel" | "centos" | "scientificlinux" | "redhat-based"
     | "oraclelinux" ->
-      (match inspect.i_major_version with
-       | 6 -> Some "el6"
-       | 7 -> Some "el7"
-       | _ -> None)
-    | "sles" | "suse-based" | "opensuse" -> Some "lp151"
-    | _ -> None in
-
-  match os with
-  | None ->
+      let r = ref [] in
+      List.push_back r (sprintf "rhel%d" inspect.i_major_version);
+      List.push_back_list r (match inspect.i_major_version with
+        | 6 -> ["el6"]
+        | 7 -> ["el7"]
+        | _ -> []);
+      List.push_back r "rhel";
+      !r
+    | "sles" | "suse-based" | "opensuse" -> [
+      sprintf "suse%d" inspect.i_major_version; "suse"; "lp151"]
+    | _ -> [] in
+
+  match oses with
+  | [] ->
       warning (f_"don't know how to install guest tools on %s-%d")
         inspect.i_distro inspect.i_major_version
-  | Some os ->
-      let src_path = "linux" // os in
+  | oses ->
+      let src_paths = List.map ((//) "linux") oses in
       let dst_path = "/var/tmp" in
-      debug "locating packages in %s" src_path;
+      debug "locating packages in: %s" (String.concat ", " src_paths);
       let packages =
-        copy_from_virtio_win g inspect src_path dst_path
+        copy_from_virtio_win g inspect src_paths dst_path
                              (fun _ _ -> true)
                              (fun () ->
-                               warning (f_"guest tools directory ‘%s’ is missing from the virtio-win directory or ISO.\n\nGuest tools are only provided in the RHV Guest Tools ISO, so this can happen if you are using the version of virtio-win which contains just the virtio drivers.  In this case only virtio drivers can be installed in the guest, and installation of Guest Tools will be skipped.")
-                                       src_path) in
+                               warning (f_"none of the guest tools directories ‘[%s]’ was found on the virtio-win directory or ISO.\n\nGuest tools are only provided in the oVirt/RHV Guest Tools ISO, so this can happen if you are using the version of virtio-win which contains just the virtio drivers.  In this case only virtio drivers can be installed in the guest, and installation of Guest Tools will be skipped.")
+                                  (String.concat ", " src_paths)) in
       debug "done copying %d files" (List.length packages);
       let packages = List.map ((//) dst_path) packages in
       try
@@ -290,30 +296,37 @@ and ddb_regedits inspect drv_name drv_pciid =
  * been copied.
  *)
 and copy_drivers g inspect driverdir =
-  [] <> copy_from_virtio_win g inspect "/" driverdir
+  [] <> copy_from_virtio_win g inspect ["/"] driverdir
     virtio_iso_path_matches_guest_os
     (fun () ->
       error (f_"root directory ‘/’ is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way.  Please report this as a bug with a full debug log."))
 
-(* Copy all files from virtio_win directory/ISO located in [srcdir]
- * subdirectory and all its subdirectories to the [destdir]. The directory
- * hierarchy is not preserved, meaning all files will be directly in [destdir].
- * The file list is filtered based on [filter] function.
+(* Find first existing direcotry from [scrdirs] list located in virtio_win
+ * directory/ISO and copy all files from that directory and all its
+ * subdirectories to the [destdir]. The directory hierarchy is not preserved,
+ * meaning all files will be directly in [destdir]. The file list is filtered
+ * based on [filter] function.
  *
- * If [srcdir] is missing from the ISO then [missing ()] is called
+ * If none of the directories in [srcdirs] exists [missing ()] is called
  * which might give a warning or error.
  *
+ * Note that the call may succeed whithout copying any file at all. This may
+ * happen when the source subdirectory exists but is empty or when [filter]
+ * function is too strict to allow any of the files.
+ *
  * Returns list of copied files.
  *)
-and copy_from_virtio_win g inspect srcdir destdir filter missing =
+and copy_from_virtio_win g inspect srcdirs destdir filter missing =
+  if srcdirs == [] then
+    invalid_arg "windows: copy_from_virtio_win: no source directories";
   let ret = ref [] in
   if is_directory virtio_win then (
     debug "windows: copy_from_virtio_win: guest tools source directory %s"
       virtio_win;
 
-    let dir = virtio_win // srcdir in
-    if not (is_directory dir) then missing ()
-    else (
+    try
+      let srcdirs = List.map ((//) virtio_win) srcdirs in
+      let dir = List.find is_directory srcdirs in
       let cmd = sprintf "cd %s && find -L -type f" (quote dir) in
       let paths = external_command cmd in
       List.iter (
@@ -329,7 +342,8 @@ and copy_from_virtio_win g inspect srcdir destdir filter missing =
             List.push_front target_name ret
           )
       ) paths
-    )
+    with Not_found ->
+      missing ()
   )
   else if is_regular_file virtio_win then (
     debug "windows: copy_from_virtio_win: guest tools source ISO %s" virtio_win;
@@ -340,9 +354,9 @@ and copy_from_virtio_win g inspect srcdir destdir filter missing =
       g2#launch ();
       let vio_root = "/" in
       g2#mount_ro "/dev/sda" vio_root;
-      let srcdir = vio_root ^ "/" ^ srcdir in
-      if not (g2#is_dir srcdir) then missing ()
-      else (
+      let srcdirs = List.map ((^) (vio_root ^ "/")) srcdirs in
+      try
+        let srcdir = List.find g2#is_dir srcdirs in
         let paths = g2#find srcdir in
         Array.iter (
           fun path ->
@@ -358,7 +372,8 @@ and copy_from_virtio_win g inspect srcdir destdir filter missing =
               List.push_front target_name ret
             )
         ) paths;
-      );
+      with Not_found ->
+        missing ();
       g2#close()
     with Guestfs.Error msg ->
       error (f_"%s: cannot open virtio-win ISO file: %s") virtio_win msg
-- 
2.20.1




More information about the Libguestfs mailing list