diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..21d0719 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +SOURCES/RHEV-Application-Provisioning-Tool.exe_4.43-5 +SOURCES/libguestfs.keyring +SOURCES/rhsrvany-fd659e77cdd9da484fdc9dcbe0605c62ec26fa30.tar.gz +SOURCES/rhsrvany.exe +SOURCES/virt-v2v-1.42.0.tar.gz diff --git a/.virt-v2v.metadata b/.virt-v2v.metadata new file mode 100644 index 0000000..84dbc8f --- /dev/null +++ b/.virt-v2v.metadata @@ -0,0 +1,5 @@ +130adbc011dc0af736465b813c2b22a600c128c1 SOURCES/RHEV-Application-Provisioning-Tool.exe_4.43-5 +1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring +136ff75deb496e48eb448bc4ae156f3911464a90 SOURCES/rhsrvany-fd659e77cdd9da484fdc9dcbe0605c62ec26fa30.tar.gz +2bd96e478fc004cd323b5bd754c856641877dac6 SOURCES/rhsrvany.exe +bdbdc7cca87735af64f7e99c050ead24fa92aa7d SOURCES/virt-v2v-1.42.0.tar.gz diff --git a/SOURCES/0001-libvirt-make-use-of-libvirt-s-default-auth-handler-R.patch b/SOURCES/0001-libvirt-make-use-of-libvirt-s-default-auth-handler-R.patch new file mode 100644 index 0000000..0703d18 --- /dev/null +++ b/SOURCES/0001-libvirt-make-use-of-libvirt-s-default-auth-handler-R.patch @@ -0,0 +1,41 @@ +From 2ab37349cf37d0ffdb9929ca24c2a024600a4848 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Thu, 21 May 2020 13:32:21 +0200 +Subject: [PATCH] libvirt: make use of libvirt's default auth handler + (RHBZ#1838425) + +Use the default libvirt authentication handler as base for ours, +overriding it with our callback only in case we have a password to +supply. + +(cherry picked from commit ce66cac50179baf2fb8b404f7eba49048c7819b0) +--- + v2v/libvirt_utils.ml | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/v2v/libvirt_utils.ml b/v2v/libvirt_utils.ml +index 7df17b29..4d0b8639 100644 +--- a/v2v/libvirt_utils.ml ++++ b/v2v/libvirt_utils.ml +@@ -33,10 +33,14 @@ let auth_for_password_file ?password_file () = + ) creds + in + +- { +- Libvirt.Connect.credtype = [ Libvirt.Connect.CredentialPassphrase ]; +- cb = auth_fn; +- } ++ let base_auth = Libvirt.Connect.get_auth_default () in ++ ++ if password_file = None then ++ base_auth ++ else ++ { base_auth with ++ cb = auth_fn; ++ } + + let get_domain conn name = + let dom = +-- +2.18.4 + diff --git a/SOURCES/0001-options-Use-new-cryptsetup-open-API-if-available.patch b/SOURCES/0001-options-Use-new-cryptsetup-open-API-if-available.patch new file mode 100644 index 0000000..1347302 --- /dev/null +++ b/SOURCES/0001-options-Use-new-cryptsetup-open-API-if-available.patch @@ -0,0 +1,34 @@ +From 96ea18db4a4f2e336145553c0fbbba59ede2221e Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 30 Mar 2020 14:34:43 +0100 +Subject: [PATCH 1/4] options: Use new cryptsetup-open API if available. + +Fall back to luks-open if we're using libguestfs <= 1.43.1. +--- + options/decrypt.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/options/decrypt.c b/options/decrypt.c +index 683cf5e..d868f70 100644 +--- a/common/options/decrypt.c ++++ b/common/options/decrypt.c +@@ -97,11 +97,15 @@ inspect_do_decrypt (guestfs_h *g, struct key_store *ks) + + /* Try each key in turn. */ + for (j = 0; keys[j] != NULL; ++j) { +- /* XXX Should we call guestfs_luks_open_ro if readonly flag ++ /* XXX Should we set GUESTFS_CRYPTSETUP_OPEN_READONLY if readonly + * is set? This might break 'mount_ro'. + */ + guestfs_push_error_handler (g, NULL, NULL); ++#ifdef GUESTFS_HAVE_CRYPTSETUP_OPEN ++ r = guestfs_cryptsetup_open (g, partitions[i], keys[j], mapname, -1); ++#else + r = guestfs_luks_open (g, partitions[i], keys[j], mapname); ++#endif + guestfs_pop_error_handler (g); + if (r == 0) + goto opened; +-- +2.18.4 + diff --git a/SOURCES/0002-i-libvirt-print-URI-without-connecting-RHBZ-1839917.patch b/SOURCES/0002-i-libvirt-print-URI-without-connecting-RHBZ-1839917.patch new file mode 100644 index 0000000..da0e072 --- /dev/null +++ b/SOURCES/0002-i-libvirt-print-URI-without-connecting-RHBZ-1839917.patch @@ -0,0 +1,214 @@ +From e04f4d6aa0e94a61b40fa6b10a5274ea89cd96a1 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Mon, 25 May 2020 16:52:07 +0200 +Subject: [PATCH] -i libvirt: print URI without connecting (RHBZ#1839917) + +Pass (again) around the libvirt URI string in the various input_libvirt +subclasses so that input_libvirt#as_options does not need to connect to +print the connection URI. + +As related change: pass input_conn as non-optional string parameter in +classes that require one (all but input_libvirt_other, basically). This +avoids the need for extra checks. + +(cherry picked from commit 86d87563ee03e86ca9abdcad4f674af66a883006) +--- + v2v/input_libvirt.ml | 10 +++++----- + v2v/input_libvirt_other.ml | 12 ++++++++---- + v2v/input_libvirt_other.mli | 4 ++-- + v2v/input_libvirt_vcenter_https.ml | 4 ++-- + v2v/input_libvirt_vcenter_https.mli | 2 +- + v2v/input_libvirt_vddk.ml | 9 ++------- + v2v/input_libvirt_vddk.mli | 4 ++-- + v2v/input_libvirt_xen_ssh.ml | 4 ++-- + v2v/input_libvirt_xen_ssh.mli | 2 +- + 9 files changed, 25 insertions(+), 26 deletions(-) + +diff --git a/v2v/input_libvirt.ml b/v2v/input_libvirt.ml +index cd5f351c..352fae94 100644 +--- a/v2v/input_libvirt.ml ++++ b/v2v/input_libvirt.ml +@@ -53,22 +53,22 @@ let input_libvirt input_conn input_password input_transport guest = + + | Some _, None, _ (* No scheme? *) + | Some _, Some "", _ -> +- Input_libvirt_other.input_libvirt_other libvirt_conn guest ++ Input_libvirt_other.input_libvirt_other libvirt_conn ?input_conn guest + + (* vCenter over https. *) + | Some server, Some ("esx"|"gsx"|"vpx"), None -> + Input_libvirt_vcenter_https.input_libvirt_vcenter_https +- libvirt_conn input_password parsed_uri server guest ++ libvirt_conn orig_uri input_password parsed_uri server guest + + (* vCenter or ESXi using nbdkit vddk plugin *) + | Some server, Some ("esx"|"gsx"|"vpx"), Some (`VDDK vddk_options) -> + Input_libvirt_vddk.input_libvirt_vddk +- libvirt_conn input_conn input_password vddk_options parsed_uri guest ++ libvirt_conn orig_uri input_password vddk_options parsed_uri guest + + (* Xen over SSH *) + | Some server, Some "xen+ssh", _ -> + Input_libvirt_xen_ssh.input_libvirt_xen_ssh +- libvirt_conn input_password parsed_uri server guest ++ libvirt_conn orig_uri input_password parsed_uri server guest + + (* Old virt-v2v also supported qemu+ssh://. However I am + * deliberately not supporting this in new virt-v2v. Don't +@@ -79,6 +79,6 @@ let input_libvirt input_conn input_password input_transport guest = + | Some _, Some _, _ -> + warning (f_"no support for remote libvirt connections to '-ic %s'. The conversion may fail when it tries to read the source disks.") + orig_uri; +- Input_libvirt_other.input_libvirt_other libvirt_conn guest ++ Input_libvirt_other.input_libvirt_other libvirt_conn ?input_conn guest + + let () = Modules_list.register_input_module "libvirt" +diff --git a/v2v/input_libvirt_other.ml b/v2v/input_libvirt_other.ml +index e00944db..6a19ae52 100644 +--- a/v2v/input_libvirt_other.ml ++++ b/v2v/input_libvirt_other.ml +@@ -40,12 +40,16 @@ let error_if_libvirt_does_not_support_json_backingfile () = + error (f_"because of libvirt bug https://bugzilla.redhat.com/1134878 you must EITHER upgrade to libvirt >= 2.1.0 OR set this environment variable:\n\nexport LIBGUESTFS_BACKEND=direct\n\nand then rerun the virt-v2v command.") + + (* Superclass. *) +-class virtual input_libvirt libvirt_conn guest = ++class virtual input_libvirt libvirt_conn ?input_conn guest = + object (self) + inherit input + + method as_options = +- sprintf "-i libvirt -ic %s %s" (Libvirt.Connect.get_uri self#conn) guest ++ sprintf "-i libvirt%s %s" ++ (match input_conn with ++ | None -> "" ++ | Some uri -> " -ic " ^ uri) ++ guest + + method private conn : Libvirt.rw Libvirt.Connect.t = + Lazy.force libvirt_conn +@@ -54,9 +58,9 @@ end + (* Subclass specialized for handling anything that's *not* VMware vCenter + * or Xen. + *) +-class input_libvirt_other libvirt_conn guest = ++class input_libvirt_other libvirt_conn ?input_conn guest = + object (self) +- inherit input_libvirt libvirt_conn guest ++ inherit input_libvirt libvirt_conn ?input_conn guest + + method source ?bandwidth () = + debug "input_libvirt_other: source ()"; +diff --git a/v2v/input_libvirt_other.mli b/v2v/input_libvirt_other.mli +index c528c3ee..ae2c0c6d 100644 +--- a/v2v/input_libvirt_other.mli ++++ b/v2v/input_libvirt_other.mli +@@ -20,11 +20,11 @@ + + val error_if_libvirt_does_not_support_json_backingfile : unit -> unit + +-class virtual input_libvirt : Libvirt.rw Libvirt.Connect.t Lazy.t -> string -> object ++class virtual input_libvirt : Libvirt.rw Libvirt.Connect.t Lazy.t -> ?input_conn:string -> string -> object + method precheck : unit -> unit + method as_options : string + method virtual source : ?bandwidth:Types.bandwidth -> unit -> Types.source * Types.source_disk list + method private conn : Libvirt.rw Libvirt.Connect.t + end + +-val input_libvirt_other : Libvirt.rw Libvirt.Connect.t Lazy.t -> string -> Types.input ++val input_libvirt_other : Libvirt.rw Libvirt.Connect.t Lazy.t -> ?input_conn:string -> string -> Types.input +diff --git a/v2v/input_libvirt_vcenter_https.ml b/v2v/input_libvirt_vcenter_https.ml +index 77bc315d..ed2e5eed 100644 +--- a/v2v/input_libvirt_vcenter_https.ml ++++ b/v2v/input_libvirt_vcenter_https.ml +@@ -32,9 +32,9 @@ open Printf + + (* Subclass specialized for handling VMware vCenter over https. *) + class input_libvirt_vcenter_https +- libvirt_conn input_password parsed_uri server guest = ++ libvirt_conn input_conn input_password parsed_uri server guest = + object (self) +- inherit input_libvirt libvirt_conn guest ++ inherit input_libvirt libvirt_conn ~input_conn guest + + val mutable dcPath = "" + +diff --git a/v2v/input_libvirt_vcenter_https.mli b/v2v/input_libvirt_vcenter_https.mli +index c2e0f3fe..a12a9815 100644 +--- a/v2v/input_libvirt_vcenter_https.mli ++++ b/v2v/input_libvirt_vcenter_https.mli +@@ -18,4 +18,4 @@ + + (** [-i libvirt] when the source is VMware vCenter *) + +-val input_libvirt_vcenter_https : Libvirt.rw Libvirt.Connect.t Lazy.t -> string option -> Xml.uri -> string -> string -> Types.input ++val input_libvirt_vcenter_https : Libvirt.rw Libvirt.Connect.t Lazy.t -> string -> string option -> Xml.uri -> string -> string -> Types.input +diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml +index fbd1e0c6..75fd146e 100644 +--- a/v2v/input_libvirt_vddk.ml ++++ b/v2v/input_libvirt_vddk.ml +@@ -99,7 +99,7 @@ class input_libvirt_vddk libvirt_conn input_conn input_password vddk_options + in + + object (self) +- inherit input_libvirt libvirt_conn guest as super ++ inherit input_libvirt libvirt_conn ~input_conn guest as super + + method precheck () = + error_unless_thumbprint () +@@ -138,12 +138,7 @@ object (self) + match parsed_uri.Xml.uri_server with + | Some server -> server + | None -> +- match input_conn with +- | Some input_conn -> +- error (f_"‘-ic %s’ URL does not contain a host name field") +- input_conn +- | None -> +- error (f_"you must use the ‘-ic’ parameter. See the virt-v2v-input-vmware(1) manual.") in ++ error (f_"‘-ic %s’ URL does not contain a host name field") input_conn in + + let user = parsed_uri.Xml.uri_user in + +diff --git a/v2v/input_libvirt_vddk.mli b/v2v/input_libvirt_vddk.mli +index 2fc6e9cf..f37d88e7 100644 +--- a/v2v/input_libvirt_vddk.mli ++++ b/v2v/input_libvirt_vddk.mli +@@ -25,7 +25,7 @@ val print_input_options : unit -> unit + val parse_input_options : (string * string) list -> vddk_options + (** Print and parse vddk -io options. *) + +-val input_libvirt_vddk : Libvirt.rw Libvirt.Connect.t Lazy.t -> string option -> string option -> vddk_options -> Xml.uri -> string -> Types.input +-(** [input_libvirt_vddk libvirt_conn vddk_options parsed_uri guest] ++val input_libvirt_vddk : Libvirt.rw Libvirt.Connect.t Lazy.t -> string -> string option -> vddk_options -> Xml.uri -> string -> Types.input ++(** [input_libvirt_vddk libvirt_conn input_conn vddk_options parsed_uri guest] + creates and returns a {!Types.input} object specialized for reading + the guest disks using the nbdkit vddk plugin. *) +diff --git a/v2v/input_libvirt_xen_ssh.ml b/v2v/input_libvirt_xen_ssh.ml +index bd1235a6..ec366b4a 100644 +--- a/v2v/input_libvirt_xen_ssh.ml ++++ b/v2v/input_libvirt_xen_ssh.ml +@@ -30,9 +30,9 @@ open Input_libvirt_other + open Printf + + (* Subclass specialized for handling Xen over SSH. *) +-class input_libvirt_xen_ssh libvirt_conn input_password parsed_uri server guest = ++class input_libvirt_xen_ssh libvirt_conn input_conn input_password parsed_uri server guest = + object (self) +- inherit input_libvirt libvirt_conn guest ++ inherit input_libvirt libvirt_conn ~input_conn guest + + method precheck () = + if backend_is_libvirt () then +diff --git a/v2v/input_libvirt_xen_ssh.mli b/v2v/input_libvirt_xen_ssh.mli +index 120a52f7..3cbca9d7 100644 +--- a/v2v/input_libvirt_xen_ssh.mli ++++ b/v2v/input_libvirt_xen_ssh.mli +@@ -18,4 +18,4 @@ + + (** [-i libvirt] when the source is Xen *) + +-val input_libvirt_xen_ssh : Libvirt.rw Libvirt.Connect.t Lazy.t -> string option -> Xml.uri -> string -> string -> Types.input ++val input_libvirt_xen_ssh : Libvirt.rw Libvirt.Connect.t Lazy.t -> string -> string option -> Xml.uri -> string -> string -> Types.input +-- +2.18.4 + diff --git a/SOURCES/0002-options-Use-cryptX-instead-of-luksX-as-the-temporary.patch b/SOURCES/0002-options-Use-cryptX-instead-of-luksX-as-the-temporary.patch new file mode 100644 index 0000000..d4bfce6 --- /dev/null +++ b/SOURCES/0002-options-Use-cryptX-instead-of-luksX-as-the-temporary.patch @@ -0,0 +1,41 @@ +From f9770058fa3bd8871b8b4ded0b10d4be418224ae Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 7 Sep 2020 10:15:40 +0100 +Subject: [PATCH 2/4] options: Use cryptX instead of luksX as the temporary + name. + +--- + options/decrypt.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/options/decrypt.c b/options/decrypt.c +index d868f70..45de5b2 100644 +--- a/common/options/decrypt.c ++++ b/common/options/decrypt.c +@@ -38,18 +38,18 @@ + + /** + * Make a LUKS map name from the partition name, +- * eg. C<"/dev/vda2" =E "luksvda2"> ++ * eg. C<"/dev/vda2" =E "cryptvda2"> + */ + static void + make_mapname (const char *device, char *mapname, size_t len) + { + size_t i = 0; + +- if (len < 5) ++ if (len < 6) + abort (); +- strcpy (mapname, "luks"); +- mapname += 4; +- len -= 4; ++ strcpy (mapname, "crypt"); ++ mapname += 5; ++ len -= 5; + + if (STRPREFIX (device, "/dev/")) + i = 5; +-- +2.18.4 + diff --git a/SOURCES/0003-options-Support-Windows-BitLocker-RHBZ-1808977.patch b/SOURCES/0003-options-Support-Windows-BitLocker-RHBZ-1808977.patch new file mode 100644 index 0000000..7871d02 --- /dev/null +++ b/SOURCES/0003-options-Support-Windows-BitLocker-RHBZ-1808977.patch @@ -0,0 +1,56 @@ +From 778c08fe7b7eb00b7f48189dd1a3edf3f3be2625 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 30 Mar 2020 14:40:45 +0100 +Subject: [PATCH 3/4] options: Support Windows BitLocker (RHBZ#1808977). + +--- + mltools/tools_utils.mli | 5 ++--- + options/decrypt.c | 9 ++++----- + 2 files changed, 6 insertions(+), 8 deletions(-) + +diff --git a/mltools/tools_utils.mli b/mltools/tools_utils.mli +index 102abff..1d1ac8a 100644 +--- a/common/mltools/tools_utils.mli ++++ b/common/mltools/tools_utils.mli +@@ -195,9 +195,8 @@ val is_btrfs_subvolume : Guestfs.guestfs -> string -> bool + (** Checks if a filesystem is a btrfs subvolume. *) + + val inspect_decrypt : Guestfs.guestfs -> key_store -> unit +-(** Simple implementation of decryption: look for any [crypto_LUKS] +- partitions and decrypt them, then rescan for VGs. This only works +- for Fedora whole-disk encryption. *) ++(** Simple implementation of decryption: look for any encrypted ++ partitions and decrypt them, then rescan for VGs. *) + + val with_timeout : string -> int -> ?sleep:int -> (unit -> 'a option) -> 'a + (** [with_timeout op timeout ?sleep fn] implements a timeout loop. +diff --git a/options/decrypt.c b/options/decrypt.c +index 45de5b2..8eb24bc 100644 +--- a/common/options/decrypt.c ++++ b/common/options/decrypt.c +@@ -65,10 +65,8 @@ make_mapname (const char *device, char *mapname, size_t len) + } + + /** +- * Simple implementation of decryption: look for any C +- * partitions and decrypt them, then rescan for VGs. This only works +- * for Fedora whole-disk encryption. WIP to make this work for other +- * encryption schemes. ++ * Simple implementation of decryption: look for any encrypted ++ * partitions and decrypt them, then rescan for VGs. + */ + void + inspect_do_decrypt (guestfs_h *g, struct key_store *ks) +@@ -82,7 +80,8 @@ inspect_do_decrypt (guestfs_h *g, struct key_store *ks) + + for (i = 0; partitions[i] != NULL; ++i) { + CLEANUP_FREE char *type = guestfs_vfs_type (g, partitions[i]); +- if (type && STREQ (type, "crypto_LUKS")) { ++ if (type && ++ (STREQ (type, "crypto_LUKS") || STREQ (type, "BitLocker"))) { + char mapname[32]; + make_mapname (partitions[i], mapname, sizeof mapname); + +-- +2.18.4 + diff --git a/SOURCES/0003-vCenter-fix-parsing-of-HTTP-status-string-RHBZ-18373.patch b/SOURCES/0003-vCenter-fix-parsing-of-HTTP-status-string-RHBZ-18373.patch new file mode 100644 index 0000000..1c8750e --- /dev/null +++ b/SOURCES/0003-vCenter-fix-parsing-of-HTTP-status-string-RHBZ-18373.patch @@ -0,0 +1,34 @@ +From bb94c68c521aa546d3f2e59aa25e388bfd9c5fc5 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 19 May 2020 12:14:18 +0200 +Subject: [PATCH] vCenter: fix parsing of HTTP status string (RHBZ#1837328) + +vCenter 7 answers with an HTTP/2 status string, so we cannot extract +the status code from it by using fixed positions in that string. +Hence, pick the status code by reading what's after the whitespace. + +Tested with vCenter 6.5 and 7. + +(cherry picked from commit d2aa82317964d62fcc8dc7b6737773003d04b998) +--- + v2v/vCenter.ml | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/v2v/vCenter.ml b/v2v/vCenter.ml +index c28a4ced..4c128b0c 100644 +--- a/v2v/vCenter.ml ++++ b/v2v/vCenter.ml +@@ -190,7 +190,9 @@ and fetch_headers_from_url password_file uri sslverify https_url = + | [] -> + dump_response stderr; + error (f_"vcenter: no status code in output of ‘curl’ command. Is ‘curl’ installed?") +- | ss -> String.sub (List.hd (List.rev ss)) 9 3 in ++ | ss -> ++ let s = List.hd (List.rev ss) in ++ String.sub s (String.index s ' ' + 1) 3 in + + let headers = + List.map ( +-- +2.18.4 + diff --git a/SOURCES/0004-options-Ignore-errors-from-guestfs_luks_uuid.patch b/SOURCES/0004-options-Ignore-errors-from-guestfs_luks_uuid.patch new file mode 100644 index 0000000..48ff652 --- /dev/null +++ b/SOURCES/0004-options-Ignore-errors-from-guestfs_luks_uuid.patch @@ -0,0 +1,50 @@ +From 132c355d3ba10b6ec303cbc059d6732056474695 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 6 Oct 2020 15:04:27 +0100 +Subject: [PATCH 4/4] options: Ignore errors from guestfs_luks_uuid. + +For BitLocker disks cryptsetup does not (yet? ever?) support reading +UUIDs and this function will fail. Skip reading the UUID in this +case. + +Updates commit bb4a2dc17a78b53437896d4215ae82df8e11b788. +--- + options/decrypt.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/options/decrypt.c b/options/decrypt.c +index 8eb24bc..434b7d5 100644 +--- a/common/options/decrypt.c ++++ b/common/options/decrypt.c +@@ -25,6 +25,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -82,11 +83,19 @@ inspect_do_decrypt (guestfs_h *g, struct key_store *ks) + CLEANUP_FREE char *type = guestfs_vfs_type (g, partitions[i]); + if (type && + (STREQ (type, "crypto_LUKS") || STREQ (type, "BitLocker"))) { ++ bool is_bitlocker = STREQ (type, "BitLocker"); + char mapname[32]; + make_mapname (partitions[i], mapname, sizeof mapname); + + #ifdef GUESTFS_HAVE_LUKS_UUID +- CLEANUP_FREE char *uuid = guestfs_luks_uuid (g, partitions[i]); ++ CLEANUP_FREE char *uuid = NULL; ++ ++ /* This fails for Windows BitLocker disks because cryptsetup ++ * luksUUID cannot read a UUID (unclear if this is a limitation ++ * of the format or cryptsetup). ++ */ ++ if (!is_bitlocker) ++ uuid = guestfs_luks_uuid (g, partitions[i]); + #else + const char *uuid = NULL; + #endif +-- +2.18.4 + diff --git a/SOURCES/0004-v2v-o-libvirt-Remove-cache-none-RHBZ-1837453.patch b/SOURCES/0004-v2v-o-libvirt-Remove-cache-none-RHBZ-1837453.patch new file mode 100644 index 0000000..0dbc5d6 --- /dev/null +++ b/SOURCES/0004-v2v-o-libvirt-Remove-cache-none-RHBZ-1837453.patch @@ -0,0 +1,97 @@ +From 939d57ef4d5bcfa31e9b98104822962b89572481 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 19 May 2020 14:40:01 +0100 +Subject: [PATCH] v2v: -o libvirt: Remove cache=none (RHBZ#1837453). + +Traditionally if you did live migration (KVM to KVM), you had to +ensure that cache=none was set on all disks of the guest up front. +This was because of quirks in how NFS works (I think the close-to-open +consistency and the fact that during live migration both qemus have +the file open), and we had to assume the worst case that a guest might +be backed by NFS. + +Because of this when virt-v2v converts a guest to run on KVM using +libvirt it sets cache=none. + +This is not necessary with modern qemu. If qemu supports the +drop-cache property of the file block driver, which libvirt will +automatically detect for us, then libvirt live migration is able to +tell qemu to drop cached data at the right time even if the backing is +NFS. + +It also had a significant performance impact. In some synthetic +benchmarks it could show 2 or 3 times slower performance. + +Thanks: Ming Xie, Peter Krempa. +(cherry picked from commit 9720f45e0cd9283739fd2a67c19e66912489dfc7) +--- + docs/virt-v2v-output-local.pod | 2 +- + tests/test-v2v-cdrom.expected | 2 +- + tests/test-v2v-floppy.expected | 2 +- + tests/test-v2v-i-ova.xml | 2 +- + v2v/create_libvirt_xml.ml | 1 - + 5 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/docs/virt-v2v-output-local.pod b/docs/virt-v2v-output-local.pod +index 38df007d..a5f155cb 100644 +--- a/docs/virt-v2v-output-local.pod ++++ b/docs/virt-v2v-output-local.pod +@@ -127,7 +127,7 @@ Edit F to change F to the pool + name. In other words, locate the following bit of XML: + + +- ++ + + + +diff --git a/tests/test-v2v-cdrom.expected b/tests/test-v2v-cdrom.expected +index e18ea6f2..34d2bf59 100644 +--- a/tests/test-v2v-cdrom.expected ++++ b/tests/test-v2v-cdrom.expected +@@ -1,5 +1,5 @@ + +- ++ + + + +diff --git a/tests/test-v2v-floppy.expected b/tests/test-v2v-floppy.expected +index dd74ed94..a718c21f 100644 +--- a/tests/test-v2v-floppy.expected ++++ b/tests/test-v2v-floppy.expected +@@ -1,5 +1,5 @@ + +- ++ + + + +diff --git a/tests/test-v2v-i-ova.xml b/tests/test-v2v-i-ova.xml +index 7c198283..e26f4f83 100644 +--- a/tests/test-v2v-i-ova.xml ++++ b/tests/test-v2v-i-ova.xml +@@ -22,7 +22,7 @@ + restart + + +- ++ + + + +diff --git a/v2v/create_libvirt_xml.ml b/v2v/create_libvirt_xml.ml +index 05553c4f..5a1fba0f 100644 +--- a/v2v/create_libvirt_xml.ml ++++ b/v2v/create_libvirt_xml.ml +@@ -336,7 +336,6 @@ let create_libvirt_xml ?pool source targets target_buses guestcaps + e "driver" [ + "name", "qemu"; + "type", t.target_format; +- "cache", "none" + ] []; + (match pool with + | None -> +-- +2.18.4 + diff --git a/SOURCES/0005-v2v-Remove-extraneous-when-setting-bandwidth-RHBZ-18.patch b/SOURCES/0005-v2v-Remove-extraneous-when-setting-bandwidth-RHBZ-18.patch new file mode 100644 index 0000000..2ea9a5f --- /dev/null +++ b/SOURCES/0005-v2v-Remove-extraneous-when-setting-bandwidth-RHBZ-18.patch @@ -0,0 +1,51 @@ +From f3ea9ceb1c3c9741d4f62d0c1d23b7c94634353a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 28 May 2020 11:40:45 +0100 +Subject: [PATCH] v2v: Remove extraneous '=' when setting bandwidth + (RHBZ#1841096). + +Commit c3a54d6aed6dfc65f9ffa59976bb8d20044c03a8 ("v2v: Add standalone +nbdkit module.") was supposed to be a simple refactoring but it broke +the --bandwidth and --bandwidth-file options (amongst other things). + +Because of an extra '=' character which was accidentally left over, it +would add an extra character in the nbdkit-rate-filter command line. +For example: + + virt-v2v .. --bandwidth 200M + +would invoke: + + nbdkit .. --filter rate rate==200M + +which causes a parse error. The --bandwidth-file option does not +invoke a parse error but does not work, for similar reasons. + +Thanks: Ming Xie +(cherry picked from commit a89a084b2d0f6d40716c1d34969f6c49ea28e9b3) +--- + v2v/nbdkit_sources.ml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/v2v/nbdkit_sources.ml b/v2v/nbdkit_sources.ml +index 979c3773..402dfd0e 100644 +--- a/v2v/nbdkit_sources.ml ++++ b/v2v/nbdkit_sources.ml +@@ -118,11 +118,11 @@ let common_create ?bandwidth ?extra_debug ?extra_env plugin_name plugin_args = + let args = + match bandwidth with + | StaticBandwidth rate -> +- [ "rate=", rate ] ++ [ "rate", rate ] + | DynamicBandwidth (None, filename) -> +- [ "rate-file=", filename ] ++ [ "rate-file", filename ] + | DynamicBandwidth (Some rate, filename) -> +- [ "rate=", rate; "rate-file=", filename ] in ++ [ "rate", rate; "rate-file", filename ] in + cmd, args + ) + else cmd, [] in +-- +2.18.4 + diff --git a/SOURCES/0006-v2v-it-vddk-Don-t-use-nbdkit-readahead-filter-with-V.patch b/SOURCES/0006-v2v-it-vddk-Don-t-use-nbdkit-readahead-filter-with-V.patch new file mode 100644 index 0000000..200e22d --- /dev/null +++ b/SOURCES/0006-v2v-it-vddk-Don-t-use-nbdkit-readahead-filter-with-V.patch @@ -0,0 +1,49 @@ +From 4e0b3de57486613c8f28ef7726df728cccd7624b Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 28 May 2020 10:59:57 +0100 +Subject: [PATCH] v2v: -it vddk: Don't use nbdkit readahead filter with VDDK + (RHBZ#1832805). + +This filter deliberately tries to coalesce reads into larger requests. +Unfortunately VMware has low limits on the size of requests it can +serve to a VDDK client and the larger requests would break with errors +like this: + + nbdkit: vddk[3]: error: [NFC ERROR] NfcFssrvrProcessErrorMsg: received NFC error 5 from server: Failed to allocate the requested 33554456 bytes + +We already increase the maximum request size by changing the +configuration on the VMware server, but it's not sufficient for VDDK +with the readahead filter. + +As readahead is only an optimization, the simplest solution is to +disable this filter when we're using nbdkit-vddk-plugin. + +Thanks: Ming Xie +(cherry picked from commit 1438174488f111fa24420758ba3bf0218dc9ee2a) +--- + v2v/nbdkit_sources.ml | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/v2v/nbdkit_sources.ml b/v2v/nbdkit_sources.ml +index 402dfd0e..bfda91a7 100644 +--- a/v2v/nbdkit_sources.ml ++++ b/v2v/nbdkit_sources.ml +@@ -97,9 +97,13 @@ let common_create ?bandwidth ?extra_debug ?extra_env plugin_name plugin_args = + let cmd = Nbdkit.add_filter_if_available cmd "retry" in + + (* Adding the readahead filter is always a win for our access +- * patterns. However if it doesn't exist don't worry. ++ * patterns. If it doesn't exist don't worry. However it ++ * breaks VMware servers (RHBZ#1832805). + *) +- let cmd = Nbdkit.add_filter_if_available cmd "readahead" in ++ let cmd = ++ if plugin_name <> "vddk" then ++ Nbdkit.add_filter_if_available cmd "readahead" ++ else cmd in + + (* Caching extents speeds up qemu-img, especially its consecutive + * block_status requests with req_one=1. +-- +2.18.4 + diff --git a/SOURCES/0007-v2v-nbdkit-Handle-password-parameter-in-common_creat.patch b/SOURCES/0007-v2v-nbdkit-Handle-password-parameter-in-common_creat.patch new file mode 100644 index 0000000..68b2d1d --- /dev/null +++ b/SOURCES/0007-v2v-nbdkit-Handle-password-parameter-in-common_creat.patch @@ -0,0 +1,116 @@ +From bcb9f50eee4050e72a532a0b805531dc72105a4f Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 1 Jun 2020 17:18:59 +0100 +Subject: [PATCH] v2v: nbdkit: Handle password= parameter in common_create. + +Just refactoring. + +(cherry picked from commit 36c008009a601634ec1c1fbc4f619b21988f075c) +--- + v2v/nbdkit_sources.ml | 42 +++++++++++++++++++----------------------- + 1 file changed, 19 insertions(+), 23 deletions(-) + +diff --git a/v2v/nbdkit_sources.ml b/v2v/nbdkit_sources.ml +index bfda91a7..47832011 100644 +--- a/v2v/nbdkit_sources.ml ++++ b/v2v/nbdkit_sources.ml +@@ -58,7 +58,8 @@ let error_unless_nbdkit_compiled_with_selinux config = + error (f_"nbdkit was compiled without SELinux support. You will have to recompile nbdkit with libselinux-devel installed, or else set SELinux to Permissive mode while doing the conversion.") + ) + +-let common_create ?bandwidth ?extra_debug ?extra_env plugin_name plugin_args = ++let common_create ?bandwidth ?extra_debug ?extra_env password ++ plugin_name plugin_args = + error_unless_nbdkit_working (); + let config = Nbdkit.config () in + error_unless_nbdkit_min_version config; +@@ -136,6 +137,15 @@ let common_create ?bandwidth ?extra_debug ?extra_env plugin_name plugin_args = + List.fold_left (fun cmd (k, v) -> Nbdkit.add_arg cmd k v) + cmd (plugin_args @ rate_args) in + ++ (* Handle the password parameter specially. *) ++ let cmd = ++ match password with ++ | NoPassword -> cmd ++ | AskForPassword -> ++ Nbdkit.add_arg cmd "password" "-" ++ | PasswordFile password_file -> ++ Nbdkit.add_arg cmd "password" ("+" ^ password_file) in ++ + cmd + + (* VDDK libraries are located under lib32/ or lib64/ relative to the +@@ -223,20 +233,16 @@ See also the virt-v2v-input-vmware(1) manual.") libNN + let get_args () = List.rev !args in + add_arg, get_args in + +- let password_param = +- match password_file with +- | None -> +- (* nbdkit asks for the password interactively *) +- "password", "-" +- | Some password_file -> +- (* nbdkit reads the password from the file *) +- "password", "+" ^ password_file in + add_arg ("server", server); + add_arg ("user", user); +- add_arg password_param; + add_arg ("vm", sprintf "moref=%s" moref); + add_arg ("file", path); + ++ let password = ++ match password_file with ++ | None -> AskForPassword ++ | Some password_file -> PasswordFile password_file in ++ + (* The passthrough parameters. *) + Option.may (fun s -> add_arg ("config", s)) config; + Option.may (fun s -> add_arg ("cookie", s)) cookie; +@@ -251,7 +257,7 @@ See also the virt-v2v-input-vmware(1) manual.") libNN + let debug_flag = + if version >= (1, 17, 10) then Some ("vddk.datapath", "0") else None in + +- common_create ?bandwidth ?extra_debug:debug_flag ?extra_env:env ++ common_create ?bandwidth ?extra_debug:debug_flag ?extra_env:env password + "vddk" (get_args ()) + + (* Create an nbdkit module specialized for reading from SSH sources. *) +@@ -267,14 +273,9 @@ let create_ssh ?bandwidth ~password ?port ~server ?user path = + add_arg ("host", server); + Option.may (fun s -> add_arg ("port", s)) port; + Option.may (fun s -> add_arg ("user", s)) user; +- (match password with +- | NoPassword -> () +- | AskForPassword -> add_arg ("password", "-") +- | PasswordFile password_file -> add_arg ("password", "+" ^ password_file) +- ); + add_arg ("path", path); + +- common_create ?bandwidth "ssh" (get_args ()) ++ common_create ?bandwidth password "ssh" (get_args ()) + + (* Create an nbdkit module specialized for reading from Curl sources. *) + let create_curl ?bandwidth ?cookie ~password ?(sslverify=true) ?user url = +@@ -287,18 +288,13 @@ let create_curl ?bandwidth ?cookie ~password ?(sslverify=true) ?user url = + add_arg, get_args in + + Option.may (fun s -> add_arg ("user", s)) user; +- (match password with +- | NoPassword -> () +- | AskForPassword -> add_arg ("password", "-") +- | PasswordFile password_file -> add_arg ("password", "+" ^ password_file) +- ); + (* https://bugzilla.redhat.com/show_bug.cgi?id=1146007#c10 *) + add_arg ("timeout", "2000"); + Option.may (fun s -> add_arg ("cookie", s)) cookie; + if not sslverify then add_arg ("sslverify", "false"); + add_arg ("url", url); + +- common_create ?bandwidth "curl" (get_args ()) ++ common_create ?bandwidth password "curl" (get_args ()) + + let run cmd = + let sock, _ = Nbdkit.run_unix cmd in +-- +2.18.4 + diff --git a/SOURCES/0008-v2v-nbdkit-Don-t-use-password-parameter-RHBZ-1842440.patch b/SOURCES/0008-v2v-nbdkit-Don-t-use-password-parameter-RHBZ-1842440.patch new file mode 100644 index 0000000..fc39e35 --- /dev/null +++ b/SOURCES/0008-v2v-nbdkit-Don-t-use-password-parameter-RHBZ-1842440.patch @@ -0,0 +1,57 @@ +From 89ab50eb404664ac3522294f2f46a1c904a28abd Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 1 Jun 2020 17:35:58 +0100 +Subject: [PATCH] v2v: nbdkit: Don't use password=- parameter (RHBZ#1842440). + +This was broken with all nbdkit plugins, some in more ways than others. + +Because we start nbdkit in the background and wait 30 seconds for it +to start running, the user had only 30 seconds to type in a password +before we timed out the process. In addition with the VDDK plugin +password=- had been broken ever since we changed the plugin to use a +reexec +(https://www.redhat.com/archives/libguestfs/2020-June/msg00012.html). + +The solution is to read the password ourselves and pass it to nbdkit +as a private file. + +(cherry picked from commit 16b551c77c88219a2f68e2fc37daf2dc4d88e4ed) +--- + v2v/nbdkit_sources.ml | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/v2v/nbdkit_sources.ml b/v2v/nbdkit_sources.ml +index 47832011..f5e91911 100644 +--- a/v2v/nbdkit_sources.ml ++++ b/v2v/nbdkit_sources.ml +@@ -142,7 +142,26 @@ let common_create ?bandwidth ?extra_debug ?extra_env password + match password with + | NoPassword -> cmd + | AskForPassword -> +- Nbdkit.add_arg cmd "password" "-" ++ (* Because we will start nbdkit in the background and then wait ++ * for 30 seconds for it to start up, we cannot use the ++ * password=- feature of nbdkit to read the password ++ * interactively (since in the words of the movie the user has ++ * only "30 seconds to comply"). In any case this feature broke ++ * in the VDDK plugin in nbdkit 1.18 and 1.20. So in the ++ * AskForPassword case we read the password here. ++ *) ++ printf "password: "; ++ let open Unix in ++ let orig = tcgetattr stdin in ++ let tios = { orig with c_echo = false } in ++ tcsetattr stdin TCSAFLUSH tios; (* Disable echo. *) ++ let password = read_line () in ++ tcsetattr stdin TCSAFLUSH orig; (* Restore echo. *) ++ printf "\n"; ++ let password_file = Filename.temp_file "v2vnbdkit" ".txt" in ++ unlink_on_exit password_file; ++ with_open_out password_file (fun chan -> output_string chan password); ++ Nbdkit.add_arg cmd "password" ("+" ^ password_file) + | PasswordFile password_file -> + Nbdkit.add_arg cmd "password" ("+" ^ password_file) in + +-- +2.18.4 + diff --git a/SOURCES/0009-libosinfo-declare-autocleanup-funcs-with-libosinfo-1.patch b/SOURCES/0009-libosinfo-declare-autocleanup-funcs-with-libosinfo-1.patch new file mode 100644 index 0000000..1b72610 --- /dev/null +++ b/SOURCES/0009-libosinfo-declare-autocleanup-funcs-with-libosinfo-1.patch @@ -0,0 +1,44 @@ +From a8f3d2b2e87aead9f6a1db66dccebb6239ddf004 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 19 Jun 2020 17:57:36 +0200 +Subject: [PATCH] libosinfo: declare autocleanup funcs with libosinfo < 1.8.0 + +libosinfo 1.8.0 declares them automatically for all of its classes, so +there is no need to declare ours. This requires fixing the definition of +the IS_LIBOSINFO_VERSION macro to wrap its body in brackets. + +While in the process, simplify the workaround for a related bug by +removing a now-useless check. + +(cherry picked from commit c1caf7132000a4560c3e20c2753978e8dd10036a) +--- + v2v/libosinfo-c.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/v2v/libosinfo-c.c b/v2v/libosinfo-c.c +index 1ab6bb4d..497840c2 100644 +--- a/v2v/libosinfo-c.c ++++ b/v2v/libosinfo-c.c +@@ -40,12 +40,18 @@ + #define V2V_LIBOSINFO_VERSION_HEX \ + MAKE_VERSION_HEX(OSINFO_MAJOR_VERSION, OSINFO_MINOR_VERSION, OSINFO_MICRO_VERSION) + #define IS_LIBOSINFO_VERSION(maj, min, mic) \ +- V2V_LIBOSINFO_VERSION_HEX >= MAKE_VERSION_HEX(maj, min, mic) ++ (V2V_LIBOSINFO_VERSION_HEX >= MAKE_VERSION_HEX(maj, min, mic)) + ++/* ++ * libosinfo 1.8.0 provides auto-cleanup functions for all its classes, ++ * so avoid declaring our own. ++ */ ++#if !IS_LIBOSINFO_VERSION(1, 8, 0) + G_DEFINE_AUTOPTR_CLEANUP_FUNC(OsinfoFilter, g_object_unref) + G_DEFINE_AUTOPTR_CLEANUP_FUNC(OsinfoLoader, g_object_unref) + G_DEFINE_AUTOPTR_CLEANUP_FUNC(OsinfoList, g_object_unref) + G_DEFINE_AUTOPTR_CLEANUP_FUNC(OsinfoOsList, g_object_unref) ++#endif + + typedef OsinfoDb *OsinfoDb_t; + typedef OsinfoOs *OsinfoOs_t; +-- +2.18.4 + diff --git a/SOURCES/0010-v2v-Use-common-documentation-for-keys-from-stdin.patch b/SOURCES/0010-v2v-Use-common-documentation-for-keys-from-stdin.patch new file mode 100644 index 0000000..3f52360 --- /dev/null +++ b/SOURCES/0010-v2v-Use-common-documentation-for-keys-from-stdin.patch @@ -0,0 +1,60 @@ +From 6aec975c07d60a2518d3f16ee91db1d03a704882 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 30 Jul 2020 14:01:48 +0100 +Subject: [PATCH] v2v: Use common documentation for --keys-from-stdin. + +(cherry picked from commit 3f9b5f26398694a8a496eae85525e3be5c4b9cca) +--- + common | 2 +- + docs/virt-v2v.pod | 11 ++++------- + 2 files changed, 5 insertions(+), 8 deletions(-) + +Submodule common be42b0b8..5ea1baec: +diff --git a/common/options/Makefile.am b/common/options/Makefile.am +index b38fedc..f7ea749 100644 +--- a/common/options/Makefile.am ++++ b/common/options/Makefile.am +@@ -19,6 +19,7 @@ include $(top_srcdir)/subdir-rules.mk + + EXTRA_DIST = \ + key-option.pod \ ++ keys-from-stdin-option.pod \ + blocksize-option.pod + + # liboptions.la contains guestfish code which is used in other +diff --git a/common/options/keys-from-stdin-option.pod b/common/options/keys-from-stdin-option.pod +new file mode 100644 +index 0000000..03c5339 +--- /dev/null ++++ b/common/options/keys-from-stdin-option.pod +@@ -0,0 +1,4 @@ ++=item B<--keys-from-stdin> ++ ++Read key or passphrase parameters from stdin. The default is ++to try to read passphrases from the user by opening F. +diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod +index a00fa8af..74934eb4 100644 +--- a/docs/virt-v2v.pod ++++ b/docs/virt-v2v.pod +@@ -382,14 +382,11 @@ through VDDK. + + __INCLUDE:key-option.pod__ + +-=item B<--keys-from-stdin> ++__INCLUDE:keys-from-stdin-option.pod__ + +-Read key or passphrase parameters from stdin. The default is +-to try to read passphrases from the user by opening F. +- +-Note this options only applies to keys and passphrases for encrypted +-devices and partitions, not for passwords used to connect to remote +-servers. ++Note I<--keys-from-stdin> only applies to keys and passphrases for ++encrypted devices and partitions, not for passwords used to connect to ++remote servers. + + =item B<--mac> aa:bb:cc:dd:ee:ffB<:network:>out + +-- +2.18.4 + diff --git a/SOURCES/0011-docs-Multiple-keys-must-be-supplied-one-per-line-RHB.patch b/SOURCES/0011-docs-Multiple-keys-must-be-supplied-one-per-line-RHB.patch new file mode 100644 index 0000000..e839fa4 --- /dev/null +++ b/SOURCES/0011-docs-Multiple-keys-must-be-supplied-one-per-line-RHB.patch @@ -0,0 +1,26 @@ +From 37ae5e04bd5f95c0c8a462dc6ef3fbdcfff4af75 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 30 Jul 2020 14:10:18 +0100 +Subject: [PATCH] docs: Multiple keys must be supplied one per line + (RHBZ#1858765). + +(cherry picked from commit 7ba65d14c0139dcf7fec45d33cee67c0f6737dd2) +--- + common | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Submodule common 5ea1baec..9338df5e: +diff --git a/common/options/keys-from-stdin-option.pod b/common/options/keys-from-stdin-option.pod +index 03c5339..8379039 100644 +--- a/common/options/keys-from-stdin-option.pod ++++ b/common/options/keys-from-stdin-option.pod +@@ -2,3 +2,6 @@ + + Read key or passphrase parameters from stdin. The default is + to try to read passphrases from the user by opening F. ++ ++If there are multiple encrypted devices then you may need to supply ++multiple keys on stdin, one per line. +-- +2.18.4 + diff --git a/SOURCES/0012-v2v-Check-that-mac-ip-parameters-are-sensible-RHBZ-1.patch b/SOURCES/0012-v2v-Check-that-mac-ip-parameters-are-sensible-RHBZ-1.patch new file mode 100644 index 0000000..06dfbd4 --- /dev/null +++ b/SOURCES/0012-v2v-Check-that-mac-ip-parameters-are-sensible-RHBZ-1.patch @@ -0,0 +1,126 @@ +From fd1cbaa0907b30f639497c38953fe605bfc68ad0 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 28 Jul 2020 13:20:10 +0100 +Subject: [PATCH] v2v: Check that --mac :ip: parameters are sensible + (RHBZ#1858775). +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is not a complete check since IP addresses come in many forms, +but this at least stops nonsense being written through to the Windows +firstboot script. + +$ virt-v2v --mac 11:22:33:44:55:66:ip:hello,world,999,invalid -i disk test1.img -o null +virt-v2v: error: cannot parse --mac ip ipaddr: doesn’t look like +“hello” is an IP address + +$ virt-v2v --mac 11:22:33:44:55:66:ip:192.168.0.10,192.168.0.1,999,192.168.2.1,192.168.2.2 -i disk test1.img -o null +virt-v2v: error: --mac ip prefix length field is out of range + +Thanks: Zi Liu +(cherry picked from commit e8bcf9615490447e1b53a8b0d3e9d202ab178cf0) +--- + v2v/cmdline.ml | 55 ++++++++++++++++++++++++++++++++------------------ + 1 file changed, 35 insertions(+), 20 deletions(-) + +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index 249137ab..3b74f307 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -47,6 +47,7 @@ type cmdline = { + + (* Matches --mac command line parameters. *) + let mac_re = PCRE.compile ~anchored:true "([[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}):(network|bridge|ip):(.*)" ++let mac_ip_re = PCRE.compile ~anchored:true "([[:xdigit:]]|:|\\.)+" + + let parse_cmdline () = + let bandwidth = ref None in +@@ -102,7 +103,7 @@ let parse_cmdline () = + + let network_map = Networks.create () in + let static_ips = ref [] in +- let add_network str = ++ let rec add_network str = + match String.split ":" str with + | "", "" -> + error (f_"invalid -n/--network parameter") +@@ -110,8 +111,7 @@ let parse_cmdline () = + Networks.add_default_network network_map out + | in_, out -> + Networks.add_network network_map in_ out +- in +- let add_bridge str = ++ and add_bridge str = + match String.split ":" str with + | "", "" -> + error (f_"invalid -b/--bridge parameter") +@@ -119,8 +119,7 @@ let parse_cmdline () = + Networks.add_default_bridge network_map out + | in_, out -> + Networks.add_bridge network_map in_ out +- in +- let add_mac str = ++ and add_mac str = + if not (PCRE.matches mac_re str) then + error (f_"cannot parse --mac \"%s\" parameter") str; + let mac = PCRE.sub 1 and out = PCRE.sub 3 in +@@ -130,24 +129,40 @@ let parse_cmdline () = + | "bridge" -> + Networks.add_mac network_map mac Bridge out + | "ip" -> +- let add if_mac_addr if_ip_address if_default_gateway +- if_prefix_length if_nameservers = +- List.push_back static_ips +- { if_mac_addr; if_ip_address; if_default_gateway; +- if_prefix_length; if_nameservers } +- in + (match String.nsplit "," out with +- | [] -> +- error (f_"invalid --mac ip option") +- | [ip] -> add mac ip None None [] +- | [ip; gw] -> add mac ip (Some gw) None [] ++ | [] -> error (f_"invalid --mac ip option") ++ | [ip] -> add_static_ip mac ip None None [] ++ | [ip; gw] -> add_static_ip mac ip (Some gw) None [] + | ip :: gw :: len :: nameservers -> +- let len = +- try int_of_string len with +- | Failure _ -> error (f_"cannot parse --mac ip prefix length field as an integer: %s") len in +- add mac ip (Some gw) (Some len) nameservers +- ); ++ add_static_ip mac ip (Some gw) (Some len) nameservers ++ ) + | _ -> assert false ++ and add_static_ip if_mac_addr if_ip_address if_default_gateway ++ if_prefix_length_str if_nameservers = ++ (* Check the IP addresses and prefix length are sensible. This ++ * is only a very simple test that they are sane, since IP addresses ++ * come in too many valid forms to check thoroughly. ++ *) ++ let rec error_unless_ip_addr what addr = ++ if not (PCRE.matches mac_ip_re addr) then ++ error (f_"cannot parse --mac ip %s: doesn’t look like “%s” is an IP address") what addr ++ in ++ error_unless_ip_addr "ipaddr" if_ip_address; ++ Option.may (error_unless_ip_addr "gw") if_default_gateway; ++ List.iter (error_unless_ip_addr "nameserver") if_nameservers; ++ let if_prefix_length = ++ match if_prefix_length_str with ++ | None -> None ++ | Some len -> ++ let len = ++ try int_of_string len with ++ | Failure _ -> error (f_"cannot parse --mac ip prefix length field as an integer: %s") len in ++ if len < 0 || len > 128 then ++ error (f_"--mac ip prefix length field is out of range"); ++ Some len in ++ List.push_back static_ips ++ { if_mac_addr; if_ip_address; if_default_gateway; ++ if_prefix_length; if_nameservers } + in + + let no_trim_warning _ = +-- +2.18.4 + diff --git a/SOURCES/0013-libvirt-read-password-file-outside-libvirt-auth-call.patch b/SOURCES/0013-libvirt-read-password-file-outside-libvirt-auth-call.patch new file mode 100644 index 0000000..de76247 --- /dev/null +++ b/SOURCES/0013-libvirt-read-password-file-outside-libvirt-auth-call.patch @@ -0,0 +1,33 @@ +From 207552533f0b4ed2e2d570a827a85a44d4248b78 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Mon, 17 Aug 2020 09:17:51 +0200 +Subject: [PATCH] libvirt: read password file outside libvirt auth callback + +This way errors that occur while reading the password file are properly +propagated, instead of being reported as errors of the libvirt +authentication callback. + +Reported by: Ming Xie. + +(cherry picked from commit 76f9f3a0603f33c85d681fe13e24516331c6aea7) +--- + v2v/libvirt_utils.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/libvirt_utils.ml b/v2v/libvirt_utils.ml +index 4d0b8639..1a24b049 100644 +--- a/v2v/libvirt_utils.ml ++++ b/v2v/libvirt_utils.ml +@@ -24,8 +24,8 @@ open Common_gettext.Gettext + module. *) + + let auth_for_password_file ?password_file () = ++ let password = Option.map read_first_line_from_file password_file in + let auth_fn creds = +- let password = Option.map read_first_line_from_file password_file in + List.map ( + function + | { Libvirt.Connect.typ = Libvirt.Connect.CredentialPassphrase } -> password +-- +2.18.4 + diff --git a/SOURCES/0014-RHEL-8-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch b/SOURCES/0014-RHEL-8-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch new file mode 100644 index 0000000..b965f2d --- /dev/null +++ b/SOURCES/0014-RHEL-8-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch @@ -0,0 +1,33 @@ +From 9331544f2456f1aef7299920d0c84dff4e47d132 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sun, 28 Sep 2014 19:14:43 +0100 +Subject: [PATCH] RHEL 8: v2v: Select correct qemu binary for -o qemu mode + (RHBZ#1147313). + +RHEL 8 does not have qemu-system-x86_64 (etc), and in addition the +qemu binary is located in /usr/libexec. Encode the path to this +binary directly in the script. + +Note that we don't support people running qemu directly like this. +It's just for quick testing of converted VMs, and to help us with +support cases. +--- + v2v/output_qemu.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml +index be3a3c5e..85d08265 100644 +--- a/v2v/output_qemu.ml ++++ b/v2v/output_qemu.ml +@@ -81,7 +81,7 @@ object + * module deals with shell and qemu comma quoting. + *) + let cmd = Qemuopts.create () in +- Qemuopts.set_binary_by_arch cmd (Some guestcaps.gcaps_arch); ++ Qemuopts.set_binary cmd "/usr/libexec/qemu-kvm"; + + let flag = Qemuopts.flag cmd + and arg = Qemuopts.arg cmd +-- +2.18.4 + diff --git a/SOURCES/0015-RHEL-8-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch b/SOURCES/0015-RHEL-8-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch new file mode 100644 index 0000000..cc2570f --- /dev/null +++ b/SOURCES/0015-RHEL-8-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch @@ -0,0 +1,105 @@ +From 7df465dede750140bbc5a2579a5256061af63e03 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 30 Sep 2014 10:50:27 +0100 +Subject: [PATCH] RHEL 8: v2v: Disable the --qemu-boot option (RHBZ#1147313). + +This cannot work because there is no Gtk or SDL output mode +in RHEL 8's qemu-kvm. + +In addition you will have to edit the -display option in the +qemu script. +--- + docs/virt-v2v-output-local.pod | 6 ++---- + docs/virt-v2v.pod | 13 ------------- + v2v/cmdline.ml | 3 ++- + 3 files changed, 4 insertions(+), 18 deletions(-) + +diff --git a/docs/virt-v2v-output-local.pod b/docs/virt-v2v-output-local.pod +index a5f155cb..3a2e6238 100644 +--- a/docs/virt-v2v-output-local.pod ++++ b/docs/virt-v2v-output-local.pod +@@ -9,7 +9,7 @@ or libvirt + + virt-v2v [-i* options] -o local -os DIRECTORY + +- virt-v2v [-i* options] -o qemu -os DIRECTORY [--qemu-boot] ++ virt-v2v [-i* options] -o qemu -os DIRECTORY + + virt-v2v [-i* options] -o json -os DIRECTORY + [-oo json-disks-pattern=PATTERN] +@@ -50,12 +50,10 @@ where C is the guest name. + + =item B<-o qemu -os> C + +-=item B<-o qemu -os> C B<--qemu-boot> +- + This converts the guest to files in C. Unlike I<-o local> + above, a shell script is created which contains the raw qemu command + you would need to boot the guest. However the shell script is not +-run, I you also add the I<--qemu-boot> option. ++run. + + =item B<-o json -os> C + +diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod +index 74934eb4..a19f0a73 100644 +--- a/docs/virt-v2v.pod ++++ b/docs/virt-v2v.pod +@@ -144,11 +144,6 @@ Since F contains the path(s) to the guest disk + image(s) you do not need to specify the name of the disk image on the + command line. + +-To convert a local disk image and immediately boot it in local +-qemu, do: +- +- virt-v2v -i disk disk.img -o qemu -os /var/tmp --qemu-boot +- + =head1 OPTIONS + + =over 4 +@@ -537,9 +532,6 @@ This is similar to I<-o local>, except that a shell script is written + which you can use to boot the guest in qemu. The converted disks and + shell script are written to the directory specified by I<-os>. + +-When using this output mode, you can also specify the I<--qemu-boot> +-option which boots the guest under qemu immediately. +- + =item B<-o> B + + This is the same as I<-o rhv>. +@@ -815,11 +807,6 @@ Print information about the source guest and stop. This option is + useful when you are setting up network and bridge maps. + See L. + +-=item B<--qemu-boot> +- +-When using I<-o qemu> only, this boots the guest immediately after +-virt-v2v finishes. +- + =item B<-q> + + =item B<--quiet> +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index 3b74f307..df69e2e0 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -284,7 +284,6 @@ let parse_cmdline () = + s_"Estimate size of source and stop"; + [ L"print-source" ], Getopt.Set print_source, + s_"Print source and stop"; +- [ L"qemu-boot" ], Getopt.Set qemu_boot, s_"Boot in qemu (-o qemu only)"; + [ L"root" ], Getopt.String ("ask|... ", set_root_choice), + s_"How to choose root filesystem"; + [ L"vddk-config" ], Getopt.String ("filename", set_input_option_compat "vddk-config"), +@@ -668,6 +667,8 @@ read the man page virt-v2v(1). + | Some d when not (is_directory d) -> + error (f_"-os %s: output directory does not exist or is not a directory") d + | Some d -> d in ++ if qemu_boot then ++ error (f_"-o qemu: the --qemu-boot option cannot be used in RHEL"); + Output_qemu.output_qemu os qemu_boot, + output_format, output_alloc + +-- +2.18.4 + diff --git a/SOURCES/0016-RHEL-8-Fix-list-of-supported-sound-cards-to-match-RH.patch b/SOURCES/0016-RHEL-8-Fix-list-of-supported-sound-cards-to-match-RH.patch new file mode 100644 index 0000000..9eda717 --- /dev/null +++ b/SOURCES/0016-RHEL-8-Fix-list-of-supported-sound-cards-to-match-RH.patch @@ -0,0 +1,34 @@ +From ff5ae6613f5b344371cd8523a022af08fa6f191b Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 24 Apr 2015 09:45:41 -0400 +Subject: [PATCH] RHEL 8: Fix list of supported sound cards to match RHEL qemu + (RHBZ#1176493). + +--- + v2v/utils.ml | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/v2v/utils.ml b/v2v/utils.ml +index ccbb9d68..c2940582 100644 +--- a/v2v/utils.ml ++++ b/v2v/utils.ml +@@ -55,13 +55,14 @@ let kvm_arch = function + (* Does qemu support the given sound card? *) + let qemu_supports_sound_card = function + | Types.AC97 +- | Types.ES1370 + | Types.ICH6 + | Types.ICH9 + | Types.PCSpeaker ++ -> true ++ | Types.ES1370 + | Types.SB16 + | Types.USBAudio +- -> true ++ -> false + + (* Find the UEFI firmware. *) + let find_uefi_firmware guest_arch = +-- +2.18.4 + diff --git a/SOURCES/0017-RHEL-8-Fix-tests-for-libguestfs-winsupport.patch b/SOURCES/0017-RHEL-8-Fix-tests-for-libguestfs-winsupport.patch new file mode 100644 index 0000000..bdd9f58 --- /dev/null +++ b/SOURCES/0017-RHEL-8-Fix-tests-for-libguestfs-winsupport.patch @@ -0,0 +1,79 @@ +From d6b625021e4bc1662b796e8c2f2a646d118f9fa1 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sun, 30 Aug 2015 03:21:57 -0400 +Subject: [PATCH] RHEL 8: Fix tests for libguestfs-winsupport. + +It doesn't let us use guestfish for arbitrary Windows edits. +--- + test-data/phony-guests/make-windows-img.sh | 1 + + tests/test-v2v-virtio-win-iso.sh | 8 +++++++- + tests/test-v2v-windows-conversion.sh | 8 +++++++- + 3 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh +index 30908a91..73cf5144 100755 +--- a/test-data/phony-guests/make-windows-img.sh ++++ b/test-data/phony-guests/make-windows-img.sh +@@ -37,6 +37,7 @@ fi + + # Create a disk image. + guestfish < "$script" + :> "$expected" + ++cat >> "$script" < "$response" ++guestfish --ro -a "$d/windows-sda" < "$script" > "$response" + diff -u "$expected" "$response" + + rm -r $d +diff --git a/tests/test-v2v-windows-conversion.sh b/tests/test-v2v-windows-conversion.sh +index f1da222a..ff94fe39 100755 +--- a/tests/test-v2v-windows-conversion.sh ++++ b/tests/test-v2v-windows-conversion.sh +@@ -73,6 +73,12 @@ mktest () + :> "$script" + :> "$expected" + ++cat >> "$script" < "$response" ++guestfish --ro -a "$d/windows-sda" < "$script" > "$response" + diff -u "$expected" "$response" + + # We also update the Registry several times, for firstboot, and (ONLY +-- +2.18.4 + diff --git a/SOURCES/0018-RHEL-8-v2v-Disable-the-virt-v2v-in-place-option.patch b/SOURCES/0018-RHEL-8-v2v-Disable-the-virt-v2v-in-place-option.patch new file mode 100644 index 0000000..31d01d5 --- /dev/null +++ b/SOURCES/0018-RHEL-8-v2v-Disable-the-virt-v2v-in-place-option.patch @@ -0,0 +1,286 @@ +From d55dcb095a383ff924acbfbe1c81a3a1eb4f4495 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 14 Jan 2016 11:53:42 -0500 +Subject: [PATCH] RHEL 8: v2v: Disable the virt-v2v --in-place option. + +This disables the virt-v2v --in-place option which we do not +wish to support in RHEL. +(See commit d0069559a939e47e5f29973ed9a69a13f0b58301). +--- + docs/test-v2v-docs.sh | 1 + + docs/virt-v2v.pod | 48 +---------------- + tests/Makefile.am | 2 - + tests/test-v2v-in-place.sh | 108 ------------------------------------- + v2v/cmdline.ml | 8 +-- + 5 files changed, 7 insertions(+), 160 deletions(-) + delete mode 100755 tests/test-v2v-in-place.sh + +diff --git a/docs/test-v2v-docs.sh b/docs/test-v2v-docs.sh +index dd2b1233..8fef46cc 100755 +--- a/docs/test-v2v-docs.sh ++++ b/docs/test-v2v-docs.sh +@@ -27,6 +27,7 @@ $top_srcdir/podcheck.pl virt-v2v.pod virt-v2v \ + --debug-overlay,\ + --ic,\ + --if,\ ++--in-place,\ + --io,\ + --ip,\ + --it,\ +diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod +index a19f0a73..6f9f323e 100644 +--- a/docs/virt-v2v.pod ++++ b/docs/virt-v2v.pod +@@ -8,10 +8,6 @@ virt-v2v - Convert a guest to use KVM + [-o mode] [other -o* options] + [guest|filename] + +- virt-v2v --in-place +- [-i mode] [other -i* options] +- [guest|filename] +- + =head1 DESCRIPTION + + Virt-v2v converts a single guest from a foreign hypervisor to run on +@@ -39,9 +35,6 @@ these sides of virt-v2v are documented separately in this manual. + + Virt-v2v normally copies from the input to the output, called "copying + mode". In this case the source guest is always left unchanged. +-In-place conversion (I<--in-place>) only uses the I<-i*> options and +-modifies the source guest in-place. (See L +-below.) + + =head2 Other virt-v2v topics + +@@ -301,20 +294,6 @@ For I<-i disk> only, this specifies the format of the input disk + image. For other input methods you should specify the input + format in the metadata. + +-=item B<--in-place> +- +-Do not create an output virtual machine in the target hypervisor. +-Instead, adjust the guest OS in the source VM to run in the input +-hypervisor. +- +-This mode is meant for integration with other toolsets, which take the +-responsibility of converting the VM configuration, providing for +-rollback in case of errors, transforming the storage, etc. +- +-See L below. +- +-Conflicts with all I<-o *> options. +- + =item B<-io> OPTION=VALUE + + Set input option(s) related to the current input mode or transport. +@@ -1332,7 +1311,7 @@ have at least 100 available inodes. + =head3 Minimum free space check in the host + + You must have sufficient free space in the host directory used to +-store temporary overlays (except in I<--in-place> mode). To find out ++store temporary overlays. To find out + which directory this is, use: + + $ df -h "`guestfish get-cachedir`" +@@ -1435,31 +1414,6 @@ that instead. + + + +-=head2 In-place conversion +- +-It is also possible to use virt-v2v in scenarios where a foreign VM +-has already been imported into a KVM-based hypervisor, but still needs +-adjustments in the guest to make it run in the new virtual hardware. +- +-In that case it is assumed that a third-party tool has created the +-target VM in the supported KVM-based hypervisor based on the source VM +-configuration and contents, but using virtual devices more appropriate +-for KVM (e.g. virtio storage and network, etc.). +- +-Then, to make the guest OS boot and run in the changed environment, +-one can use: +- +- virt-v2v -ic qemu:///system converted_vm --in-place +- +-Virt-v2v will analyze the configuration of C in the +-C libvirt instance, and apply various fixups to the +-guest OS configuration to make it match the VM configuration. This +-may include installing virtio drivers, configuring the bootloader, the +-mountpoints, the network interfaces, and so on. +- +-Should an error occur during the operation, virt-v2v exits with an +-error code leaving the VM in an undefined state. +- + =head2 Machine readable output + + The I<--machine-readable> option can be used to make the output more +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 871dc3c9..eee4e1af 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -76,7 +76,6 @@ TESTS = \ + test-v2v-floppy.sh \ + test-v2v-i-disk.sh \ + test-v2v-i-ova.sh \ +- test-v2v-in-place.sh \ + test-v2v-mac.sh \ + test-v2v-machine-readable.sh \ + test-v2v-networks-and-bridges.sh \ +@@ -225,7 +224,6 @@ EXTRA_DIST += \ + test-v2v-i-vmx-3.vmx \ + test-v2v-i-vmx-4.vmx \ + test-v2v-i-vmx-5.vmx \ +- test-v2v-in-place.sh \ + test-v2v-it-vddk-io-query.sh \ + test-v2v-machine-readable.sh \ + test-v2v-mac-expected.xml \ +diff --git a/tests/test-v2v-in-place.sh b/tests/test-v2v-in-place.sh +deleted file mode 100755 +index 6f7d78f3..00000000 +--- a/tests/test-v2v-in-place.sh ++++ /dev/null +@@ -1,108 +0,0 @@ +-#!/bin/bash - +-# libguestfs virt-v2v test script +-# Copyright (C) 2014 Red Hat Inc. +-# Copyright (C) 2015 Parallels IP Holdings GmbH. +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or +-# (at your option) any later version. +-# +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program; if not, write to the Free Software +-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +- +-# Test --in-place. +- +-unset CDPATH +-export LANG=C +-set -e +- +-$TEST_FUNCTIONS +-skip_if_skipped +-skip_if_backend uml +-skip_unless_phony_guest windows.img +- +-img_base="$abs_top_builddir/test-data/phony-guests/windows.img" +- +-export VIRT_TOOLS_DATA_DIR="$top_srcdir/test-data/fake-virt-tools" +-export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win" +- +-d=$PWD/test-v2v-in-place.d +-rm -rf $d +-mkdir $d +- +-img="$d/test.qcow2" +-rm -f $img +-qemu-img create -f qcow2 -b $img_base -o compat=1.1,backing_fmt=raw $img +-md5="$(do_md5 $img_base)" +- +-libvirt_xml="$d/test.xml" +-rm -f $libvirt_xml +-n=windows-overlay +-cat > $libvirt_xml < +- +- $n +- 1048576 +- +- hvm +- +- +- +- +- +- +- +- +- +- +- +-EOF +- +-$VG virt-v2v --debug-gc -i libvirt -ic "test://$libvirt_xml" $n --in-place +- +-# Test that the drivers have been copied over into the guest +-script="$d/test.fish" +-expected="$d/expected" +-response="$d/response" +- +-mktest () +-{ +- local cmd="$1" exp="$2" +- +- echo "echo '$cmd'" >> "$script" +- echo "$cmd" >> "$expected" +- +- echo "$cmd" >> "$script" +- echo "$exp" >> "$expected" +-} +- +-:> "$script" +-:> "$expected" +- +-firstboot_dir="/Program Files/Guestfs/Firstboot" +-mktest "is-dir \"$firstboot_dir\"" true +-mktest "is-file \"$firstboot_dir/firstboot.bat\"" true +-mktest "is-dir \"$firstboot_dir/scripts\"" true +-virtio_dir="/Windows/Drivers/VirtIO" +-mktest "is-dir \"$virtio_dir\"" true +-for drv in netkvm qxl vioscsi viostor; do +- for sfx in cat inf sys; do +- mktest "is-file \"$virtio_dir/$drv.$sfx\"" true +- done +-done +- +-guestfish --ro -a "$img" -i < "$script" > "$response" +-diff -u "$expected" "$response" +- +-# Test the base image remained untouched +-test "$md5" = "$(do_md5 $img_base)" +- +-# Clean up. +-rm -r $d +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index df69e2e0..7b79d462 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -252,8 +252,7 @@ let parse_cmdline () = + s_"Use password from file to connect to input hypervisor"; + [ M"it" ], Getopt.String ("transport", set_string_option_once "-it" input_transport), + s_"Input transport"; +- [ L"in-place" ], Getopt.Set in_place, +- s_"Only tune the guest in the input VM"; ++ [ L"in-place" ], Getopt.Set in_place, Getopt.hidden_option_description; + [ L"mac" ], Getopt.String ("mac:network|bridge|ip:out", add_mac), + s_"Map NIC to network or bridge or assign static IP"; + [ S 'n'; L"network" ], Getopt.String ("in:out", add_network), +@@ -396,7 +395,6 @@ read the man page virt-v2v(1). + pr "vddk\n"; + pr "colours-option\n"; + pr "vdsm-compat-option\n"; +- pr "in-place\n"; + pr "io/oo\n"; + pr "mac-option\n"; + pr "bandwidth-option\n"; +@@ -572,6 +570,10 @@ read the man page virt-v2v(1). + error (f_"only ‘-it ssh’ can be used here") in + Input_vmx.input_vmx input_password input_transport arg in + ++ (* Prevent use of --in-place option in RHEL. *) ++ if in_place then ++ error (f_"--in-place cannot be used in RHEL"); ++ + (* Common error message. *) + let error_option_cannot_be_used_in_output_mode mode opt = + error (f_"-o %s: %s option cannot be used in this output mode") mode opt +-- +2.18.4 + diff --git a/SOURCES/0019-RHEL-8-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch b/SOURCES/0019-RHEL-8-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch new file mode 100644 index 0000000..4e6fb58 --- /dev/null +++ b/SOURCES/0019-RHEL-8-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch @@ -0,0 +1,26 @@ +From ca9e31a9ae2e9cf5df5c65955ad746ee9f8d560b Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 2 Mar 2017 14:21:37 +0100 +Subject: [PATCH] RHEL 8: v2v: -i disk: force VNC as display (RHBZ#1372671) + +The SDL output mode is not supported in RHEL 8's qemu-kvm. +--- + v2v/input_disk.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/input_disk.ml b/v2v/input_disk.ml +index d146e84c..4e403003 100644 +--- a/v2v/input_disk.ml ++++ b/v2v/input_disk.ml +@@ -89,7 +89,7 @@ class input_disk input_format disk = object + s_features = [ "acpi"; "apic"; "pae" ]; + s_firmware = UnknownFirmware; (* causes virt-v2v to autodetect *) + s_display = +- Some { s_display_type = Window; s_keymap = None; s_password = None; ++ Some { s_display_type = VNC; s_keymap = None; s_password = None; + s_listen = LNoListen; s_port = None }; + s_video = None; + s_sound = None; +-- +2.18.4 + diff --git a/SOURCES/0020-RHEL-8-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch b/SOURCES/0020-RHEL-8-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch new file mode 100644 index 0000000..86a19a5 --- /dev/null +++ b/SOURCES/0020-RHEL-8-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch @@ -0,0 +1,26 @@ +From 959c084383b259ff54a247b4fdda3254e3f335db Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Wed, 8 Mar 2017 11:03:40 +0100 +Subject: [PATCH] RHEL 8: v2v: do not mention SUSE Xen hosts (RHBZ#1430203) + +They are not supported in RHEL 8. +--- + docs/virt-v2v-input-xen.pod | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/docs/virt-v2v-input-xen.pod b/docs/virt-v2v-input-xen.pod +index 3b3cf0f0..32da2848 100644 +--- a/docs/virt-v2v-input-xen.pod ++++ b/docs/virt-v2v-input-xen.pod +@@ -12,7 +12,7 @@ virt-v2v-input-xen - Using virt-v2v to convert guests from Xen + =head1 DESCRIPTION + + This page documents how to use L to convert guests from +-RHEL 5 Xen, or SLES and OpenSUSE Xen hosts. ++RHEL 5 Xen hosts. + + =head1 INPUT FROM XEN + +-- +2.18.4 + diff --git a/SOURCES/0021-RHEL-8-v2v-rhv-upload-Remove-restriction-on-oa-spars.patch b/SOURCES/0021-RHEL-8-v2v-rhv-upload-Remove-restriction-on-oa-spars.patch new file mode 100644 index 0000000..1040963 --- /dev/null +++ b/SOURCES/0021-RHEL-8-v2v-rhv-upload-Remove-restriction-on-oa-spars.patch @@ -0,0 +1,89 @@ +From 4bd92b1fc4f830529b439c4a4e09281fcd9eab78 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 14 May 2018 10:16:58 +0100 +Subject: [PATCH] RHEL 8: v2v: rhv-upload: Remove restriction on -oa sparse. + +See: https://bugzilla.redhat.com/show_bug.cgi?id=1565681 +and the v2v-devel private thread "Do we already support migration using FC?" +--- + docs/virt-v2v-output-rhv.pod | 8 +------- + v2v/output_rhv_upload.ml | 10 +--------- + v2v/rhv-upload-plugin.py | 4 +--- + 3 files changed, 3 insertions(+), 19 deletions(-) + +diff --git a/docs/virt-v2v-output-rhv.pod b/docs/virt-v2v-output-rhv.pod +index 7c9b478a..36c3676f 100644 +--- a/docs/virt-v2v-output-rhv.pod ++++ b/docs/virt-v2v-output-rhv.pod +@@ -5,7 +5,7 @@ virt-v2v-output-rhv - Using virt-v2v to convert guests to oVirt or RHV + =head1 SYNOPSIS + + virt-v2v [-i* options] -o rhv-upload [-oc ENGINE_URL] -os STORAGE +- [-op PASSWORD] [-of raw] ++ [-op PASSWORD] + [-oo rhv-cafile=FILE] + [-oo rhv-cluster=CLUSTER] + [-oo rhv-direct] +@@ -79,12 +79,6 @@ username is not specified then virt-v2v defaults to using + C which is the typical superuser account for oVirt + instances. + +-=item I<-of raw> +- +-Currently you must use I<-of raw> and you cannot use I<-oa preallocated>. +- +-These restrictions will be loosened in a future version. +- + =item I<-op> F + + A file containing a password to be used when connecting to the oVirt +diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml +index 5c6c2611..81896e53 100644 +--- a/v2v/output_rhv_upload.ml ++++ b/v2v/output_rhv_upload.ml +@@ -135,17 +135,10 @@ let error_unless_nbdkit_compiled_with_selinux config = + error (f_"nbdkit was compiled without SELinux support. You will have to recompile nbdkit with libselinux-devel installed, or else set SELinux to Permissive mode while doing the conversion.") + ) + +-(* Output sparse must be sparse. We may be able to +- * lift this limitation in future, but it requires changes on the +- * RHV side. See TODO file for details. XXX +- *) ++(* Output format must be raw. *) + let error_current_limitation required_param = + error (f_"rhv-upload: currently you must use ‘%s’. This restriction will be loosened in a future version.") required_param + +-let error_unless_output_alloc_sparse output_alloc = +- if output_alloc <> Sparse then +- error_current_limitation "-oa sparse" +- + let json_optstring = function + | Some s -> JSON.String s + | None -> JSON.Null +@@ -247,7 +240,6 @@ object + error_unless_nbdkit_min_version config; + error_unless_nbdkit_python_plugin_working plugin_script; + error_unless_nbdkit_compiled_with_selinux config; +- error_unless_output_alloc_sparse output_alloc; + + (* Python code prechecks. *) + let precheck_fn = tmpdir // "v2vprecheck.json" in +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index d3e6260e..471102da 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -477,10 +477,8 @@ def create_disk(connection): + # size, based on qemu-img measure of the overlay. + initial_size=params['disk_size'], + provisioned_size=params['disk_size'], +- # XXX Ignores params['output_sparse']. +- # Handling this properly will be complex, see: + # https://www.redhat.com/archives/libguestfs/2018-March/msg00177.html +- sparse=True, ++ sparse=params['output_sparse'], + storage_domains=[ + types.StorageDomain( + name=params['output_storage'], +-- +2.18.4 + diff --git a/SOURCES/0022-RHEL-8-use-platform-python.patch b/SOURCES/0022-RHEL-8-use-platform-python.patch new file mode 100644 index 0000000..2a57635 --- /dev/null +++ b/SOURCES/0022-RHEL-8-use-platform-python.patch @@ -0,0 +1,27 @@ +From ca86a08fe00a56a21d239cb6d1ca6dc9f8ff28fa Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Sun, 16 Dec 2018 16:42:46 +0100 +Subject: [PATCH] RHEL 8: use platform-python + +Use the stable platform-python provided in BaseOS, instead of relying on +some arbitrary version installed by the user. +--- + v2v/python_script.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/python_script.ml b/v2v/python_script.ml +index 33c5e9a2..b1ea8f9d 100644 +--- a/v2v/python_script.ml ++++ b/v2v/python_script.ml +@@ -24,7 +24,7 @@ open Unix_utils + + open Common_gettext.Gettext + +-let python = "python3" (* Defined by PEP 394 *) ++let python = "/usr/libexec/platform-python" + + type script = { + tmpdir : string; (* Temporary directory. *) +-- +2.18.4 + diff --git a/SOURCES/0023-RHEL-8-point-to-KB-for-supported-v2v-hypervisors-gue.patch b/SOURCES/0023-RHEL-8-point-to-KB-for-supported-v2v-hypervisors-gue.patch new file mode 100644 index 0000000..abeb02f --- /dev/null +++ b/SOURCES/0023-RHEL-8-point-to-KB-for-supported-v2v-hypervisors-gue.patch @@ -0,0 +1,125 @@ +From 1de8532631a765c03196774e0b4a41966284bae3 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 26 Mar 2019 09:42:25 +0100 +Subject: [PATCH] RHEL 8: point to KB for supported v2v hypervisors/guests + +--- + docs/virt-v2v-support.pod | 102 ++------------------------------------ + 1 file changed, 4 insertions(+), 98 deletions(-) + +diff --git a/docs/virt-v2v-support.pod b/docs/virt-v2v-support.pod +index 8333366b..a5150907 100644 +--- a/docs/virt-v2v-support.pod ++++ b/docs/virt-v2v-support.pod +@@ -8,104 +8,10 @@ systems and guests in virt-v2v + This page documents which foreign hypervisors, virtualization + management systems and guest types that L can support. + +-Note this page applies to upstream virt-v2v from +-L and in downstream distributions of virt-v2v +-sometimes features are intentionally removed, or are present but not +-supported. +- +-=head2 Hypervisors (Input) +- +-=over 4 +- +-=item VMware ESXi +- +-Must be managed by VMware vCenter E 5.0 unless VDDK is available. +- +-=item OVA exported from VMware +- +-OVAs from other hypervisors will not work. +- +-=item VMX from VMware +- +-VMX files generated by other hypervisors will not work. +- +-=item RHEL 5 Xen +- +-=item SUSE Xen +- +-=item Citrix Xen +- +-Citrix Xen has not been recently tested. +- +-=item Hyper-V +- +-Not recently tested. Requires that you export the disk or use +-L on Hyper-V. +- +-=item Direct from disk images +- +-Only disk images exported from supported hypervisors, and using +-container formats supported by qemu. +- +-=item Physical machines +- +-Using the L tool. +- +-=back +- +-=head2 Hypervisors (Output) +- +-QEMU and KVM only. +- +-=head2 Virtualization management systems (Output) +- +-=over 4 +- +-=item OpenStack +- +-=item Red Hat Virtualization (RHV) 4.1 and up +- +-=item Local libvirt +- +-And hence L, L, and similar tools. +- +-=item Local disk +- +-=back +- +-=head2 Guests +- +-=over 4 +- +-=item Red Hat Enterprise Linux 3, 4, 5, 6, 7 +- +-=item CentOS 3, 4, 5, 6, 7 +- +-=item Scientific Linux 3, 4, 5, 6, 7 +- +-=item Oracle Linux +- +-=item Fedora +- +-=item SLES 10 and up +- +-=item OpenSUSE 10 and up +- +-=item Debian 6 and up +- +-=item Ubuntu 10.04, 12.04, 14.04, 16.04, and up +- +-=item Windows XP to Windows 10 / Windows Server 2016 +- +-We use Windows internal version numbers, see +-L +- +-Currently NT 5.2 to NT 6.3 are supported. +- +-See L below for additional notes on converting Windows +-guests. +- +-=back ++For more information on supported hypervisors, and guest types in ++RHEL, please consult the following Knowledgebase article on these ++Red Hat Customer Portal: ++L. + + =head2 Guest firmware + +-- +2.18.4 + diff --git a/SOURCES/0024-v2v-Allow-large-temporary-directory-to-be-set-on-a-g.patch b/SOURCES/0024-v2v-Allow-large-temporary-directory-to-be-set-on-a-g.patch new file mode 100644 index 0000000..1c11564 --- /dev/null +++ b/SOURCES/0024-v2v-Allow-large-temporary-directory-to-be-set-on-a-g.patch @@ -0,0 +1,388 @@ +From 186c237ac1cb6f6830cfe2d08dfdcfdbdffab264 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 6 Apr 2020 10:19:12 +0100 +Subject: [PATCH] v2v: Allow large temporary directory to be set on a global + basis. + +Previously we placed large files in g#get_cachedir () (usually +/var/tmp). However the problem is this ties the libguestfs appliance +and the virt-v2v overlay files to the same location. + +When virt-v2v is run in a container, or any other situation where +local storage is limited, it's helpful to be able to put the overlay +files on an externally mounted PVC, which might be using NFS and +shared between containers. But putting the libguestfs appliance on +NFS in a shared location is certainly not recommended. + +This allows the two locations to be set separately: + + VIRT_V2V_TMPDIR - location of large temporary files, can use NFS + and may be shared + + LIBGUESTFS_CACHEDIR - location of libguestfs appliance + +Another motivation for this patch is to allow more reliable cleanup of +large temporary files by an external process, as described in the +updated documentation. + +Small temporary files are placed in $TMPDIR (usually /tmp). I cleaned +up some existing code which used /var/tmp for small temporaries. + +(cherry picked from commit 717b808bc5cb632778973eb000600e87eaf5c31a) +--- + docs/virt-v2v.pod | 27 +++++++++++++++++++-------- + v2v/input_ova.ml | 4 ++-- + v2v/input_vmx.ml | 3 +-- + v2v/output_glance.ml | 3 +-- + v2v/output_null.ml | 3 +-- + v2v/output_rhv_upload.ml | 29 ++++++++++++++++------------- + v2v/parse_ova.ml | 6 ++---- + v2v/python_script.ml | 12 +++--------- + v2v/python_script.mli | 5 +---- + v2v/utils.ml | 6 +++++- + v2v/utils.mli | 5 +++++ + v2v/v2v.ml | 14 ++++++-------- + 12 files changed, 62 insertions(+), 55 deletions(-) + +diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod +index 6f9f323e..af69d633 100644 +--- a/docs/virt-v2v.pod ++++ b/docs/virt-v2v.pod +@@ -1172,8 +1172,8 @@ possible. + =head3 Disk space + + Virt-v2v places potentially large temporary files in +-C<$LIBGUESTFS_CACHEDIR> (which is F if you don't set it). +-Using tmpfs is a bad idea. ++C<$VIRT_V2V_TMPDIR> (usually F, see also ++L below). Using tmpfs is a bad idea. + + For each guest disk, an overlay is stored temporarily. This stores + the changes made during conversion, and is used as a cache. The +@@ -1186,12 +1186,12 @@ and output methods may use disk space, as outlined in the table below. + =item I<-i ova> + + This temporarily places a full copy of the uncompressed source disks +-in C<$LIBGUESTFS_CACHEDIR> (or F). ++in C<$VIRT_V2V_TMPDIR> (or F). + + =item I<-o glance> + + This temporarily places a full copy of the output disks in +-C<$LIBGUESTFS_CACHEDIR> (or F). ++C<$VIRT_V2V_TMPDIR> (or F). + + =item I<-o local> + +@@ -1311,7 +1311,7 @@ have at least 100 available inodes. + =head3 Minimum free space check in the host + + You must have sufficient free space in the host directory used to +-store temporary overlays. To find out ++store large temporary overlays. To find out + which directory this is, use: + + $ df -h "`guestfish get-cachedir`" +@@ -1319,9 +1319,12 @@ which directory this is, use: + /dev/mapper/root 50G 40G 6.8G 86% / + + and look under the C column. Virt-v2v will refuse to do the +-conversion at all unless at least 1GB is available there. ++conversion at all unless at least 1GB is available there. You can ++change the directory that virt-v2v uses by setting ++C<$VIRT_V2V_TMPDIR>. + +-See also L above. ++See also L above and L ++below. + + =head2 Running virt-v2v as root or non-root + +@@ -1496,10 +1499,18 @@ conversion. + + =over 4 + ++=item C ++ + =item C + + Location of the temporary directory used for the potentially large +-temporary overlay file. If not set, F is used. ++temporary overlay file. If neither environment variable is set then ++F is used. ++ ++To reliably ensure large temporary files are cleaned up (for example ++in case virt-v2v crashes) you should create a randomly named directory ++under F, set C to point to this directory, ++then when virt-v2v exits remove the directory. + + See the L section above. + +diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml +index 5d3bece1..d78a5ce8 100644 +--- a/v2v/input_ova.ml ++++ b/v2v/input_ova.ml +@@ -132,8 +132,8 @@ class input_ova ova = object + (* The spec allows the file to be gzip-compressed, in + * which case we must uncompress it into a temporary. + *) +- let temp_dir = (open_guestfs ())#get_cachedir () in +- let new_filename = Filename.temp_file ~temp_dir "ova" ".vmdk" in ++ let new_filename = ++ Filename.temp_file ~temp_dir:Utils.large_tmpdir "ova" ".vmdk" in + unlink_on_exit new_filename; + let cmd = + sprintf "zcat %s > %s" (quote filename) (quote new_filename) in +diff --git a/v2v/input_vmx.ml b/v2v/input_vmx.ml +index f1d143e9..7a7647e5 100644 +--- a/v2v/input_vmx.ml ++++ b/v2v/input_vmx.ml +@@ -389,8 +389,7 @@ and find_nics vmx = + + class input_vmx input_password input_transport arg = + let tmpdir = +- let base_dir = (open_guestfs ())#get_cachedir () in +- let t = Mkdtemp.temp_dir ~base_dir "vmx." in ++ let t = Mkdtemp.temp_dir "vmx." in + rmdir_on_exit t; + t in + object +diff --git a/v2v/output_glance.ml b/v2v/output_glance.ml +index 0a9e9181..e8facd0a 100644 +--- a/v2v/output_glance.ml ++++ b/v2v/output_glance.ml +@@ -33,8 +33,7 @@ class output_glance () = + * to write to a temporary file. XXX + *) + let tmpdir = +- let base_dir = (open_guestfs ())#get_cachedir () in +- let t = Mkdtemp.temp_dir ~base_dir "glance." in ++ let t = Mkdtemp.temp_dir ~base_dir:large_tmpdir "glance." in + rmdir_on_exit t; + t in + object +diff --git a/v2v/output_null.ml b/v2v/output_null.ml +index 3528da50..edb749ea 100644 +--- a/v2v/output_null.ml ++++ b/v2v/output_null.ml +@@ -75,8 +75,7 @@ class output_null = + * the null-co device w/ a JSON URL. + *) + let tmpdir = +- let base_dir = (open_guestfs ())#get_cachedir () in +- let t = Mkdtemp.temp_dir ~base_dir "null." in ++ let t = Mkdtemp.temp_dir ~base_dir:large_tmpdir "null." in + rmdir_on_exit t; + t in + object +diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml +index 81896e53..913992d9 100644 +--- a/v2v/output_rhv_upload.ml ++++ b/v2v/output_rhv_upload.ml +@@ -148,25 +148,28 @@ class output_rhv_upload output_alloc output_conn + rhv_options = + (* Create a temporary directory which will be deleted on exit. *) + let tmpdir = +- let base_dir = (open_guestfs ())#get_cachedir () in +- let t = Mkdtemp.temp_dir ~base_dir "rhvupload." in ++ let t = Mkdtemp.temp_dir "rhvupload." in + rmdir_on_exit t; + t in + + let diskid_file_of_id id = tmpdir // sprintf "diskid.%d" id in + + (* Create Python scripts for precheck, vmcheck, plugin and create VM. *) +- let py_create = Python_script.create ~tmpdir in +- let precheck_script = py_create ~name:"rhv-upload-precheck.py" +- Output_rhv_upload_precheck_source.code in +- let vmcheck_script = py_create ~name:"rhv-upload-vmcheck.py" +- Output_rhv_upload_vmcheck_source.code in +- let plugin_script = py_create ~name:"rhv-upload-plugin.py" +- Output_rhv_upload_plugin_source.code in +- let createvm_script = py_create ~name:"rhv-upload-createvm.py" +- Output_rhv_upload_createvm_source.code in +- let deletedisks_script = py_create ~name:"rhv-upload-deletedisks.py" +- Output_rhv_upload_deletedisks_source.code in ++ let precheck_script = ++ Python_script.create ~name:"rhv-upload-precheck.py" ++ Output_rhv_upload_precheck_source.code in ++ let vmcheck_script = ++ Python_script.create ~name:"rhv-upload-vmcheck.py" ++ Output_rhv_upload_vmcheck_source.code in ++ let plugin_script = ++ Python_script.create ~name:"rhv-upload-plugin.py" ++ Output_rhv_upload_plugin_source.code in ++ let createvm_script = ++ Python_script.create ~name:"rhv-upload-createvm.py" ++ Output_rhv_upload_createvm_source.code in ++ let deletedisks_script = ++ Python_script.create ~name:"rhv-upload-deletedisks.py" ++ Output_rhv_upload_deletedisks_source.code in + + (* JSON parameters which are invariant between disks. *) + let json_params = [ +diff --git a/v2v/parse_ova.ml b/v2v/parse_ova.ml +index 0b939ac4..568ac5fa 100644 +--- a/v2v/parse_ova.ml ++++ b/v2v/parse_ova.ml +@@ -71,8 +71,7 @@ let rec parse_ova ova = + if is_directory ova then ova, Directory + else ( + let tmpdir = +- let base_dir = (open_guestfs ())#get_cachedir () in +- let t = Mkdtemp.temp_dir ~base_dir "ova." in ++ let t = Mkdtemp.temp_dir ~base_dir:large_tmpdir "ova." in + rmdir_on_exit t; + t in + +@@ -221,8 +220,7 @@ and uncompress_head format file = + *) + and uncompressed_type format file = + let head, headlen = uncompress_head format file in +- let tmpfile, chan = +- Filename.open_temp_file "ova.file." "" in ++ let tmpfile, chan = Filename.open_temp_file "ova.file." "" in + output chan head 0 headlen; + close_out chan; + let ret = detect_file_type tmpfile in +diff --git a/v2v/python_script.ml b/v2v/python_script.ml +index b1ea8f9d..212c8e1b 100644 +--- a/v2v/python_script.ml ++++ b/v2v/python_script.ml +@@ -31,15 +31,9 @@ type script = { + path : string; (* Path to script. *) + } + +-let create ?(name = "script.py") ?tmpdir code = +- let tmpdir = +- match tmpdir with +- | None -> +- let base_dir = (open_guestfs ())#get_cachedir () in +- let t = Mkdtemp.temp_dir ~base_dir "v2v." in +- rmdir_on_exit t; +- t +- | Some dir -> dir in ++let create ?(name = "script.py") code = ++ let tmpdir = Mkdtemp.temp_dir "v2v." in ++ rmdir_on_exit tmpdir; + let path = tmpdir // name in + with_open_out path (fun chan -> output_string chan code); + { tmpdir; path } +diff --git a/v2v/python_script.mli b/v2v/python_script.mli +index 6bf77e34..fdf73514 100644 +--- a/v2v/python_script.mli ++++ b/v2v/python_script.mli +@@ -20,14 +20,11 @@ + + type script + +-val create : ?name:string -> ?tmpdir:string -> string -> script ++val create : ?name:string -> string -> script + (** Create a Python script object. + + The optional parameter [?name] is a hint for the name of the script. + +- The optional parameter [?tmpdir] is the temporary directory to use +- (instead of creating a new one). +- + The parameter is the Python code. Usually this is + [Some_source.code] where [some_source.ml] is generated from + the Python file by [v2v/embed.sh] (see also [v2v/Makefile.am]). *) +diff --git a/v2v/utils.ml b/v2v/utils.ml +index c2940582..a6c359f0 100644 +--- a/v2v/utils.ml ++++ b/v2v/utils.ml +@@ -24,6 +24,10 @@ open Std_utils + open Tools_utils + open Common_gettext.Gettext + ++let large_tmpdir = ++ try Sys.getenv "VIRT_V2V_TMPDIR" ++ with Not_found -> (open_guestfs ())#get_cachedir () ++ + (* Is SELinux enabled and enforcing on the host? *) + let have_selinux = + 0 = Sys.command "getenforce 2>/dev/null | grep -isq Enforcing" +@@ -114,6 +118,7 @@ let qemu_img_supports_offset_and_size () = + * file that has an offset and size. + *) + let tmp = Filename.temp_file "v2vqemuimgtst" ".img" in ++ unlink_on_exit tmp; + Unix.truncate tmp 1024; + + let json = [ +@@ -133,7 +138,6 @@ let qemu_img_supports_offset_and_size () = + (if verbose () then "" else " 2>&1") in + debug "%s" cmd; + let r = 0 = Sys.command cmd in +- Unix.unlink tmp; + debug "qemu-img supports \"offset\" and \"size\" in json URLs: %b" r; + r + +diff --git a/v2v/utils.mli b/v2v/utils.mli +index 937e2b9b..d86ca507 100644 +--- a/v2v/utils.mli ++++ b/v2v/utils.mli +@@ -18,6 +18,11 @@ + + (** Utilities used in virt-v2v only. *) + ++val large_tmpdir : string ++(** [VIRT_V2V_TMPDIR] or [/var/tmp]. Create all large temporary files ++ such as overlays in this directory. Small temporary files can ++ use the default behaviour eg. of {!Filename.temp_file} *) ++ + val have_selinux : bool + (** True if SELinux is enabled and enforcing on the host. *) + +diff --git a/v2v/v2v.ml b/v2v/v2v.ml +index 73edff2c..a58ff433 100644 +--- a/v2v/v2v.ml ++++ b/v2v/v2v.ml +@@ -264,8 +264,6 @@ and set_source_networks_and_bridges cmdline source = + let nics = List.map (Networks.map cmdline.network_map) source.s_nics in + { source with s_nics = nics } + +-and overlay_dir = (open_guestfs ())#get_cachedir () +- + (* Conversion can fail or hang if there is insufficient free space in + * the temporary directory used to store overlays on the host + * (RHBZ#1316479). Although only a few hundred MB is actually +@@ -273,12 +271,12 @@ and overlay_dir = (open_guestfs ())#get_cachedir () + * guestfs appliance which is also stored here. + *) + and check_host_free_space () = +- let free_space = StatVFS.free_space (StatVFS.statvfs overlay_dir) in +- debug "check_host_free_space: overlay_dir=%s free_space=%Ld" +- overlay_dir free_space; ++ let free_space = StatVFS.free_space (StatVFS.statvfs large_tmpdir) in ++ debug "check_host_free_space: large_tmpdir=%s free_space=%Ld" ++ large_tmpdir free_space; + if free_space < 1_073_741_824L then + error (f_"insufficient free space in the conversion server temporary directory %s (%s).\n\nEither free up space in that directory, or set the LIBGUESTFS_CACHEDIR environment variable to point to another directory with more than 1GB of free space.\n\nSee also the virt-v2v(1) manual, section \"Minimum free space check in the host\".") +- overlay_dir (human_size free_space) ++ large_tmpdir (human_size free_space) + + (* Create a qcow2 v3 overlay to protect the source image(s). *) + and create_overlays source_disks = +@@ -286,7 +284,7 @@ and create_overlays source_disks = + List.mapi ( + fun i ({ s_qemu_uri = qemu_uri; s_format = format } as source) -> + let overlay_file = +- Filename.temp_file ~temp_dir:overlay_dir "v2vovl" ".qcow2" in ++ Filename.temp_file ~temp_dir:large_tmpdir "v2vovl" ".qcow2" in + unlink_on_exit overlay_file; + + (* There is a specific reason to use the newer qcow2 variant: +@@ -823,7 +821,7 @@ and preserve_overlays overlays src_name = + List.iter ( + fun ov -> + let saved_filename = +- sprintf "%s/%s-%s.qcow2" overlay_dir src_name ov.ov_sd in ++ sprintf "%s/%s-%s.qcow2" large_tmpdir src_name ov.ov_sd in + rename ov.ov_overlay_file saved_filename; + info (f_"Overlay saved as %s [--debug-overlays]") saved_filename + ) overlays +-- +2.18.4 + diff --git a/SOURCES/0025-v2v-o-openstack-Allow-guests-to-be-converted-to-UEFI.patch b/SOURCES/0025-v2v-o-openstack-Allow-guests-to-be-converted-to-UEFI.patch new file mode 100644 index 0000000..1813ef9 --- /dev/null +++ b/SOURCES/0025-v2v-o-openstack-Allow-guests-to-be-converted-to-UEFI.patch @@ -0,0 +1,34 @@ +From 82d56820db4f05711b125daf46a4777e99dbdf87 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 25 Aug 2020 08:23:52 +0100 +Subject: [PATCH] v2v: -o openstack: Allow guests to be converted to UEFI + (RHBZ#1872094). + +Since this output method was written the code has always been capable +of adding the hw_firmware_type = uefi image property, and this +property has been supported since at least OpenStack 12 which is years +old. + +Interestingly now all of the output modes support both BIOS and UEFI. + +(cherry picked from commit 5fa65a13fbbaab03cb558d0c776c17227433f1b3) +--- + v2v/output_openstack.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/output_openstack.ml b/v2v/output_openstack.ml +index 179b0edf..fdc04b02 100644 +--- a/v2v/output_openstack.ml ++++ b/v2v/output_openstack.ml +@@ -390,7 +390,7 @@ object + | None -> "" + | Some op -> " -op " ^ op) + +- method supported_firmware = [ TargetBIOS ] ++ method supported_firmware = [ TargetBIOS; TargetUEFI ] + + (* List of Cinder volume IDs. *) + val mutable volume_ids = [] +-- +2.18.4 + diff --git a/SOURCES/0026-v2v-Fix-spelling-mistake-in-uninstall-function-name.patch b/SOURCES/0026-v2v-Fix-spelling-mistake-in-uninstall-function-name.patch new file mode 100644 index 0000000..2a709e9 --- /dev/null +++ b/SOURCES/0026-v2v-Fix-spelling-mistake-in-uninstall-function-name.patch @@ -0,0 +1,44 @@ +From 358122c089d1e4df014a6821365341d3220ab6e6 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 19 Jan 2021 11:26:23 +0000 +Subject: [PATCH] v2v: Fix spelling mistake in uninstall function name. + +Fixes: commit 53847717fa1d0ffc2a174275badf486eb1ed6fae +(cherry picked from commit 3515c9f617271bec89962ba8a2b8c690e6df4c99) +--- + v2v/convert_windows.ml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml +index ba26949f..f2f7b95c 100644 +--- a/v2v/convert_windows.ml ++++ b/v2v/convert_windows.ml +@@ -135,7 +135,7 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips = + (* Locate and retrieve all the uninstallation commands for installed + * applications. + *) +- let unistallation_commands pretty_name matchfn extra_uninstall_string = ++ let uninstallation_commands pretty_name matchfn extra_uninstall_string = + let uninsts = ref [] in + + Registry.with_hive_readonly g inspect.i_windows_software_hive +@@ -198,14 +198,14 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips = + *) + let extra_uninstall_string = + Some "PREVENT_REBOOT=Yes LAUNCHED_BY_SETUP_EXE=Yes" in +- unistallation_commands "Parallels Tools" matchfn extra_uninstall_string in ++ uninstallation_commands "Parallels Tools" matchfn extra_uninstall_string in + + (* Locate and retrieve all uninstallation commands for VMware Tools. *) + let vmwaretools_uninst = + let matchfn s = + String.find s "VMware Tools" != -1 + in +- unistallation_commands "VMware Tools" matchfn None in ++ uninstallation_commands "VMware Tools" matchfn None in + + (*----------------------------------------------------------------------*) + (* Perform the conversion of the Windows guest. *) +-- +2.18.4 + diff --git a/SOURCES/0027-v2v-windows-Refactor-uninstallation_commands-functio.patch b/SOURCES/0027-v2v-windows-Refactor-uninstallation_commands-functio.patch new file mode 100644 index 0000000..fee1023 --- /dev/null +++ b/SOURCES/0027-v2v-windows-Refactor-uninstallation_commands-functio.patch @@ -0,0 +1,137 @@ +From 9c81b523857e057b8361cbbcc4647ed02b572ca0 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 19 Jan 2021 11:38:46 +0000 +Subject: [PATCH] v2v: windows: Refactor uninstallation_commands function. + +Simplify and shorten this function: + + - Remove unnecessary use of Not_found exception and generally + simplify flow control. + + - Use sprintf. + +This shouldn't change what the function does. + +(cherry picked from commit d48530209a79725f26d6e25101bed6f228f45e8d) +--- + v2v/convert_windows.ml | 89 ++++++++++++++++++------------------------ + 1 file changed, 37 insertions(+), 52 deletions(-) + +diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml +index f2f7b95c..84db742f 100644 +--- a/v2v/convert_windows.ml ++++ b/v2v/convert_windows.ml +@@ -135,56 +135,41 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips = + (* Locate and retrieve all the uninstallation commands for installed + * applications. + *) +- let uninstallation_commands pretty_name matchfn extra_uninstall_string = +- let uninsts = ref [] in ++ let uninstallation_commands pretty_name matchfn extra_uninstall_params = ++ let path = ["Microsoft"; "Windows"; "CurrentVersion"; "Uninstall"] in ++ let uninstval = "UninstallString" in ++ let ret = ref [] in + +- Registry.with_hive_readonly g inspect.i_windows_software_hive +- (fun reg -> +- try +- let path = ["Microsoft"; "Windows"; "CurrentVersion"; "Uninstall"] in +- let node = +- match Registry.get_node reg path with +- | None -> raise Not_found +- | Some node -> node in +- let uninstnodes = g#hivex_node_children node in +- +- Array.iter ( +- fun { G.hivex_node_h = uninstnode } -> +- try ++ Registry.with_hive_readonly g inspect.i_windows_software_hive ( ++ fun reg -> ++ match Registry.get_node reg path with ++ | None -> () ++ | Some node -> ++ let uninstnodes = g#hivex_node_children node in ++ Array.iter ( ++ fun { G.hivex_node_h = uninstnode } -> + let valueh = g#hivex_node_get_value uninstnode "DisplayName" in +- if valueh = 0L then +- raise Not_found; +- +- let dispname = g#hivex_value_string valueh in +- if not (matchfn dispname) then +- raise Not_found; +- +- let uninstval = "UninstallString" in +- let valueh = g#hivex_node_get_value uninstnode uninstval in +- if valueh = 0L then ( +- let name = g#hivex_node_name uninstnode in +- warning (f_"cannot uninstall %s: registry key ‘HKLM\\SOFTWARE\\%s\\%s’ with DisplayName ‘%s’ doesn't contain value ‘%s’") +- pretty_name (String.concat "\\" path) name dispname uninstval; +- raise Not_found +- ); +- +- let uninst = (g#hivex_value_string valueh) ^ +- " /quiet /norestart /l*v+ \"%~dpn0.log\"" ^ +- " REBOOT=ReallySuppress REMOVE=ALL" in +- let uninst = +- match extra_uninstall_string with +- | None -> uninst +- | Some s -> uninst ^ " " ^ s in +- +- List.push_front uninst uninsts +- with +- Not_found -> () +- ) uninstnodes +- with +- Not_found -> () +- ); +- +- !uninsts ++ if valueh <> 0L then ( ++ let dispname = g#hivex_value_string valueh in ++ if matchfn dispname then ( ++ let valueh = g#hivex_node_get_value uninstnode uninstval in ++ if valueh <> 0L then ( ++ let reg_cmd = g#hivex_value_string valueh in ++ let cmd = ++ sprintf "%s /quiet /norestart /l*v+ \"%%~dpn0.log\" REBOOT=ReallySuppress REMOVE=ALL %s" ++ reg_cmd extra_uninstall_params in ++ List.push_front cmd ret ++ ) ++ else ++ let name = g#hivex_node_name uninstnode in ++ warning (f_"cannot uninstall %s: registry key ‘HKLM\\SOFTWARE\\%s\\%s’ with DisplayName ‘%s’ doesn't contain value ‘%s’") ++ pretty_name (String.concat "\\" path) name ++ dispname uninstval ++ ) ++ ) ++ ) uninstnodes ++ ) (* with_hive_readonly *); ++ !ret + in + + (* Locate and retrieve all uninstallation commands for Parallels Tools. *) +@@ -196,16 +181,16 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips = + (* Without these custom Parallels-specific MSI properties the + * uninstaller still shows a no-way-out reboot dialog. + *) +- let extra_uninstall_string = +- Some "PREVENT_REBOOT=Yes LAUNCHED_BY_SETUP_EXE=Yes" in +- uninstallation_commands "Parallels Tools" matchfn extra_uninstall_string in ++ let extra_uninstall_params = ++ "PREVENT_REBOOT=Yes LAUNCHED_BY_SETUP_EXE=Yes" in ++ uninstallation_commands "Parallels Tools" matchfn extra_uninstall_params in + + (* Locate and retrieve all uninstallation commands for VMware Tools. *) + let vmwaretools_uninst = + let matchfn s = + String.find s "VMware Tools" != -1 + in +- uninstallation_commands "VMware Tools" matchfn None in ++ uninstallation_commands "VMware Tools" matchfn "" in + + (*----------------------------------------------------------------------*) + (* Perform the conversion of the Windows guest. *) +-- +2.18.4 + diff --git a/SOURCES/0028-v2v-Replace-broken-VMware-Tools-uninstall-command-ms.patch b/SOURCES/0028-v2v-Replace-broken-VMware-Tools-uninstall-command-ms.patch new file mode 100644 index 0000000..216584d --- /dev/null +++ b/SOURCES/0028-v2v-Replace-broken-VMware-Tools-uninstall-command-ms.patch @@ -0,0 +1,62 @@ +From 2bf5fc815d53e581398e787ae96444c438945ab3 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 19 Jan 2021 12:17:49 +0000 +Subject: [PATCH] v2v: Replace broken VMware Tools uninstall command msiexec /i + with /x. + +Fixes: https://bugzilla.redhat.com/1917760 +Thanks: Chetan Nagarkar +(cherry picked from commit f7496b0a7e76a06bda8d7ec1aba36741f8cb295c) +--- + v2v/convert_windows.ml | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml +index 84db742f..44cef5ed 100644 +--- a/v2v/convert_windows.ml ++++ b/v2v/convert_windows.ml +@@ -135,7 +135,7 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips = + (* Locate and retrieve all the uninstallation commands for installed + * applications. + *) +- let uninstallation_commands pretty_name matchfn extra_uninstall_params = ++ let uninstallation_commands pretty_name matchfn modfn extra_uninstall_params = + let path = ["Microsoft"; "Windows"; "CurrentVersion"; "Uninstall"] in + let uninstval = "UninstallString" in + let ret = ref [] in +@@ -155,6 +155,7 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips = + let valueh = g#hivex_node_get_value uninstnode uninstval in + if valueh <> 0L then ( + let reg_cmd = g#hivex_value_string valueh in ++ let reg_cmd = modfn reg_cmd in + let cmd = + sprintf "%s /quiet /norestart /l*v+ \"%%~dpn0.log\" REBOOT=ReallySuppress REMOVE=ALL %s" + reg_cmd extra_uninstall_params in +@@ -183,14 +184,22 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips = + *) + let extra_uninstall_params = + "PREVENT_REBOOT=Yes LAUNCHED_BY_SETUP_EXE=Yes" in +- uninstallation_commands "Parallels Tools" matchfn extra_uninstall_params in ++ uninstallation_commands "Parallels Tools" matchfn identity ++ extra_uninstall_params in + + (* Locate and retrieve all uninstallation commands for VMware Tools. *) + let vmwaretools_uninst = + let matchfn s = + String.find s "VMware Tools" != -1 + in +- uninstallation_commands "VMware Tools" matchfn "" in ++ (* VMware Tools writes the install command (MsiExec /I) into the ++ * UninstallString key in the registry, rather than the uninstall ++ * command. Try to spot this and rewrite. (RHBZ#1917760). ++ *) ++ let re1 = PCRE.compile ~caseless:true "msiexec" in ++ let re2 = PCRE.compile ~caseless:true "/i" in ++ let msifn s = if PCRE.matches re1 s then PCRE.replace re2 "/x" s else s in ++ uninstallation_commands "VMware Tools" matchfn msifn "" in + + (*----------------------------------------------------------------------*) + (* Perform the conversion of the Windows guest. *) +-- +2.18.4 + diff --git a/SOURCES/0030-v2v-rhv-upload-plugin-Defer-imageio-connection.patch b/SOURCES/0030-v2v-rhv-upload-plugin-Defer-imageio-connection.patch new file mode 100644 index 0000000..73d3d48 --- /dev/null +++ b/SOURCES/0030-v2v-rhv-upload-plugin-Defer-imageio-connection.patch @@ -0,0 +1,83 @@ +From 987ddcd2ad7546212d3afed52b56f27a664624d6 Mon Sep 17 00:00:00 2001 +From: Nir Soffer +Date: Thu, 21 Jan 2021 03:40:00 +0200 +Subject: [PATCH] v2v: rhv-upload-plugin: Defer imageio connection + +When using vddk input with certain vmware version, qemu-img may spend +lot of time getting source image extents. If getting image extents takes +more than 60 seconds, imageio server closes the idle connection, and the +transfer will fail on the first write with: + +nbdkit: python[1]: error: /var/tmp/rhvupload.0OKqWA/rhv-upload-plugin.py: pwrite: error: +Traceback (most recent call last): + File "/var/tmp/rhvupload.0OKqWA/rhv-upload-plugin.py", line 94, in wrapper + return func(h, *args) + File "/var/tmp/rhvupload.0OKqWA/rhv-upload-plugin.py", line 230, in pwrite + r = http.getresponse() + File "/usr/lib64/python3.6/http/client.py", line 1361, in getresponse + response.begin() + File "/usr/lib64/python3.6/http/client.py", line 311, in begin + version, status, reason = self._read_status() + File "/usr/lib64/python3.6/http/client.py", line 280, in _read_status + raise RemoteDisconnected("Remote end closed connection without" + http.client.RemoteDisconnected: Remote end closed connection without response + +This happens only when not using unix socket, for example when running +on non-ovirt host, or ovirt host from another data center, or when using +-oo rhv_direct=false + +When using unix socket, we close the initial HTTPSConnection, and +created a new UnixHTTPConnection. This connection is not connected to +the server yet. When qemu-img tries to access the server, the connection +is connected automatically. + +Fix the issue by closing the initial connection used to get server +options and initialize the handle, and storing a closed connection in +the handle. + +Here is the flow with this change: + +1. Create HTTPSConnection for getting server options +2. Close the connection[1] +3. If using unix socket, create UnixHTTPConnection. +4. Store the connection in the handle. +5. When qemu-img try to write/zero, the connection is reconnects + automatically to imageio server[2] + +Tested by adding a 300 milliseconds delay in nbdkit file plugin. Due to +the way qemu-img works, this cause more than 2 minutes delay after +open() but before the first pwrite(). Without this change, the import +fails consistently when using rhv_direct=false. + +[1] https://github.com/python/cpython/blob/34df10a9a16b38d54421eeeaf73ec89828563be7/Lib/http/client.py#L958 +[2] https://github.com/python/cpython/blob/34df10a9a16b38d54421eeeaf73ec89828563be7/Lib/http/client.py#L972 + +Signed-off-by: Nir Soffer +(cherry picked from commit 1d5fc257765c444644e5bfc6525e86ff201755f0) +--- + v2v/rhv-upload-plugin.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 471102da..7cd6dea6 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -117,6 +117,15 @@ def open(readonly): + destination_url = parse_transfer_url(transfer) + http = create_http(destination_url) + options = get_options(http, destination_url) ++ ++ # Close the initial connection to imageio server. When qemu-img will ++ # try to access the server, HTTPConnection will reconnect ++ # automatically. If we keep this connection idle and qemu-img is too ++ # slow getting image extents, imageio server may close the connection, ++ # and the import will fail on the first write. ++ # See https://bugzilla.redhat.com/1916176. ++ http.close() ++ + http = optimize_http(http, host, options) + except: + cancel_transfer(connection, transfer) +-- +2.18.4 + diff --git a/SOURCES/0031-v2v-windows-Fix-schtasks-SD-parameter.patch b/SOURCES/0031-v2v-windows-Fix-schtasks-SD-parameter.patch new file mode 100644 index 0000000..2f7b54e --- /dev/null +++ b/SOURCES/0031-v2v-windows-Fix-schtasks-SD-parameter.patch @@ -0,0 +1,37 @@ +From 88429f56491ed0e5b3f5f91e6e352fa1251484bc Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 30 Nov 2020 08:55:34 +0000 +Subject: [PATCH] v2v: windows: Fix schtasks /SD parameter. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Thanks: Dinesh Herath, Tomáš Golembiovský, Bryan Kinney, Mark Zealey + +Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1895323 +(cherry picked from commit b65711c9293415f671d35d0e2f9b55a74343da45) +--- + v2v/convert_windows.ml | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml +index 44cef5ed..4d844e2d 100644 +--- a/v2v/convert_windows.ml ++++ b/v2v/convert_windows.ml +@@ -422,11 +422,12 @@ popd + and configure_qemu_ga files = + List.iter ( + fun msi_path -> ++ (* Windows is a trashfire. https://stackoverflow.com/a/18730884 *) + let fb_script = sprintf "\ + echo Removing any previously scheduled qemu-ga installation + schtasks.exe /Delete /TN Firstboot-qemu-ga /F + echo Scheduling delayed installation of qemu-ga from %s +-powershell.exe -command \"$d = (get-date).AddSeconds(120); schtasks.exe /Create /SC ONCE /ST $d.ToString('HH:mm') /SD $d.ToString('MM/dd/yyyy') /RU SYSTEM /TN Firstboot-qemu-ga /TR \\\"C:\\%s /forcerestart /qn /l+*vx C:\\%s.log\\\"\" ++powershell.exe -command \"$d = (get-date).AddSeconds(120); $FormatHack = ($([System.Globalization.DateTimeFormatInfo]::CurrentInfo.ShortDatePattern) -replace 'M+/', 'MM/') -replace 'd+/', 'dd/'; schtasks.exe /Create /SC ONCE /ST $d.ToString('HH:mm') /SD $d.ToString($FormatHack) /RU SYSTEM /TN Firstboot-qemu-ga /TR \\\"C:\\%s /forcerestart /qn /l+*vx C:\\%s.log\\\"\" + " + msi_path msi_path msi_path in + Firstboot.add_firstboot_script g inspect.i_root +-- +2.18.4 + diff --git a/SOURCES/0032-v2v-Turn-pnp_wait.exe-warning-into-a-debug-message.patch b/SOURCES/0032-v2v-Turn-pnp_wait.exe-warning-into-a-debug-message.patch new file mode 100644 index 0000000..cb0a252 --- /dev/null +++ b/SOURCES/0032-v2v-Turn-pnp_wait.exe-warning-into-a-debug-message.patch @@ -0,0 +1,32 @@ +From b04361528b04dc39368c1d90760e50fad63baa9f Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 3 Dec 2020 10:14:08 +0000 +Subject: [PATCH] v2v: Turn pnp_wait.exe warning into a debug message. + +We've used virt-v2v for years in RHEL without pnp_wait and it's never +been an issue. We don't need a warning here. + +Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1903960 +(cherry picked from commit 834bea6931b49dc4b14ebe04fd0e0884290bfb78) +--- + v2v/convert_windows.ml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml +index 4d844e2d..33fbd410 100644 +--- a/v2v/convert_windows.ml ++++ b/v2v/convert_windows.ml +@@ -267,8 +267,8 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips = + if Sys.file_exists tool_path then + configure_wait_pnp tool_path + else +- warning (f_"%s is missing. Firstboot scripts may conflict with PnP.") +- tool_path; ++ debug (f_"%s is missing. Firstboot scripts may conflict with PnP.") ++ tool_path; + + (* Install RHEV-APT only if appropriate for the output hypervisor. *) + if output#install_rhev_apt then ( +-- +2.18.4 + diff --git a/SOURCES/0033-docs-UEFI-guest-conversion-to-o-openstack-is-support.patch b/SOURCES/0033-docs-UEFI-guest-conversion-to-o-openstack-is-support.patch new file mode 100644 index 0000000..bb5a192 --- /dev/null +++ b/SOURCES/0033-docs-UEFI-guest-conversion-to-o-openstack-is-support.patch @@ -0,0 +1,27 @@ +From 6fb69c6239902cd4462b6c28bc82118cbf9643f2 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 25 Aug 2020 08:27:42 +0100 +Subject: [PATCH] docs: UEFI guest conversion to -o openstack is supported + (RHBZ#1872100). + +(cherry picked from commit db4e673df51d1235a040dc4a4782268743523e5a) +--- + docs/virt-v2v-support.pod | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/docs/virt-v2v-support.pod b/docs/virt-v2v-support.pod +index a5150907..1ffc0f9d 100644 +--- a/docs/virt-v2v-support.pod ++++ b/docs/virt-v2v-support.pod +@@ -38,7 +38,7 @@ hypervisor, else you will have to adjust paths in the metadata. + + =item UEFI on OpenStack + +-Not supported. ++Supported since virt-v2v E 1.43.2. + + =item UEFI on oVirt or RHV + +-- +2.18.4 + diff --git a/SOURCES/0034-docs-o-openstack-Clarify-name-of-file-containing-Ope.patch b/SOURCES/0034-docs-o-openstack-Clarify-name-of-file-containing-Ope.patch new file mode 100644 index 0000000..d5499d6 --- /dev/null +++ b/SOURCES/0034-docs-o-openstack-Clarify-name-of-file-containing-Ope.patch @@ -0,0 +1,47 @@ +From 8a57af71779e274d31fe7f87a75bc937a59575db Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 27 Apr 2021 16:12:12 +0100 +Subject: [PATCH] docs: -o openstack: Clarify name of file containing OpenStack + auth + +In particular, don't use "stackrc" since you will likely be connecting +to the undercloud. + +Thanks: Ming Xie +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1871754 +(cherry picked from commit 61b4b5cc2f64e7a642ea03681f36829dbe665825) +--- + docs/virt-v2v-output-openstack.pod | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/docs/virt-v2v-output-openstack.pod b/docs/virt-v2v-output-openstack.pod +index 78623d97..f5a3abad 100644 +--- a/docs/virt-v2v-output-openstack.pod ++++ b/docs/virt-v2v-output-openstack.pod +@@ -89,8 +89,8 @@ endpoints. You will need to either set up your C<$OS_*> environment + variables or use output options on the virt-v2v command line to + authenticate with OpenStack. + +-Normally there is a file called something like C, +-C etc which you can simply C to set everything up. ++Normally there is a file called C or C ++which you can simply C to set everything up. + + For example: + +@@ -179,8 +179,10 @@ To output to OpenStack Glance, use the I<-o glance> option. + + This runs the L CLI program which must be installed on the + virt-v2v conversion host. For authentication to work, you will need +-to set C environment variables. In most cases you can do this +-by sourcing a file called something like F. ++to set C environment variables. ++ ++Normally there is a file called C or C ++which you can simply C to set everything up. + + Virt-v2v adds metadata for the guest to Glance, describing such things + as the guest operating system and what drivers it requires. The +-- +2.18.4 + diff --git a/SOURCES/0035-v2v-Allow-output-to-block-devices-RHBZ-1868690.patch b/SOURCES/0035-v2v-Allow-output-to-block-devices-RHBZ-1868690.patch new file mode 100644 index 0000000..8ea622a --- /dev/null +++ b/SOURCES/0035-v2v-Allow-output-to-block-devices-RHBZ-1868690.patch @@ -0,0 +1,152 @@ +From 704e86cb3bd4ddc3b7c207967f0413b4637be1f3 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 1 Sep 2020 14:44:17 +0100 +Subject: [PATCH] v2v: Allow output to block devices (RHBZ#1868690). + +We previously implicitly supported writing to block devices instead of +local files, but there were several problems: + +* Block devices could be deleted, especially if virt-v2v failed during + a conversion. + +* Block devices could be overwritten by a file with the same name, + although I believe this is just an observed consequence of the + previous point, or at least I was not able to reproduce this until + virt-v2v failed for another reason and then I noticed that because + the block device was deleted, the next run overwrote it with a file. + +* It was not documented anywhere how to do it. + +This commit makes the small code change needed to allow virt-v2v to +write to a block device, only for existing outputs which write to +local files (ie. using TargetFile). Also it avoids deleting block +devices accidentally on failure. + +Note this commit intentionally does not prevent you from writing qcow2 +to a block device. RHV uses this so it is a thing that people do. + +(cherry picked from commit 9a5974fa3bc038e5e5dbb9605a6db77d06e7bf77) +--- + docs/virt-v2v.pod | 33 ++++++++++++++++++++++++++++++ + v2v/v2v.ml | 51 ++++++++++++++++++++++++++++------------------- + 2 files changed, 63 insertions(+), 21 deletions(-) + +diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod +index af69d633..50b0bc8e 100644 +--- a/docs/virt-v2v.pod ++++ b/docs/virt-v2v.pod +@@ -1378,8 +1378,41 @@ require either a special user and/or for you to source a script that + sets authentication environment variables. Consult the Glance + documentation. + ++=item Writing to block devices ++ ++This normally requires root. See the next section. ++ + =back + ++=head2 Writing to block devices ++ ++Some output modes write to local files. In general these modes also ++let you write to block devices, but before you run virt-v2v you may ++have to arrange for symbolic links to the desired block devices in the ++output directory. ++ ++For example if using I<-o local -os /dir> then virt-v2v would normally ++create files called: ++ ++ /dir/name-sda # first disk ++ /dir/name-sdb # second disk ++ ... ++ /dir/name.xml # metadata ++ ++If you wish the disks to be written to block devices then you would ++need to create F-sda> (etc) as symlinks to the block ++devices: ++ ++ # lvcreate -L 10G -n VolumeForDiskA VG ++ # lvcreate -L 6G -n VolumeForDiskB VG ++ # ln -sf /dev/VG/VolumeForDiskA /dir/name-sda ++ # ln -sf /dev/VG/VolumeForDiskB /dir/name-sdb ++ ++Note that you must precreate the correct number of block devices of ++the correct size. Typically I<-of raw> has to be used too, but other ++formats such as qcow2 can be useful occasionally so virt-v2v does not ++force you to use raw on block devices. ++ + =head2 Minimal XML for -i libvirtxml option + + When using the I<-i libvirtxml> option, you have to supply some +diff --git a/v2v/v2v.ml b/v2v/v2v.ml +index a58ff433..1f8d0138 100644 +--- a/v2v/v2v.ml ++++ b/v2v/v2v.ml +@@ -681,7 +681,10 @@ and copy_targets cmdline targets input output = + fun t -> + match t.target_file with + | TargetURI _ -> () +- | TargetFile s -> try unlink s with _ -> () ++ | TargetFile filename -> ++ if not (is_block_device filename) then ( ++ try unlink filename with _ -> () ++ ) + ) targets + ) + ); +@@ -711,27 +714,33 @@ and copy_targets cmdline targets input output = + + (match t.target_file with + | TargetFile filename -> +- (* It turns out that libguestfs's disk creation code is +- * considerably more flexible and easier to use than +- * qemu-img, so create the disk explicitly using libguestfs +- * then pass the 'qemu-img convert -n' option so qemu reuses +- * the disk. +- * +- * Also we allow the output mode to actually create the disk +- * image. This lets the output mode set ownership and +- * permissions correctly if required. ++ (* As a special case, allow output to a block device or ++ * symlink to a block device. In this case we don't ++ * create/overwrite the block device. (RHBZ#1868690). + *) +- (* What output preallocation mode should we use? *) +- let preallocation = +- match t.target_format, cmdline.output_alloc with +- | ("raw"|"qcow2"), Sparse -> Some "sparse" +- | ("raw"|"qcow2"), Preallocated -> Some "full" +- | _ -> None (* ignore -oa flag for other formats *) in +- let compat = +- match t.target_format with "qcow2" -> Some "1.1" | _ -> None in +- output#disk_create filename t.target_format +- t.target_overlay.ov_virtual_size +- ?preallocation ?compat ++ if not (is_block_device filename) then ( ++ (* It turns out that libguestfs's disk creation code is ++ * considerably more flexible and easier to use than ++ * qemu-img, so create the disk explicitly using libguestfs ++ * then pass the 'qemu-img convert -n' option so qemu reuses ++ * the disk. ++ * ++ * Also we allow the output mode to actually create the disk ++ * image. This lets the output mode set ownership and ++ * permissions correctly if required. ++ *) ++ (* What output preallocation mode should we use? *) ++ let preallocation = ++ match t.target_format, cmdline.output_alloc with ++ | ("raw"|"qcow2"), Sparse -> Some "sparse" ++ | ("raw"|"qcow2"), Preallocated -> Some "full" ++ | _ -> None (* ignore -oa flag for other formats *) in ++ let compat = ++ match t.target_format with "qcow2" -> Some "1.1" | _ -> None in ++ output#disk_create filename t.target_format ++ t.target_overlay.ov_virtual_size ++ ?preallocation ?compat ++ ) + + | TargetURI _ -> + (* XXX For the moment we assume that qemu URI outputs +-- +2.18.4 + diff --git a/SOURCES/0036-v2v-Disable-readahead-for-VMware-curl-sources-too-RH.patch b/SOURCES/0036-v2v-Disable-readahead-for-VMware-curl-sources-too-RH.patch new file mode 100644 index 0000000..9639da0 --- /dev/null +++ b/SOURCES/0036-v2v-Disable-readahead-for-VMware-curl-sources-too-RH.patch @@ -0,0 +1,42 @@ +From e12604349587b67b3b4c3d0b7b1779999460a93d Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 19 Jun 2020 13:43:47 +0100 +Subject: [PATCH] v2v: Disable readahead for VMware curl sources too + (RHBZ#1848862). + +This appears to be the cause of timeouts during the conversion step +where VMware VCenter server's Tomcat HTTPS server stops responding to +requests (or rather, responds only with 503 errors). The server later +recovers and in fact because of the retry filter the conversion +usually succeeds, but I found that we can avoid the problem by +disabling readahead. + +(cherry picked from commit 9f4940068022d4e7abdfea6617b73a2b206f19aa) +--- + v2v/nbdkit_sources.ml | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/v2v/nbdkit_sources.ml b/v2v/nbdkit_sources.ml +index f5e91911..7c177e35 100644 +--- a/v2v/nbdkit_sources.ml ++++ b/v2v/nbdkit_sources.ml +@@ -99,12 +99,12 @@ let common_create ?bandwidth ?extra_debug ?extra_env password + + (* Adding the readahead filter is always a win for our access + * patterns. If it doesn't exist don't worry. However it +- * breaks VMware servers (RHBZ#1832805). ++ * breaks VMware servers (RHBZ#1832805, RHBZ#1848862). + *) + let cmd = +- if plugin_name <> "vddk" then +- Nbdkit.add_filter_if_available cmd "readahead" +- else cmd in ++ match plugin_name with ++ | "vddk" | "curl" -> cmd ++ | _ -> Nbdkit.add_filter_if_available cmd "readahead" in + + (* Caching extents speeds up qemu-img, especially its consecutive + * block_status requests with req_one=1. +-- +2.18.4 + diff --git a/SOURCES/0037-docs-Document-how-to-remove-Out-of-HTTP-sessions-lim.patch b/SOURCES/0037-docs-Document-how-to-remove-Out-of-HTTP-sessions-lim.patch new file mode 100644 index 0000000..d63a420 --- /dev/null +++ b/SOURCES/0037-docs-Document-how-to-remove-Out-of-HTTP-sessions-lim.patch @@ -0,0 +1,37 @@ +From c0c4fa145da8a1d7b423c6f54bdf94d270c633de Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 3 Dec 2020 10:06:29 +0000 +Subject: [PATCH] docs: Document how to remove "Out of HTTP sessions" limit. + +Thanks: Tamir +(cherry picked from commit 00649e98be43b4b05a28c5c8c858a54ec4fe3e7a) +--- + docs/virt-v2v-input-vmware.pod | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/docs/virt-v2v-input-vmware.pod b/docs/virt-v2v-input-vmware.pod +index e4df920e..ae8964dd 100644 +--- a/docs/virt-v2v-input-vmware.pod ++++ b/docs/virt-v2v-input-vmware.pod +@@ -579,6 +579,18 @@ a stable IP address. After that log in to the vCenter server’s admin + console at C. Under the C tab, select + C and then reboot it. + ++=head2 vCenter: "Out of HTTP sessions: Limited to ..." ++ ++VMware vCenter appears to limit HTTP sessions and in some ++circumstances virt-v2v may exceed this number. You can adjust or ++remove the limit by editing F on the vCenter ++server. Increase the CmaxSessionCountE> field, or set it to ++C<0> which makes it unlimited: ++ ++ ++ 0 ++ ++ + =head1 SEE ALSO + + L. +-- +2.18.4 + diff --git a/SOURCES/0038-v2v-Increase-required-free-space-in-Windows-to-100-M.patch b/SOURCES/0038-v2v-Increase-required-free-space-in-Windows-to-100-M.patch new file mode 100644 index 0000000..530b9f7 --- /dev/null +++ b/SOURCES/0038-v2v-Increase-required-free-space-in-Windows-to-100-M.patch @@ -0,0 +1,131 @@ +From 90e0e0cfe7d90bb9b8cc4a8eb9225266b1622453 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 15 Apr 2021 16:52:36 +0100 +Subject: [PATCH] v2v: Increase required free space in Windows to 100 MB + +With an increasing number of drivers being installed in Windows the +existing limit (20 MB) was far too low. In fact we found that a guest +with 63 MB of free space would sometimes run out of space. + +This commit increases the required space to 100 MB for Windows. + +There are also a couple of smaller fixes: + + - We now properly distinguish between / as a Linux boot drive, + and Windows. + + - The error message has been improved to display MBs instead of bytes. + +Reported-by: Ming Xie +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1949147 +(cherry picked from commit dfcf60c916a986a352938b432231a36558a3bc05) +--- + docs/virt-v2v.pod | 8 +++++++- + v2v/v2v.ml | 46 +++++++++++++++++++++++++--------------------- + 2 files changed, 32 insertions(+), 22 deletions(-) + +diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod +index 50b0bc8e..4016c724 100644 +--- a/docs/virt-v2v.pod ++++ b/docs/virt-v2v.pod +@@ -1288,7 +1288,7 @@ to perform the conversion. Currently it checks: + + =over 4 + +-=item Linux root filesystem or Windows C drive ++=item Linux root filesystem + + Minimum free space: 20 MB + +@@ -1299,6 +1299,12 @@ Minimum free space: 50 MB + This is because we need to build a new initramfs for some Enterprise + Linux conversions. + ++=item Windows C drive ++ ++Minimum free space: 100 MB ++ ++We may have to copy in many virtio drivers and guest agents. ++ + =item Any other mountable filesystem + + Minimum free space: 10 MB +diff --git a/v2v/v2v.ml b/v2v/v2v.ml +index 1f8d0138..bde51885 100644 +--- a/v2v/v2v.ml ++++ b/v2v/v2v.ml +@@ -108,7 +108,7 @@ let rec main () = + let inspect = Inspect_source.inspect_source cmdline.root_choice g in + + let mpstats = get_mpstats g in +- check_guest_free_space mpstats; ++ check_guest_free_space inspect mpstats; + + (* Estimate space required on target for each disk. Note this is a max. *) + (match conversion_mode with +@@ -377,27 +377,28 @@ and print_mpstat chan { mp_dev = dev; mp_path = path; + * + * Also make sure filesystems have available inodes. (RHBZ#1764569) + *) +-and check_guest_free_space mpstats = ++and check_guest_free_space inspect mpstats = + message (f_"Checking for sufficient free disk space in the guest"); + + (* Check whether /boot has its own mount point. *) + let has_boot = List.exists (fun { mp_path } -> mp_path = "/boot") mpstats in ++ let is_windows = inspect.i_distro = "windows" in + +- let needed_bytes_for_mp = function +- | "/boot" +- | "/" when not has_boot -> +- (* We usually regenerate the initramfs, which has a +- * typical size of 20-30MB. Hence: +- *) +- 50_000_000L +- | "/" -> +- (* We may install some packages, and they would usually go +- * on the root filesystem. +- *) +- 20_000_000L +- | _ -> +- (* For everything else, just make sure there is some free space. *) +- 10_000_000L ++ let needed_megabytes_for_mp = function ++ (* We usually regenerate the initramfs, which has a ++ * typical size of 20-30MB. Hence: ++ *) ++ | "/boot" | "/" when not has_boot && not is_windows -> 50 ++ (* We may install some packages, and they would usually go ++ * on the root filesystem. ++ *) ++ | "/" when not is_windows -> 20 ++ (* Windows requires copying in many device drivers and possibly ++ * guest agents, so we need more space. (RHBZ#1949147). ++ *) ++ | "/" (* when is_windows *) -> 100 ++ (* For everything else, just make sure there is some free space. *) ++ | _ -> 10 + in + + (* Reasonable headroom for conversion operations. *) +@@ -407,10 +408,13 @@ and check_guest_free_space mpstats = + fun { mp_path; mp_statvfs = { G.bfree; bsize; files; ffree } } -> + (* bfree = free blocks for root user *) + let free_bytes = bfree *^ bsize in +- let needed_bytes = needed_bytes_for_mp mp_path in +- if free_bytes < needed_bytes then +- error (f_"not enough free space for conversion on filesystem ‘%s’. %Ld bytes free < %Ld bytes needed") +- mp_path free_bytes needed_bytes; ++ let needed_megabytes = needed_megabytes_for_mp mp_path in ++ let needed_bytes = Int64.of_int needed_megabytes *^ 1024L *^ 1024L in ++ if free_bytes < needed_bytes then ( ++ let mb i = Int64.to_float i /. 1024. /. 1024. in ++ error (f_"not enough free space for conversion on filesystem ‘%s’. %.1f MB free < %d MB needed") ++ mp_path (mb free_bytes) needed_megabytes ++ ); + (* Not all the filesystems have inode counts. *) + if files > 0L && ffree < needed_inodes then + error (f_"not enough available inodes for conversion on filesystem ‘%s’. %Ld inodes available < %Ld inodes needed") +-- +2.18.4 + diff --git a/SOURCES/0039-v2v-windows-Allow-qxldod.inf-as-synonym-for-qxl.inf.patch b/SOURCES/0039-v2v-windows-Allow-qxldod.inf-as-synonym-for-qxl.inf.patch new file mode 100644 index 0000000..c719b08 --- /dev/null +++ b/SOURCES/0039-v2v-windows-Allow-qxldod.inf-as-synonym-for-qxl.inf.patch @@ -0,0 +1,30 @@ +From 575cb719ceb56d5f1812b6580f3a181bd95f5030 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 27 Apr 2021 17:29:42 +0100 +Subject: [PATCH] v2v: windows: Allow qxldod.inf as synonym for qxl.inf + +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1926102 +Thanks: Xiaodai Wang, Ming Xie +(cherry picked from commit 11d1f3cd6878ae7713e589194f97526f744dc090) +--- + v2v/windows_virtio.ml | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml +index 4e00cd61..b8256bad 100644 +--- a/v2v/windows_virtio.ml ++++ b/v2v/windows_virtio.ml +@@ -155,7 +155,9 @@ let rec install_drivers ((g, _) as reg) inspect rcaps = + + (* Can we install the QXL driver? *) + let video : guestcaps_video_type = +- let has_qxl = g#exists (driverdir // "qxl.inf") in ++ let has_qxl = ++ g#exists (driverdir // "qxl.inf") || ++ g#exists (driverdir // "qxldod.inf") in + match rcaps.rcaps_video, has_qxl with + | Some QXL, false -> + error (f_"there is no QXL driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s") +-- +2.18.4 + diff --git a/SOURCES/0040-RHEL-8-docs-Fix-version-of-virt-v2v-which-added-UEFI.patch b/SOURCES/0040-RHEL-8-docs-Fix-version-of-virt-v2v-which-added-UEFI.patch new file mode 100644 index 0000000..13013b1 --- /dev/null +++ b/SOURCES/0040-RHEL-8-docs-Fix-version-of-virt-v2v-which-added-UEFI.patch @@ -0,0 +1,28 @@ +From e8d3beabfba4b309296569e84b275724e3cd9709 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 30 Jun 2021 16:18:20 +0100 +Subject: [PATCH] RHEL 8: docs: Fix version of virt-v2v which added UEFI for + OpenStack + +Reported-by: Tingting Zheng +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1872100#c7 +--- + docs/virt-v2v-support.pod | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/docs/virt-v2v-support.pod b/docs/virt-v2v-support.pod +index 1ffc0f9d..a9bfffab 100644 +--- a/docs/virt-v2v-support.pod ++++ b/docs/virt-v2v-support.pod +@@ -38,7 +38,7 @@ hypervisor, else you will have to adjust paths in the metadata. + + =item UEFI on OpenStack + +-Supported since virt-v2v E 1.43.2. ++Supported since virt-v2v E 1.42.0-7. + + =item UEFI on oVirt or RHV + +-- +2.18.4 + diff --git a/SOURCES/0041-v2v-Increase-Linux-minimum-root-filesystem-to-100-MB.patch b/SOURCES/0041-v2v-Increase-Linux-minimum-root-filesystem-to-100-MB.patch new file mode 100644 index 0000000..b6509b9 --- /dev/null +++ b/SOURCES/0041-v2v-Increase-Linux-minimum-root-filesystem-to-100-MB.patch @@ -0,0 +1,60 @@ +From 906e087d6c57d4c1f24ecb60f98a6c98f75881a7 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 20 May 2021 09:10:20 +0100 +Subject: [PATCH] v2v: Increase Linux minimum root filesystem to 100 MB + +Ming Xie created a RHEL 8.3 guest which required around 70 MB free in +order to recreate the initramfs (temporary space used by the pigz +step). Increase the minimum space required to 100 MB, the same as for +Windows. + +Seealso commit dfcf60c916a986a352938b432231a36558a3bc05. + +Reported-by: Ming Xie +Fixes: https://bugzilla.redhat.com/1764569#c16 +(cherry picked from commit e82ff27c3bea5ce2cc3b7d1ce8d775989fc7e5a5) +--- + docs/virt-v2v.pod | 2 +- + v2v/v2v.ml | 12 +++++------- + 2 files changed, 6 insertions(+), 8 deletions(-) + +diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod +index 4016c724..4ecce369 100644 +--- a/docs/virt-v2v.pod ++++ b/docs/virt-v2v.pod +@@ -1290,7 +1290,7 @@ to perform the conversion. Currently it checks: + + =item Linux root filesystem + +-Minimum free space: 20 MB ++Minimum free space: 100 MB + + =item Linux F + +diff --git a/v2v/v2v.ml b/v2v/v2v.ml +index bde51885..8af86687 100644 +--- a/v2v/v2v.ml ++++ b/v2v/v2v.ml +@@ -389,14 +389,12 @@ and check_guest_free_space inspect mpstats = + * typical size of 20-30MB. Hence: + *) + | "/boot" | "/" when not has_boot && not is_windows -> 50 +- (* We may install some packages, and they would usually go +- * on the root filesystem. ++ (* Both Linux and Windows require installation of files, ++ * device drivers and guest agents. ++ * https://bugzilla.redhat.com/1949147 ++ * https://bugzilla.redhat.com/1764569#c16 + *) +- | "/" when not is_windows -> 20 +- (* Windows requires copying in many device drivers and possibly +- * guest agents, so we need more space. (RHBZ#1949147). +- *) +- | "/" (* when is_windows *) -> 100 ++ | "/" -> 100 + (* For everything else, just make sure there is some free space. *) + | _ -> 10 + in +-- +2.18.4 + diff --git a/SOURCES/0042-v2v-rhv-upload-plugin-Fix-waiting-for-finalize.patch b/SOURCES/0042-v2v-rhv-upload-plugin-Fix-waiting-for-finalize.patch new file mode 100644 index 0000000..d637b66 --- /dev/null +++ b/SOURCES/0042-v2v-rhv-upload-plugin-Fix-waiting-for-finalize.patch @@ -0,0 +1,179 @@ +From 419aa23f0c6338b01b644094c3af2c024470e9b2 Mon Sep 17 00:00:00 2001 +From: Nir Soffer +Date: Sat, 10 Jul 2021 02:35:27 +0300 +Subject: [PATCH] v2v: rhv-upload-plugin: Fix waiting for finalize + +Waiting for image transfer finalize is complex. In the past we tried to +simplify the process by waiting on the disk status, but turns out that +due to the way oVirt lock the disk, this is not reliable. + +These is finalize success flow: + +1. User asks to finalize the transfer +2. oVirt sets transfer phase to FINALIZING_SUCCESS +3. oVirt finalizes the transfer +4. oVirt sets disk status to OK +5. oVirt unlocks the disk and changes transfer phase to FINISHED_SUCCESS +6. oVirt removes the transfer + +In oVirt logs we can see that disk status changes to OK about 3 seconds +before the disk is actually unlocked. This is a very old problem that is +unlikely to be fixed. + +The only way to wait for transfer completion is to poll the transfer +phase, but oVirt makes this hard by removing the transfer shortly after +it completes, so we may not be able to get the FINISHED_SUCCESS phase. +If the transfer was removed before we got one of the final phases, we +need to check the disk status to understand the result of transfer. + +oVirt 4.4.7 made polling transfer phase easier by keeping the transfer +after completion, but we need to support older versions so we must have +generic code that work with any version. + +To make debugging easier, we log the transfer phase during polling. Here +is a typical transfer log when finalizing transfer: + + finalizing transfer 59e545f3-db1f-4a6b-90b1-80ac66572faa + transfer 59e545f3-db1f-4a6b-90b1-80ac66572faa is finalizing_success + transfer 59e545f3-db1f-4a6b-90b1-80ac66572faa is finalizing_success + transfer 59e545f3-db1f-4a6b-90b1-80ac66572faa is finalizing_success + transfer 59e545f3-db1f-4a6b-90b1-80ac66572faa is finalizing_success + transfer 59e545f3-db1f-4a6b-90b1-80ac66572faa is finished_success + transfer 59e545f3-db1f-4a6b-90b1-80ac66572faa finalized in 5.153 seconds + +Signed-off-by: Nir Soffer +Fixes: https://bugzilla.redhat.com/1976024 +(cherry picked from commit 79702b28329d15a7485801ed7e915d486fcc0cf4) +--- + v2v/rhv-upload-plugin.py | 98 ++++++++++++++++++++++++++++------------ + 1 file changed, 69 insertions(+), 29 deletions(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 7cd6dea6..61ade1a8 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -601,17 +601,29 @@ def finalize_transfer(connection, transfer, disk_id): + """ + Finalize a transfer, making the transfer disk available. + +- If finalizing succeeds, transfer's phase will change to FINISHED_SUCCESS +- and the transer's disk status will change to OK. On errors, the transfer's +- phase will change to FINISHED_FAILURE and the disk status will change to +- ILLEGAL and it will be removed. In both cases the transfer entity will be +- removed shortly after. ++ If finalizing succeeds, the transfer's disk status will change to OK ++ and transfer's phase will change to FINISHED_SUCCESS. Unfortunately, ++ the disk status is modified before the transfer finishes, and oVirt ++ may still hold a lock on the disk at this point. + +- If oVirt fails to finalize the transfer, transfer's phase will change to +- PAUSED_SYSTEM. In this case the disk's status will change to ILLEGAL and it +- will not be removed. ++ The only way to make sure that the disk is unlocked, is to wait ++ until the transfer phase switches FINISHED_SUCCESS. Unfortunately ++ oVirt makes this hard to use because the transfer is removed shortly ++ after switching the phase to the final phase. However if the ++ transfer was removed, we can be sure that the disk is not locked, ++ since oVirt releases the locks before removing the transfer. + +- For simplicity, we track only disk's status changes. ++ On errors, the transfer's phase will change to FINISHED_FAILURE and ++ the disk status will change to ILLEGAL and it will be removed. Again ++ the transfer will be removed shortly after that. ++ ++ If oVirt fails to finalize the transfer, transfer's phase will ++ change to PAUSED_SYSTEM. In this case the disk's status will change ++ to ILLEGAL and it will not be removed. ++ ++ oVirt 4.4.7 made waiting for transfer easier by keeping transfers ++ after they complete, but we must support older versions so we have ++ generic code that work with any version. + + For more info see: + - http://ovirt.github.io/ovirt-engine-api-model/4.4/#services/image_transfer +@@ -626,34 +638,62 @@ def finalize_transfer(connection, transfer, disk_id): + + transfer_service.finalize() + +- disk_service = (connection.system_service() +- .disks_service() +- .disk_service(disk_id)) +- + while True: + time.sleep(1) + try: +- disk = disk_service.get() ++ transfer = transfer_service.get() + except sdk.NotFoundError: +- # Disk verification failed and the system removed the disk. +- raise RuntimeError( +- "transfer %s failed: disk %s was removed" +- % (transfer.id, disk_id)) ++ # Transfer was removed (ovirt < 4.4.7). We need to check the ++ # disk status to understand if the transfer was successful. ++ # Due to the way oVirt does locking, we know that the disk ++ # is unlocked at this point so we can check only once. + +- if disk.status == types.DiskStatus.ILLEGAL: +- # Disk verification failed or transfer was paused by the system. +- raise RuntimeError( +- "transfer %s failed: disk is ILLEGAL" % transfer.id) ++ debug("transfer %s was removed, checking disk %s status" ++ % (transfer.id, disk_id)) ++ ++ disk_service = (connection.system_service() ++ .disks_service() ++ .disk_service(disk_id)) + +- if disk.status == types.DiskStatus.OK: +- debug("transfer %s finalized in %.3f seconds" +- % (transfer.id, time.time() - start)) +- break ++ try: ++ disk = disk_service.get() ++ except sdk.NotFoundError: ++ raise RuntimeError( ++ "transfer %s failed: disk %s was removed" ++ % (transfer.id, disk_id)) ++ ++ debug("disk %s is %s" % (disk_id, disk.status)) ++ ++ if disk.status == types.DiskStatus.OK: ++ break + +- if time.time() > start + timeout: + raise RuntimeError( +- "timed out waiting for transfer %s to finalize" +- % transfer.id) ++ "transfer %s failed: disk is %s" % (transfer.id, disk.status)) ++ else: ++ # Transfer exists, check if it reached one of the final ++ # phases, or we timed out. ++ ++ debug("transfer %s is %s" % (transfer.id, transfer.phase)) ++ ++ if transfer.phase == types.ImageTransferPhase.FINISHED_SUCCESS: ++ break ++ ++ if transfer.phase == types.ImageTransferPhase.FINISHED_FAILURE: ++ raise RuntimeError( ++ "transfer %s has failed" % (transfer.id,)) ++ ++ if transfer.phase == types.ImageTransferPhase.PAUSED_SYSTEM: ++ raise RuntimeError( ++ "transfer %s was paused by system" % (transfer.id,)) ++ ++ if time.time() > start + timeout: ++ raise RuntimeError( ++ "timed out waiting for transfer %s to finalize, " ++ "transfer is %s" ++ % (transfer.id, transfer.phase)) ++ ++ debug("transfer %s finalized in %.3f seconds" ++ % (transfer.id, time.time() - start)) + + + def transfer_supports_format(): +-- +2.18.4 + diff --git a/SOURCES/0043-v2v-windows-Do-not-fix-NTFS-heads-in-Windows-Vista-a.patch b/SOURCES/0043-v2v-windows-Do-not-fix-NTFS-heads-in-Windows-Vista-a.patch new file mode 100644 index 0000000..716acd1 --- /dev/null +++ b/SOURCES/0043-v2v-windows-Do-not-fix-NTFS-heads-in-Windows-Vista-a.patch @@ -0,0 +1,80 @@ +From 72f50e52515369ef8decda9493422d6235f5b365 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 18 Aug 2021 11:00:12 +0100 +Subject: [PATCH] v2v: windows: Do not fix NTFS heads in Windows Vista and + later + +Setting/adjusting the number of drive heads in the NTFS header is only +necessary for ancient versions of Windows. Modern versions ignore +this. In addition this operation broke when we added BitLocker +support. Only do this for ancient Windows 2000/XP and skip it for +everything else. + +Reported-by: Ming Xie +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1994984 +(cherry picked from commit 0a394c5c2f802098c9e481b4bacee7821e5dd0ae) +--- + v2v/convert_windows.ml | 44 ++++++++++++++++++++++-------------------- + 1 file changed, 23 insertions(+), 21 deletions(-) + +diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml +index 33fbd410..13de10cb 100644 +--- a/v2v/convert_windows.ml ++++ b/v2v/convert_windows.ml +@@ -730,30 +730,32 @@ if errorlevel 3010 exit /b 0 + however, as this is specific to Windows 2003 it lists location + 0x1A as unused. + *) +- let rootpart = inspect.i_root in ++ if inspect.i_major_version < 6 (* is Windows 2000/XP *) then ( ++ let rootpart = inspect.i_root in + +- (* Ignore if the rootpart is something like /dev/sda. RHBZ#1276540. *) +- if not (g#is_whole_device rootpart) then ( +- (* Check that the root device contains NTFS magic. *) +- let magic = g#pread_device rootpart 8 3L in +- if magic = "NTFS " then ( +- (* Get the size of the whole disk containing the root partition. *) +- let rootdev = g#part_to_dev rootpart in (* eg. /dev/sda *) +- let size = g#blockdev_getsize64 rootdev in ++ (* Ignore if the rootpart is something like /dev/sda. RHBZ#1276540. *) ++ if not (g#is_whole_device rootpart) then ( ++ (* Check that the root device contains NTFS magic. *) ++ let magic = g#pread_device rootpart 8 3L in ++ if magic = "NTFS " then ( ++ (* Get the size of the whole disk containing the root partition. *) ++ let rootdev = g#part_to_dev rootpart in (* eg. /dev/sda *) ++ let size = g#blockdev_getsize64 rootdev in + +- let heads = (* refer to the table above *) +- if size < 2114445312L then 0x40 +- else if size < 4228374780L then 0x80 +- else 0xff in ++ let heads = (* refer to the table above *) ++ if size < 2114445312L then 0x40 ++ else if size < 4228374780L then 0x80 ++ else 0xff in + +- (* Update NTFS's idea of the number of heads. This is an +- * unsigned 16 bit little-endian integer, offset 0x1a from the +- * beginning of the partition. +- *) +- let b = Bytes.create 2 in +- Bytes.unsafe_set b 0 (Char.chr heads); +- Bytes.unsafe_set b 1 '\000'; +- ignore (g#pwrite_device rootpart (Bytes.to_string b) 0x1a_L) ++ (* Update NTFS's idea of the number of heads. This is an ++ * unsigned 16 bit little-endian integer, offset 0x1a from the ++ * beginning of the partition. ++ *) ++ let b = Bytes.create 2 in ++ Bytes.unsafe_set b 0 (Char.chr heads); ++ Bytes.unsafe_set b 1 '\000'; ++ ignore (g#pwrite_device rootpart (Bytes.to_string b) 0x1a_L) ++ ) + ) + ) + +-- +2.18.4 + diff --git a/SOURCES/SOURCES b/SOURCES/SOURCES new file mode 100644 index 0000000..e5f23a5 --- /dev/null +++ b/SOURCES/SOURCES @@ -0,0 +1,18 @@ +Source Offer + +A complete machine-readable copy of the source code corresponding to +portions of the accompanying package is available upon request. This +offer is valid to anyone in receipt of this information and shall +expire three years following the date of the final distribution of +this package by Red Hat, Inc. + +To obtain such source code, send a check or money order in the amount +of US$10.00 to: + +General Counsel +Red Hat, Inc. +100 East Davie Street +Raleigh, NC 27601 USA + +Please specify the name, version and release of the package for which +you are requesting corresponding source code. diff --git a/SOURCES/copy-patches.sh b/SOURCES/copy-patches.sh new file mode 100755 index 0000000..9ee98b6 --- /dev/null +++ b/SOURCES/copy-patches.sh @@ -0,0 +1,55 @@ +#!/bin/bash - + +set -e + +# Maintainer script to copy patches from the git repo to the current +# directory. Use it like this: +# ./copy-patches.sh + +rhel_version=av-8.5.0 + +# Check we're in the right directory. +if [ ! -f virt-v2v.spec ]; then + echo "$0: run this from the directory containing 'virt-v2v.spec'" + exit 1 +fi + +git_checkout=$HOME/d/virt-v2v-rhel-$rhel_version +if [ ! -d $git_checkout ]; then + echo "$0: $git_checkout does not exist" + echo "This script is only for use by the maintainer when preparing a" + echo "virt-v2v release on RHEL." + exit 1 +fi + +# Get the base version of virt-v2v. +version=`grep '^Version:' virt-v2v.spec | awk '{print $2}'` +tag="v$version" + +# Remove any existing patches. +git rm -f [0-9]*.patch ||: +rm -f [0-9]*.patch + +# Get the patches. +(cd $git_checkout; rm -f [0-9]*.patch; git format-patch -N --submodule=diff $tag) +mv $git_checkout/[0-9]*.patch . + +# Remove any not to be applied. +rm -f *NOT-FOR-RPM*.patch + +# Add the patches. +git add [0-9]*.patch + +# Print out the patch lines. +echo +echo "--- Copy the following text into virt-v2v.spec file" +echo + +echo "# Patches." +for f in [0-9]*.patch; do + n=`echo $f | awk -F- '{print $1}'` + echo "Patch$n: $f" +done + +echo +echo "--- End of text" diff --git a/SOURCES/virt-v2v-1.42.0.tar.gz.sig b/SOURCES/virt-v2v-1.42.0.tar.gz.sig new file mode 100644 index 0000000..6b56583 --- /dev/null +++ b/SOURCES/virt-v2v-1.42.0.tar.gz.sig @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAl6YQ9QRHHJpY2hAYW5u +ZXhpYS5vcmcACgkQkXOPc+G3aKAgTBAAiT/ojN14i0NRzpuGSb7I9oupzclVqic8 +c5NIXH8TGYLY9tVMYSsr+uyWu8Qk2lsqV6knXeqbBKot/682v2AlYn6ZpG+cl8tm +ZKjVSwMwLVdAvV5zTaggEO/Xs8WbtSkmTk184s62804qlc+mv0ngFTGZomKjH4o1 +tHgJnegeR/lppeBnIuhAC/hWo6SyhPul8UnDg3rnByWOX7Qs3p4lY9y5hHv2pQfK +ezXLDYBBAtQ3oe3p8jh3SCe7GLxxX8oxDCn6l8K7AK4czRMLJ/iykS/iE+E1bazM +V7rUItPfK3MhrWThlekn4u5tOclCDKbK75Hgkb2qjeK9Ctad80boXnNEnIv0UWFr +SaqCKmJrOtohn2oR/aUmTXm2u09jy+nQTRhvqy/2TNTdExCa1A6n7r0EcEJQMQPX +DK34+cbn3J+/+BA9kyH2a2/pTwJBaCk4PCXyrxWAkHyLUt9HZwmtPXUeBhq/iMIf +QZSo/LgXTTNEpsFx5K3xuvy6Ps/IaImeI8xdU2wl252/HN4wY3roZOBNflbTCF2m +aXFXf6bReZmO9HJg5674zCYkB0N8nSPMaHmv7EWyK7sEMKCUuYnWMiEBHtIZA+dW +Qp3IdoODkjciwVzJL2E7RhA2GNvwnkay4WYqb0mjAPVktVTnhla7S1hSD8SM6Fs7 +sVAPrKAFidk= +=l3OH +-----END PGP SIGNATURE----- diff --git a/SPECS/virt-v2v.spec b/SPECS/virt-v2v.spec new file mode 100644 index 0000000..c4518b8 --- /dev/null +++ b/SPECS/virt-v2v.spec @@ -0,0 +1,454 @@ +# If we should verify tarball signature with GPGv2. +%global verify_tarball_signature 1 + +# If there are patches which touch autotools files, set this to 1. +%global patches_touch_autotools 1 + +# The source directory. +%global source_directory 1.42-stable + +Name: virt-v2v +Epoch: 1 +Version: 1.42.0 +Release: 15%{?dist} +Summary: Convert a virtual machine to run on KVM + +License: GPLv2+ +URL: https://github.com/libguestfs/virt-v2v + +Source0: http://download.libguestfs.org/virt-v2v/%{source_directory}/%{name}-%{version}.tar.gz +%if 0%{verify_tarball_signature} +Source1: http://download.libguestfs.org/virt-v2v/%{source_directory}/%{name}-%{version}.tar.gz.sig +# Keyring used to verify tarball signature. +Source2: libguestfs.keyring +%endif + +# Architectures where virt-v2v is shipped. +# +# not on aarch64 because it is not useful there +# not on %%{power64} because of RHBZ#1287826 +# not on s390x because it is not useful there +ExclusiveArch: x86_64 + +# RHEL 8 git repository is: +# https://github.com/libguestfs/virt-v2v/tree/rhel-av-8.5.0 +# Use 'copy-patches.sh' to copy the patches from the git repo +# to the current directory. + +# Patches. +Patch0001: 0001-libvirt-make-use-of-libvirt-s-default-auth-handler-R.patch +Patch0002: 0002-i-libvirt-print-URI-without-connecting-RHBZ-1839917.patch +Patch0003: 0003-vCenter-fix-parsing-of-HTTP-status-string-RHBZ-18373.patch +Patch0004: 0004-v2v-o-libvirt-Remove-cache-none-RHBZ-1837453.patch +Patch0005: 0005-v2v-Remove-extraneous-when-setting-bandwidth-RHBZ-18.patch +Patch0006: 0006-v2v-it-vddk-Don-t-use-nbdkit-readahead-filter-with-V.patch +Patch0007: 0007-v2v-nbdkit-Handle-password-parameter-in-common_creat.patch +Patch0008: 0008-v2v-nbdkit-Don-t-use-password-parameter-RHBZ-1842440.patch +Patch0009: 0009-libosinfo-declare-autocleanup-funcs-with-libosinfo-1.patch +Patch0010: 0010-v2v-Use-common-documentation-for-keys-from-stdin.patch +Patch0011: 0011-docs-Multiple-keys-must-be-supplied-one-per-line-RHB.patch +Patch0012: 0012-v2v-Check-that-mac-ip-parameters-are-sensible-RHBZ-1.patch +Patch0013: 0013-libvirt-read-password-file-outside-libvirt-auth-call.patch +Patch0014: 0014-RHEL-8-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch +Patch0015: 0015-RHEL-8-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch +Patch0016: 0016-RHEL-8-Fix-list-of-supported-sound-cards-to-match-RH.patch +Patch0017: 0017-RHEL-8-Fix-tests-for-libguestfs-winsupport.patch +Patch0018: 0018-RHEL-8-v2v-Disable-the-virt-v2v-in-place-option.patch +Patch0019: 0019-RHEL-8-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch +Patch0020: 0020-RHEL-8-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch +Patch0021: 0021-RHEL-8-v2v-rhv-upload-Remove-restriction-on-oa-spars.patch +Patch0022: 0022-RHEL-8-use-platform-python.patch +Patch0023: 0023-RHEL-8-point-to-KB-for-supported-v2v-hypervisors-gue.patch +Patch0024: 0024-v2v-Allow-large-temporary-directory-to-be-set-on-a-g.patch +Patch0025: 0025-v2v-o-openstack-Allow-guests-to-be-converted-to-UEFI.patch +Patch0026: 0026-v2v-Fix-spelling-mistake-in-uninstall-function-name.patch +Patch0027: 0027-v2v-windows-Refactor-uninstallation_commands-functio.patch +Patch0028: 0028-v2v-Replace-broken-VMware-Tools-uninstall-command-ms.patch +#Patch0029: 0029-Update-common-submodule-to-latest-upstream.patch +Patch0030: 0030-v2v-rhv-upload-plugin-Defer-imageio-connection.patch +Patch0031: 0031-v2v-windows-Fix-schtasks-SD-parameter.patch +Patch0032: 0032-v2v-Turn-pnp_wait.exe-warning-into-a-debug-message.patch +Patch0033: 0033-docs-UEFI-guest-conversion-to-o-openstack-is-support.patch +Patch0034: 0034-docs-o-openstack-Clarify-name-of-file-containing-Ope.patch +Patch0035: 0035-v2v-Allow-output-to-block-devices-RHBZ-1868690.patch +Patch0036: 0036-v2v-Disable-readahead-for-VMware-curl-sources-too-RH.patch +Patch0037: 0037-docs-Document-how-to-remove-Out-of-HTTP-sessions-lim.patch +Patch0038: 0038-v2v-Increase-required-free-space-in-Windows-to-100-M.patch +Patch0039: 0039-v2v-windows-Allow-qxldod.inf-as-synonym-for-qxl.inf.patch +Patch0040: 0040-RHEL-8-docs-Fix-version-of-virt-v2v-which-added-UEFI.patch +Patch0041: 0041-v2v-Increase-Linux-minimum-root-filesystem-to-100-MB.patch +Patch0042: 0042-v2v-rhv-upload-plugin-Fix-waiting-for-finalize.patch +Patch0043: 0043-v2v-windows-Do-not-fix-NTFS-heads-in-Windows-Vista-a.patch + +# Patches which apply to the common/ submodule. +# These have to be hand-modified. +Patch1001: 0001-options-Use-new-cryptsetup-open-API-if-available.patch +Patch1002: 0002-options-Use-cryptX-instead-of-luksX-as-the-temporary.patch +Patch1003: 0003-options-Support-Windows-BitLocker-RHBZ-1808977.patch +Patch1004: 0004-options-Ignore-errors-from-guestfs_luks_uuid.patch + +# Use git for patch management. +BuildRequires: git + +%if 0%{patches_touch_autotools} +BuildRequires: autoconf, automake, libtool +%endif + +# RHSRVANY and RHEV-APT, used for Windows virt-v2v conversions. +# RHSRVANY is built from source under Fedora from +# mingw32-srvany-1.0-15.20150115gitfd659e77.fc23.noarch +# RHEV-APT is taken from the RHEV Tools CD +# See https://bugzilla.redhat.com/show_bug.cgi?id=1186850 +Source94: rhsrvany-fd659e77cdd9da484fdc9dcbe0605c62ec26fa30.tar.gz +Source95: SOURCES +Source96: rhsrvany.exe +Source97: RHEV-Application-Provisioning-Tool.exe_4.43-5 + +Source99: copy-patches.sh + +BuildRequires: /usr/bin/pod2man +BuildRequires: gcc +BuildRequires: ocaml >= 4.01 +BuildRequires: libguestfs-devel >= 1:1.42 + +BuildRequires: augeas-devel +BuildRequires: bash-completion +BuildRequires: file-devel +BuildRequires: gettext-devel +BuildRequires: jansson-devel +BuildRequires: libosinfo-devel +BuildRequires: libvirt-devel +BuildRequires: libvirt-daemon-kvm +BuildRequires: libxml2-devel +BuildRequires: pcre-devel +BuildRequires: perl(Sys::Guestfs) +BuildRequires: po4a +BuildRequires: /usr/bin/virsh + +BuildRequires: ocaml-findlib-devel +BuildRequires: ocaml-libguestfs-devel +BuildRequires: ocaml-fileutils-devel +BuildRequires: ocaml-gettext-devel + +BuildRequires: nbdkit-python-plugin + +%if 0%{verify_tarball_signature} +BuildRequires: gnupg2 +%endif + +Requires: libguestfs%{?_isa} >= 1:1.42 +Requires: libguestfs-tools-c >= 1:1.42 + +# For Windows conversions. +Requires: libguestfs-winsupport >= 7.2 + +Requires: gawk +Requires: gzip +Requires: unzip +Requires: curl + +# Ensure the UEFI firmware is available, to properly convert +# EFI guests (RHBZ#1429643). +%ifarch x86_64 +Requires: edk2-ovmf +%endif +%ifarch aarch64 +Requires: edk2-aarch64 +%endif + +# Needed for -it vddk, and -o rhv-upload. +Requires: nbdkit +Requires: nbdkit-curl-plugin +Requires: nbdkit-python-plugin +Requires: nbdkit-ssh-plugin +Requires: nbdkit-vddk-plugin +Requires: platform-python + + +%description +Virt-v2v converts a single guest from a foreign hypervisor to run on +KVM. It can read Linux and Windows guests running on VMware, Xen, +Hyper-V and some other hypervisors, and convert them to KVM managed by +libvirt, OpenStack, oVirt, Red Hat Virtualisation (RHV) or several +other targets. It can modify the guest to make it bootable on KVM and +install virtio drivers so it will run quickly. + + +%package bash-completion +Summary: Bash tab-completion for %{name} +BuildArch: noarch +Requires: bash-completion >= 2.0 +Requires: %{name} = %{epoch}:%{version}-%{release} + +# The bash completion for virt-v2v were shipped with the others of libguestfs: +Obsoletes: libguestfs-bash-completion < 1:1.42.0 + + +%description bash-completion +Install this package if you want intelligent bash tab-completion +for %{name}. + + +%package man-pages-ja +Summary: Japanese (ja) man pages for %{name} +BuildArch: noarch +Requires: %{name} = %{epoch}:%{version}-%{release} + +# The man pages for virt-v2v were shipped with the others of libguestfs: +Obsoletes: libguestfs-man-pages-ja < 1:1.42.0 + +%description man-pages-ja +%{name}-man-pages-ja contains Japanese (ja) man pages +for %{name}. + + +%package man-pages-uk +Summary: Ukrainian (uk) man pages for %{name} +BuildArch: noarch +Requires: %{name} = %{epoch}:%{version}-%{release} + +# The man pages for virt-v2v were shipped with the others of libguestfs: +Obsoletes: libguestfs-man-pages-uk < 1:1.42.0 + +%description man-pages-uk +%{name}-man-pages-uk contains Ukrainian (uk) man pages +for %{name}. + + +%prep +%if 0%{verify_tarball_signature} +tmphome="$(mktemp -d)" +gpgv2 --homedir "$tmphome" --keyring %{SOURCE2} %{SOURCE1} %{SOURCE0} +%endif +%setup -q + +# Use git to manage patches. +# http://rwmj.wordpress.com/2011/08/09/nice-rpm-git-patch-management-trick/ +git init +git config user.email "libguestfs@redhat.com" +git config user.name "libguestfs" +git add . +git commit -a -q -m "%{version} baseline" +git am %{patches} + +%if 0%{patches_touch_autotools} +autoreconf -fi +%endif + + +%build +%configure \ + --with-extra="rhel=%{rhel},release=%{release}" + +make V=1 %{?_smp_mflags} + + +%install +%make_install + +# Virt-tools data directory. +mkdir -p $RPM_BUILD_ROOT%{_datadir}/virt-tools +cp %{SOURCE96} $RPM_BUILD_ROOT%{_datadir}/virt-tools/rhsrvany.exe +cp %{SOURCE97} $RPM_BUILD_ROOT%{_datadir}/virt-tools/rhev-apt.exe + +# Delete the v2v test harness. +rm -r $RPM_BUILD_ROOT%{_libdir}/ocaml/v2v_test_harness +rm -r $RPM_BUILD_ROOT%{_libdir}/ocaml/stublibs/dllv2v_test_harness* +rm $RPM_BUILD_ROOT%{_mandir}/man1/virt-v2v-test-harness.1* + +# Find locale files. +%find_lang %{name} + + +%check +# All tests fail at the moment because of bugs in libvirt blockdev. +# # Tests fail on both armv7 and ppc64le in Fedora 31 because the kernel +# # cannot boot on qemu. +# %ifnarch %{arm} ppc64le + +# # On x86_64 this single test fails with: "virt-v2v: warning: the +# # target hypervisor does not support a x86_64 KVM guest". Missing +# # BuildRequires? +# %ifarch x86_64 +# truncate -s 0 tests/test-v2v-o-libvirt.sh +# %endif + +# # This test fails in mock. +# truncate -s 0 tests/test-v2v-oa-option.sh + +# # Make sure we can see the debug messages (RHBZ#1230160). +# export LIBGUESTFS_DEBUG=1 +# export LIBGUESTFS_TRACE=1 + +# make %{?_smp_mflags} check || { +# cat tests/test-suite.log +# exit 1 +# } + +# %endif + + +%files -f %{name}.lang +%doc COPYING README +%{_bindir}/virt-v2v +%{_bindir}/virt-v2v-copy-to-local +%{_mandir}/man1/virt-v2v.1* +%{_mandir}/man1/virt-v2v-copy-to-local.1* +%{_mandir}/man1/virt-v2v-hacking.1* +%{_mandir}/man1/virt-v2v-input-vmware.1* +%{_mandir}/man1/virt-v2v-input-xen.1* +%{_mandir}/man1/virt-v2v-output-local.1* +%{_mandir}/man1/virt-v2v-output-openstack.1* +%{_mandir}/man1/virt-v2v-output-rhv.1* +%{_mandir}/man1/virt-v2v-release-notes-1.42.1* +%{_mandir}/man1/virt-v2v-support.1* +%{_datadir}/virt-tools + + +%files bash-completion +%doc COPYING +%{_datadir}/bash-completion/completions/virt-v2v +%{_datadir}/bash-completion/completions/virt-v2v-copy-to-local + + +%files man-pages-ja +%doc COPYING +%lang(ja) %{_mandir}/ja/man1/*.1* + + +%files man-pages-uk +%doc COPYING +%lang(uk) %{_mandir}/uk/man1/*.1* + + +%changelog +* Wed Aug 18 2021 Richard W.M. Jones - 1:1.42.0-15 +- v2v: windows: Do not fix NTFS heads in Windows Vista and later + resolves: rhbz#1995000 + +* Fri Jul 16 2021 Richard W.M. Jones - 1:1.42.0-14 +- v2v: rhv-upload-plugin: Fix waiting for finalize + resolves: rhbz#1976024 + +* Wed Jun 30 2021 Richard W.M. Jones - 1:1.42.0-13 +- docs: Fix version of virt-v2v which added UEFI for OpenStack + related: rhbz#1872100 +- v2v: Increase Linux minimum root filesystem to 100 MB + resolves: rhbz#1764569 + +* Tue May 11 2021 Richard W.M. Jones - 1:1.42.0-12 +- v2v: Fix conversion of BitLocker guests + resolves: rhbz#1959051 + +* Tue Apr 27 2021 Richard W.M. Jones - 1:1.42.0-11 +- v2v: windows: Allow qxldod.inf as synonym for qxl.inf + resolves: rhbz#1926102 +- v2v: Increase required free space in Windows to 100 MB + resolves: rhbz#1949147 +- docs: Document how to remove "Out of HTTP sessions" limit +- v2v: Disable readahead for VMware curl sources too + resolves: rhbz#1848862 +- v2v: Allow output to block devices + resolves: rhbz#1868690 +- docs: -o openstack: Clarify name of file containing OpenStack auth + resolves: rhbz#1871754 +- docs: UEFI guest conversion to -o openstack is supported + resolves: rhbz#1872100 +- v2v: Turn pnp_wait.exe warning into a debug message + resolves: rhbz#1903960 +- v2v: windows: Fix schtasks /SD parameter + resolves: rhbz#1895323 + +* Thu Jan 21 2021 Richard W.M. Jones - 1:1.42.0-9 +- v2v: rhv-upload-plugin: Defer imageio connection + resolves: rhbz#1911568 + +* Tue Jan 19 2021 Richard W.M. Jones - 1:1.42.0-8 +- Replace broken VMware Tools uninstall command msiexec /i with /x. + resolves: rhbz#1917760 + +* Tue Jan 12 2021 Richard W.M. Jones - 1:1.42.0-7 +- Tell virt-v2v where overlay files must be placed +- Allow conversion to UEFI openstack + resolves: rhbz#1820282 rhbz#1872094 + +* Tue Sep 01 2020 Pino Toscano - 1:1.42.0-6 +- Improve the documentation of --keys-from-stdin + resolves: rhbz#1858765 +- Check that --mac :ip: parameters are sensible + resolves: rhbz#1858775 +- -i libvirt: read password file outside libvirt auth callback + resolves: rhbz#1869454 + +* Wed Jun 24 2020 Pino Toscano - 1:1.42.0-5 +- Ship a newer version of rhev-apt.exe + resolves: rhbz#1850000 +- Ship the rhsrvany sources with a note for them, as requested by + Red Hat Legal. +- -i libvirt: ask for the password ourselves instead of letting nbdkit + ask for it (and potentially time out) + related: rhbz#1838425 +- Fix build with libosinfo >= 1.8.0 + resolves: rhbz#1850423 + +* Thu May 28 2020 Pino Toscano - 1:1.42.0-4 +- -i libvirt: ask again for the password when -ip is not specified + resolves: rhbz#1838425 +- -i libvirt: print URI without connecting + resolves: rhbz#1839917 +- Handle HTTP/2 replies from vCenter + resolves: rhbz#1840126 +- -o libvirt: remove cache=none from disks + resolves: rhbz#1837453 +- Fix parameters for the nbdkit rate filter + resolves: rhbz#1841096 +- -it vddk: do not use the nbdkit readahead filter with VDDK + resolves: rhbz#1832805 + +* Wed May 06 2020 Pino Toscano - 1:1.42.0-3 +- Actually fix epoch dependencies. +- Fix virt-v2v-man-pages-uk migration from libguestfs-man-pages-uk. + +* Wed May 06 2020 Pino Toscano - 1:1.42.0-2 +- Bump the libguestfs requirement to 1.42.0. +- Bump the epoch to 1 to match the version virt-v2v had when built from + the libguestfs source. + +* Thu Apr 16 2020 Richard W.M. Jones - 1.42.0-1 +- New upstream stable version 1.42.0. + +* Sat Apr 04 2020 Richard W.M. Jones - 1.41.8-11 +- Update all OCaml dependencies for RPM 4.16. + +* Thu Feb 27 2020 Richard W.M. Jones - 1.41.8-10 +- OCaml 4.10.0 final. + +* Fri Jan 31 2020 Fedora Release Engineering - 1.41.8-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Sun Jan 19 2020 Richard W.M. Jones - 1.41.8-8 +- Bump release and rebuild. + +* Sun Jan 19 2020 Richard W.M. Jones - 1.41.8-7 +- Bump release and rebuild. + +* Sun Jan 19 2020 Richard W.M. Jones - 1.41.8-6 +- Bump release and rebuild. + +* Sun Jan 19 2020 Richard W.M. Jones - 1.41.8-5 +- OCaml 4.10.0+beta1 rebuild. +- Use nbdkit-python-plugin (now all Python 3 in Rawhide). + +* Wed Nov 27 2019 Richard W.M. Jones - 1.41.8-4 +- Use license instead of doc for COPYING file. +- Include license in all subpackages. +- Use gpgverify macro. +- Don't own bash-completion directory because we Require the + bash-completion package which owns it already. + +* Tue Nov 26 2019 Richard W.M. Jones - 1.41.8-2 +- Fix permissions on .sig file. +- Disable -oa preallocated test since it fails in reviewers mock environment. + +* Fri Nov 15 2019 Richard W.M. Jones - 1.41.8-1 +- Initial release of separate virt-v2v program, was part of libguestfs.