diff --git a/.gitignore b/.gitignore index a588c01..811e356 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -SOURCES/RHEV-Application-Provisioning-Tool.exe_4.12 -SOURCES/libguestfs-1.36.10.tar.gz +SOURCES/RHEV-Application-Provisioning-Tool.exe_4.42 +SOURCES/libguestfs-1.38.2.tar.gz SOURCES/libguestfs.keyring SOURCES/rhsrvany.exe diff --git a/.libguestfs.metadata b/.libguestfs.metadata index e7d2b1b..d3282a9 100644 --- a/.libguestfs.metadata +++ b/.libguestfs.metadata @@ -1,4 +1,4 @@ -8fec32284530ce6d485629fcbd1f7f3e005ae8a0 SOURCES/RHEV-Application-Provisioning-Tool.exe_4.12 -93c94f8c614af17078b345ea3f5f5a187194cace SOURCES/libguestfs-1.36.10.tar.gz +c44dcbd8c9b390e151c16821ff093e4dc408be66 SOURCES/RHEV-Application-Provisioning-Tool.exe_4.42 +34567b42feff61b56e0e44bb9c52a70a96950c53 SOURCES/libguestfs-1.38.2.tar.gz 1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring 2bd96e478fc004cd323b5bd754c856641877dac6 SOURCES/rhsrvany.exe diff --git a/SOURCES/0001-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch b/SOURCES/0001-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch index 36203e1..f231b46 100644 --- a/SOURCES/0001-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch +++ b/SOURCES/0001-RHEL-7-Remove-libguestfs-live-RHBZ-798980.patch @@ -1,4 +1,4 @@ -From a237b1b342e1fa7d6b0229fd9b58dad21fd07877 Mon Sep 17 00:00:00 2001 +From 54fdf8cea3fce1171e30a2c30ebbadbd9df5adaf Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 21 Dec 2012 15:50:11 +0000 Subject: [PATCH] RHEL 7: Remove libguestfs live (RHBZ#798980). @@ -9,7 +9,7 @@ This isn't supported in RHEL 7. 1 file changed, 7 insertions(+) diff --git a/lib/launch-unix.c b/lib/launch-unix.c -index 8ce4ca5b4..9be2b9c5f 100644 +index 9af481fd9..974336ccd 100644 --- a/lib/launch-unix.c +++ b/lib/launch-unix.c @@ -37,6 +37,12 @@ @@ -34,5 +34,5 @@ index 8ce4ca5b4..9be2b9c5f 100644 static int -- -2.14.3 +2.17.1 diff --git a/SOURCES/0002-RHEL-7-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch b/SOURCES/0002-RHEL-7-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch index 23a11a9..b0bb0af 100644 --- a/SOURCES/0002-RHEL-7-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch +++ b/SOURCES/0002-RHEL-7-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch @@ -1,25 +1,25 @@ -From 5cb76a0fdc42cecd218b905acfd4d3ce07faf748 Mon Sep 17 00:00:00 2001 +From 98c7c205306eb27e63b3eccc930ceab88e15be25 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 18 Jul 2013 18:31:53 +0100 Subject: [PATCH] RHEL 7: Remove 9p APIs from RHEL (RHBZ#921710). --- Makefile.am | 2 +- - daemon/9p.c | 225 ---------------------------------------------- + daemon/9p.c | 224 -------------------------------------- daemon/Makefile.am | 1 - docs/C_SOURCE_FILES | 1 - - generator/actions_core.ml | 21 ----- + generator/actions_core.ml | 21 ---- generator/proc_nr.ml | 2 - gobject/Makefile.inc | 2 - po/POTFILES | 2 - - 8 files changed, 1 insertion(+), 255 deletions(-) + 8 files changed, 1 insertion(+), 254 deletions(-) delete mode 100644 daemon/9p.c diff --git a/Makefile.am b/Makefile.am -index 494892206..ffe002837 100644 +index cc363341f..8fb25a57c 100644 --- a/Makefile.am +++ b/Makefile.am -@@ -73,7 +73,7 @@ SUBDIRS += tests/xfs +@@ -78,7 +78,7 @@ SUBDIRS += tests/xfs SUBDIRS += tests/charsets SUBDIRS += tests/xml SUBDIRS += tests/mount-local @@ -30,10 +30,10 @@ index 494892206..ffe002837 100644 SUBDIRS += tests/disk-labels diff --git a/daemon/9p.c b/daemon/9p.c deleted file mode 100644 -index fc5b01736..000000000 +index 55644249d..000000000 --- a/daemon/9p.c +++ /dev/null -@@ -1,225 +0,0 @@ +@@ -1,224 +0,0 @@ -/* libguestfs - the guestfsd daemon - * Copyright (C) 2011 Red Hat Inc. - * @@ -69,7 +69,6 @@ index fc5b01736..000000000 -#include "actions.h" - -#define BUS_PATH "/sys/bus/virtio/drivers/9pnet_virtio" --GUESTFSD_EXT_CMD(str_mount, mount); - -static char *read_whole_file (const char *filename); - @@ -251,7 +250,7 @@ index fc5b01736..000000000 - } - - r = command (NULL, &err, -- str_mount, "-o", opts, "-t", "9p", mount_tag, mp, NULL); +- "mount", "-o", opts, "-t", "9p", mount_tag, mp, NULL); - if (r == -1) { - reply_with_error ("%s on %s: %s", mount_tag, mountpoint, err); - return -1; @@ -260,22 +259,22 @@ index fc5b01736..000000000 - return 0; -} diff --git a/daemon/Makefile.am b/daemon/Makefile.am -index 31414653f..7aeaf7b8d 100644 +index 6240f517d..29f3aa6df 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am -@@ -49,7 +49,6 @@ endif - guestfsd_SOURCES = \ - ../common/errnostring/errnostring.h \ +@@ -76,7 +76,6 @@ guestfsd_SOURCES = \ ../common/protocol/guestfs_protocol.h \ + ../common/utils/cleanups.h \ + ../common/utils/guestfs-utils.h \ - 9p.c \ acl.c \ actions.h \ available.c \ diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES -index f54015de0..d7fa51cf6 100644 +index f3ee61e0d..e8b1d5283 100644 --- a/docs/C_SOURCE_FILES +++ b/docs/C_SOURCE_FILES -@@ -49,7 +49,6 @@ common/windows/windows.h +@@ -70,7 +70,6 @@ common/windows/windows.h customize/crypt-c.c customize/dummy.c customize/perl_edit-c.c @@ -284,16 +283,16 @@ index f54015de0..d7fa51cf6 100644 daemon/actions.h daemon/augeas.c diff --git a/generator/actions_core.ml b/generator/actions_core.ml -index 5e487df02..dc54d616a 100644 +index 2ae3ec1d9..237edafce 100644 --- a/generator/actions_core.ml +++ b/generator/actions_core.ml -@@ -6371,27 +6371,6 @@ This returns true iff the device exists and contains all zero bytes. +@@ -6179,27 +6179,6 @@ This returns true iff the device exists and contains all zero bytes. Note that for large devices this can take a long time to run." }; - { defaults with - name = "list_9p"; added = (1, 11, 12); -- style = RStringList "mounttags", [], []; +- style = RStringList (RPlainString, "mounttags"), [], []; - shortdesc = "list 9p filesystems"; - longdesc = "\ -List all 9p filesystems attached to the guest. A list of @@ -301,7 +300,7 @@ index 5e487df02..dc54d616a 100644 - - { defaults with - name = "mount_9p"; added = (1, 11, 12); -- style = RErr, [String "mounttag"; String "mountpoint"], [OString "options"]; +- style = RErr, [String (PlainString, "mounttag"); String (PlainString, "mountpoint")], [OString "options"]; - camel_name = "Mount9P"; - shortdesc = "mount 9p filesystem"; - longdesc = "\ @@ -314,9 +313,9 @@ index 5e487df02..dc54d616a 100644 - { defaults with name = "list_dm_devices"; added = (1, 11, 15); - style = RStringList "devices", [], []; + style = RStringList (RDevice, "devices"), [], []; diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml -index b3be31996..7f92e0427 100644 +index 9e16ab14a..e6b018c62 100644 --- a/generator/proc_nr.ml +++ b/generator/proc_nr.ml @@ -295,8 +295,6 @@ let proc_nr = [ @@ -329,10 +328,10 @@ index b3be31996..7f92e0427 100644 288, "ntfsresize"; 289, "btrfs_filesystem_resize"; diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc -index 8fa8599d3..7a5272684 100644 +index 5aa2dcafe..b8f8e9226 100644 --- a/gobject/Makefile.inc +++ b/gobject/Makefile.inc -@@ -92,7 +92,6 @@ guestfs_gobject_headers= \ +@@ -93,7 +93,6 @@ guestfs_gobject_headers= \ include/guestfs-gobject/optargs-mksquashfs.h \ include/guestfs-gobject/optargs-mkswap.h \ include/guestfs-gobject/optargs-mktemp.h \ @@ -340,7 +339,7 @@ index 8fa8599d3..7a5272684 100644 include/guestfs-gobject/optargs-mount_local.h \ include/guestfs-gobject/optargs-ntfsclone_out.h \ include/guestfs-gobject/optargs-ntfsfix.h \ -@@ -184,7 +183,6 @@ guestfs_gobject_sources= \ +@@ -186,7 +185,6 @@ guestfs_gobject_sources= \ src/optargs-mksquashfs.c \ src/optargs-mkswap.c \ src/optargs-mktemp.c \ @@ -349,10 +348,10 @@ index 8fa8599d3..7a5272684 100644 src/optargs-ntfsclone_out.c \ src/optargs-ntfsfix.c \ diff --git a/po/POTFILES b/po/POTFILES -index 447b2a1e3..2856b36a3 100644 +index a049d66fe..5daec8a89 100644 --- a/po/POTFILES +++ b/po/POTFILES -@@ -39,7 +39,6 @@ customize/crypt-c.c +@@ -58,7 +58,6 @@ customize/crypt-c.c customize/dummy.c customize/perl_edit-c.c customize/test-password.pl @@ -360,7 +359,7 @@ index 447b2a1e3..2856b36a3 100644 daemon/acl.c daemon/augeas.c daemon/available.c -@@ -266,7 +265,6 @@ gobject/src/optargs-mkfs_btrfs.c +@@ -290,7 +289,6 @@ gobject/src/optargs-mkfs_btrfs.c gobject/src/optargs-mksquashfs.c gobject/src/optargs-mkswap.c gobject/src/optargs-mktemp.c @@ -369,5 +368,5 @@ index 447b2a1e3..2856b36a3 100644 gobject/src/optargs-ntfsclone_out.c gobject/src/optargs-ntfsfix.c -- -2.14.3 +2.17.1 diff --git a/SOURCES/0003-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch b/SOURCES/0003-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch index 43b43a8..000e9cc 100644 --- a/SOURCES/0003-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch +++ b/SOURCES/0003-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch @@ -1,4 +1,4 @@ -From 0b0b38041f963b36be1d2e38a7cd7743cece0722 Mon Sep 17 00:00:00 2001 +From a3b29ff1114ffe50a09e9505b377697999751a84 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 29 Jul 2013 14:47:56 +0100 Subject: [PATCH] RHEL 7: Disable unsupported remote drive protocols @@ -22,21 +22,21 @@ We hope to gradually add some of these back over the lifetime of RHEL 7. In RHEL 7.2: rbd (Ceph) support was enabled. --- - docs/guestfs-testing.pod | 20 ------- - fish/guestfish.pod | 66 ++-------------------- - fish/test-add-uri.sh | 32 ----------- - generator/actions_core.ml | 50 +---------------- - lib/drives.c | 8 +++ - lib/guestfs.pod | 100 --------------------------------- - tests/disks/test-qemu-drive-libvirt.sh | 28 --------- - tests/disks/test-qemu-drive.sh | 60 -------------------- + docs/guestfs-testing.pod | 20 ----- + fish/guestfish.pod | 66 ++-------------- + fish/test-add-uri.sh | 32 -------- + generator/actions_core.ml | 50 +------------ + lib/drives.c | 8 ++ + lib/guestfs.pod | 100 ------------------------- + tests/disks/test-qemu-drive-libvirt.sh | 28 ------- + tests/disks/test-qemu-drive.sh | 60 --------------- 8 files changed, 16 insertions(+), 348 deletions(-) diff --git a/docs/guestfs-testing.pod b/docs/guestfs-testing.pod -index 1e88ed4df..ce64755db 100644 +index f558964bf..8f264ed17 100644 --- a/docs/guestfs-testing.pod +++ b/docs/guestfs-testing.pod -@@ -113,26 +113,6 @@ image. To exit, type C. +@@ -109,26 +109,6 @@ image. To exit, type C. If you get an error, try enabling debugging (add C<-v> to the command line). Also make sure that L succeeds. @@ -64,7 +64,7 @@ index 1e88ed4df..ce64755db 100644 Run L on guests or disk images: diff --git a/fish/guestfish.pod b/fish/guestfish.pod -index feaae7f8c..a9fc8d2df 100644 +index bbf43aad5..f4762f929 100644 --- a/fish/guestfish.pod +++ b/fish/guestfish.pod @@ -131,9 +131,9 @@ To list what is available do: @@ -79,7 +79,7 @@ index feaae7f8c..a9fc8d2df 100644 =head2 Remote control -@@ -1120,12 +1120,12 @@ L>. +@@ -1127,12 +1127,12 @@ L>. On the command line, you can use the I<-a> option to add network block devices using a URI-style format, for example: @@ -94,7 +94,7 @@ index feaae7f8c..a9fc8d2df 100644 The possible I<-a URI> formats are described below. -@@ -1135,40 +1135,6 @@ The possible I<-a URI> formats are described below. +@@ -1142,40 +1142,6 @@ The possible I<-a URI> formats are described below. Add the local disk image (or device) called F. @@ -135,7 +135,7 @@ index feaae7f8c..a9fc8d2df 100644 =head2 B<-a nbd://example.com[:port]> =head2 B<-a nbd://example.com[:port]/exportname> -@@ -1203,35 +1169,13 @@ The equivalent API command would be: +@@ -1210,35 +1176,13 @@ The equivalent API command would be: > add pool/disk protocol:rbd server:tcp:example.com:port @@ -222,10 +222,10 @@ index 756df997b..8f84fd31b 100755 rm test-add-uri.out rm test-add-uri.img diff --git a/generator/actions_core.ml b/generator/actions_core.ml -index dc54d616a..ee2539c09 100644 +index 237edafce..aca5b1f43 100644 --- a/generator/actions_core.ml +++ b/generator/actions_core.ml -@@ -522,29 +522,6 @@ F is interpreted as a local file or device. +@@ -297,29 +297,6 @@ F is interpreted as a local file or device. This is the default if the optional protocol parameter is omitted. @@ -255,7 +255,7 @@ index dc54d616a..ee2539c09 100644 =item C Connect to the Network Block Device server. -@@ -561,22 +538,6 @@ The C parameter may be supplied. See below. +@@ -336,22 +313,6 @@ The C parameter may be supplied. See below. See also: L. @@ -278,7 +278,7 @@ index dc54d616a..ee2539c09 100644 =back =item C -@@ -587,13 +548,8 @@ is a list of server(s). +@@ -362,13 +323,8 @@ is a list of server(s). Protocol Number of servers required -------- -------------------------- file List must be empty or param not used at all @@ -292,7 +292,7 @@ index dc54d616a..ee2539c09 100644 Each list element is a string specifying a server. The string must be in one of the following formats: -@@ -609,10 +565,10 @@ for the protocol is used (see F). +@@ -384,10 +340,10 @@ for the protocol is used (see F). =item C @@ -307,7 +307,7 @@ index dc54d616a..ee2539c09 100644 example if using the libvirt backend and if the libvirt backend is configured to start the qemu appliance as a special user such as C. If in doubt, diff --git a/lib/drives.c b/lib/drives.c -index 509522430..d3887c148 100644 +index 82ef30093..ba5d07ed0 100644 --- a/lib/drives.c +++ b/lib/drives.c @@ -165,6 +165,7 @@ create_drive_non_file (guestfs_h *g, @@ -372,10 +372,10 @@ index 509522430..d3887c148 100644 } +#endif /* DISABLED IN RHEL 7 */ else { - error (g, _("unknown protocol '%s'"), protocol); + error (g, _("unknown protocol ‘%s’"), protocol); drv = NULL; /*FALLTHROUGH*/ diff --git a/lib/guestfs.pod b/lib/guestfs.pod -index e02cda6f8..41aa7ad83 100644 +index d5a0e81e7..684f8dc6c 100644 --- a/lib/guestfs.pod +++ b/lib/guestfs.pod @@ -714,70 +714,6 @@ servers. The server string is documented in @@ -493,7 +493,7 @@ index e02cda6f8..41aa7ad83 100644 Libguestfs has APIs for inspecting an unknown disk image to find out diff --git a/tests/disks/test-qemu-drive-libvirt.sh b/tests/disks/test-qemu-drive-libvirt.sh -index 3520e8a83..7671afb4a 100755 +index ab8052de1..ad22b2fbb 100755 --- a/tests/disks/test-qemu-drive-libvirt.sh +++ b/tests/disks/test-qemu-drive-libvirt.sh @@ -64,34 +64,6 @@ check_output @@ -607,5 +607,5 @@ index 19dd60a2f..583e031bd 100755 -grep -sq -- '-drive file=ssh://rich@example.com/disk.img,' "$DEBUG_QEMU_FILE" || fail -rm "$DEBUG_QEMU_FILE" -- -2.14.3 +2.17.1 diff --git a/SOURCES/0004-RHEL-7-Remove-User-Mode-Linux-RHBZ-1144197.patch b/SOURCES/0004-RHEL-7-Remove-User-Mode-Linux-RHBZ-1144197.patch index f16ac1b..4c07811 100644 --- a/SOURCES/0004-RHEL-7-Remove-User-Mode-Linux-RHBZ-1144197.patch +++ b/SOURCES/0004-RHEL-7-Remove-User-Mode-Linux-RHBZ-1144197.patch @@ -1,4 +1,4 @@ -From 30f46900825b5a48024220d651d12166e2d8fe92 Mon Sep 17 00:00:00 2001 +From adeeafce7f7ada1c8b98120745388d5a51b27ca3 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 19 Sep 2014 13:38:20 +0100 Subject: [PATCH] RHEL 7: Remove User-Mode Linux (RHBZ#1144197). @@ -9,7 +9,7 @@ This isn't supported in RHEL 7. 1 file changed, 13 insertions(+) diff --git a/lib/launch-uml.c b/lib/launch-uml.c -index 65745ff47..3b67f2598 100644 +index b8825cf56..1acf8db27 100644 --- a/lib/launch-uml.c +++ b/lib/launch-uml.c @@ -44,7 +44,9 @@ struct backend_uml_data { @@ -68,5 +68,5 @@ index 65745ff47..3b67f2598 100644 static int shutdown_uml (guestfs_h *g, void *datav, int check_for_errors) -- -2.14.3 +2.17.1 diff --git a/SOURCES/0005-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch b/SOURCES/0005-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch index a40ac53..e71f0bc 100644 --- a/SOURCES/0005-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch +++ b/SOURCES/0005-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch @@ -1,4 +1,4 @@ -From a16c5c28835dab579f7ff0c782bff4706f5efc28 Mon Sep 17 00:00:00 2001 +From 03d534fcb1d7ab336d9c7de6b791b42797c35aeb Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Sun, 28 Sep 2014 19:14:43 +0100 Subject: [PATCH] RHEL 7: v2v: Select correct qemu binary for -o qemu mode @@ -12,22 +12,22 @@ 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/qemu_command.ml | 2 +- + v2v/output_qemu.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/v2v/qemu_command.ml b/v2v/qemu_command.ml -index ccdda8ad4..19757e007 100644 ---- a/v2v/qemu_command.ml -+++ b/v2v/qemu_command.ml -@@ -32,7 +32,7 @@ and arg = - | Commas of string * string list +diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml +index 952660de2..72a4ec9b6 100644 +--- a/v2v/output_qemu.ml ++++ b/v2v/output_qemu.ml +@@ -71,7 +71,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 create ?(arch = "x86_64") () = -- { cmd = "qemu-system-" ^ arch; args = [] } -+ { cmd = "/usr/libexec/qemu-kvm"; args = [] } - - let flag t k = - assert (String.is_prefix k "-"); + let flag = Qemuopts.flag cmd + and arg = Qemuopts.arg cmd -- -2.14.3 +2.17.1 diff --git a/SOURCES/0006-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch b/SOURCES/0006-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch index 749237d..05c63e7 100644 --- a/SOURCES/0006-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch +++ b/SOURCES/0006-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch @@ -1,4 +1,4 @@ -From ba16c33451e806c58601eceec54e4c7048f398bc Mon Sep 17 00:00:00 2001 +From 49da490111d1d1ef839c914da2bce9a234d22dcf Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 30 Sep 2014 10:50:27 +0100 Subject: [PATCH] RHEL 7: v2v: Disable the --qemu-boot option (RHBZ#1147313). @@ -14,18 +14,18 @@ qemu script. 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml -index c7c7437ec..5a1ea04f3 100644 +index d88d0a579..d6f99fa00 100644 --- a/v2v/cmdline.ml +++ b/v2v/cmdline.ml -@@ -199,7 +199,6 @@ let parse_cmdline () = - [ L"password-file" ], Getopt.String ("file", set_string_option_once "--password-file" password_file), - s_"Use password from file"; - [ 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"vdsm-compat" ], Getopt.Symbol ("0.10|1.1", ["0.10"; "1.1"], set_vdsm_compat), s_"Write qcow2 with compat=0.10|1.1"; - [ L"vdsm-image-uuid" ], Getopt.String ("uuid", add_vdsm_image_uuid), s_"Output image UUID(s)"; -@@ -405,6 +404,8 @@ read the man page virt-v2v(1). +@@ -220,7 +220,6 @@ let parse_cmdline () = + s_"Use password from file"; + [ 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_string_option_once "--vddk-config" vddk_config), +@@ -507,6 +506,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 @@ -35,10 +35,10 @@ index c7c7437ec..5a1ea04f3 100644 output_format, output_alloc diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 5d4ed9ae5..ff91e29b8 100644 +index 484e14747..1c06502ec 100644 --- a/v2v/virt-v2v.pod +++ b/v2v/virt-v2v.pod -@@ -145,11 +145,6 @@ Since F contains the path(s) to the guest disk +@@ -114,11 +114,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. @@ -47,10 +47,10 @@ index 5d4ed9ae5..ff91e29b8 100644 - - virt-v2v -i disk disk.img -o qemu -os /var/tmp --qemu-boot - - =head1 SUPPORT MATRIX + =head1 INPUT AND OUTPUT MODES - =head2 Hypervisors (Input) -@@ -466,9 +461,6 @@ This is similar to I<-o local>, except that a shell script is written + ┌────────────┐ ┌─────────▶ -o null +@@ -517,9 +512,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>. @@ -60,7 +60,7 @@ index 5d4ed9ae5..ff91e29b8 100644 =item B<-o> B This is the same as I<-o rhv>. -@@ -558,11 +550,6 @@ Print information about the source guest and stop. This option is +@@ -609,11 +601,6 @@ Print information about the source guest and stop. This option is useful when you are setting up network and bridge maps. See L. @@ -73,5 +73,5 @@ index 5d4ed9ae5..ff91e29b8 100644 =item B<--quiet> -- -2.14.3 +2.17.1 diff --git a/SOURCES/0007-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch b/SOURCES/0007-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch deleted file mode 100644 index fb75f80..0000000 --- a/SOURCES/0007-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 4706dff15716286461c0826da9f703dc1b49177d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 2 Oct 2014 16:44:00 +0100 -Subject: [PATCH] RHEL 7: Revert "tests: rsync: Skip this test when the backend - is libvirt." - -This reverts commit 765dc6237ce7b93dd2f33d99be53eae92e048a7a. ---- - tests/rsync/test-rsync.sh | 35 +++++++---------------------------- - 1 file changed, 7 insertions(+), 28 deletions(-) - -diff --git a/tests/rsync/test-rsync.sh b/tests/rsync/test-rsync.sh -index c6d98cfd1..246396276 100755 ---- a/tests/rsync/test-rsync.sh -+++ b/tests/rsync/test-rsync.sh -@@ -26,33 +26,10 @@ skip_if_skipped - skip_unless rsync --help - skip_unless_feature_available rsync - --# Get host IP address. XXX Bit of a hack. --backend="$(guestfish get-backend)" --case "$backend" in -- direct) -- ip=169.254.2.2 -- listen_address=localhost -- ;; -- libvirt|libvirt:*) -- # This would work, except that the host firewall is effective -- # on virbr0, and that is likely to block the non-standard port -- # number that we listen on. --# ip="$(ip -4 -o address show virbr0 | --# awk '{print $4}' | --# awk -F/ '{print $1}')" --# listen_address="$ip" -- echo "$0: skipping test because host firewall will probably prevent this test from working" -- exit 77 -- ;; -- uml) -- echo "$0: skipping test because networking is not available in the UML backend" -- exit 77 -- ;; -- *) -- echo "$0: don't know how to get IP address of backend $backend" -- exit 77 -- ;; --esac -+if [ "$(guestfish get-backend)" = "uml" ]; then -+ echo "$0: skipping test because networking is not available in the UML backend" -+ exit 77 -+fi - - pwd="$(pwd)" - datadir="$(cd ../../test-data/files && pwd)" -@@ -66,7 +43,7 @@ port="$(awk 'BEGIN{srand(); print 65000+int(500*rand())}' rsyncd.conf < +Date: Fri, 2 Mar 2018 16:22:35 +0100 +Subject: [PATCH] RHEL 7: move VIRTIO_DEVICE_NAME() macro to guestfs-internal.h + +This way it can be used also in other places than launch-direct.c. +--- + lib/guestfs-internal.h | 11 +++++++++++ + lib/launch-direct.c | 11 ----------- + 2 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h +index adeb9478a..8e4e30a20 100644 +--- a/lib/guestfs-internal.h ++++ b/lib/guestfs-internal.h +@@ -136,6 +136,17 @@ + /* Maximum size of Windows explorer.exe. 2.6MB on Windows 7. */ + #define MAX_WINDOWS_EXPLORER_SIZE (4 * 1000 * 1000) + ++/* Differences in qemu device names on ARMv7 (virtio-mmio), s/390x ++ * (CCW) vs normal hardware with PCI. ++ */ ++#if defined(__arm__) ++#define VIRTIO_DEVICE_NAME(type) type "-device" ++#elif defined(__s390x__) ++#define VIRTIO_DEVICE_NAME(type) type "-ccw" ++#else ++#define VIRTIO_DEVICE_NAME(type) type "-pci" ++#endif ++ + /* Machine types. */ + #ifdef __arm__ + #define MACHINE_TYPE "virt" +diff --git a/lib/launch-direct.c b/lib/launch-direct.c +index 47e8f37de..f6c494d69 100644 +--- a/lib/launch-direct.c ++++ b/lib/launch-direct.c +@@ -49,17 +49,6 @@ + #include "guestfs_protocol.h" + #include "qemuopts.h" + +-/* Differences in qemu device names on ARMv7 (virtio-mmio), s/390x +- * (CCW) vs normal hardware with PCI. +- */ +-#if defined(__arm__) +-#define VIRTIO_DEVICE_NAME(type) type "-device" +-#elif defined(__s390x__) +-#define VIRTIO_DEVICE_NAME(type) type "-ccw" +-#else +-#define VIRTIO_DEVICE_NAME(type) type "-pci" +-#endif +- + /* Per-handle data. */ + struct backend_direct_data { + pid_t pid; /* Qemu PID. */ +-- +2.17.1 + diff --git a/SOURCES/0008-RHEL-7-Revert-appliance-Change-example-ping-lines-to.patch b/SOURCES/0008-RHEL-7-Revert-appliance-Change-example-ping-lines-to.patch deleted file mode 100644 index 1f25364..0000000 --- a/SOURCES/0008-RHEL-7-Revert-appliance-Change-example-ping-lines-to.patch +++ /dev/null @@ -1,28 +0,0 @@ -From a46f806126a9ab8240194f3637665365fea278b2 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 2 Oct 2014 16:44:04 +0100 -Subject: [PATCH] RHEL 7: Revert "appliance: Change example ping lines to ping - 8.8.8.8." - -This reverts commit 07c0926b588db5c86214917b609c2f477c817c0e. ---- - appliance/init | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/appliance/init b/appliance/init -index 59b5c4955..c6a269dd1 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -157,7 +157,8 @@ if test "$guestfs_verbose" = 1 && test "$guestfs_boot_analysis" != 1; then - date - echo -n "clocksource: " - cat /sys/devices/system/clocksource/clocksource0/current_clocksource -- #ping -n -v -c 5 8.8.8.8 -+ #ping -n -v -c 5 10.0.2.2 -+ #ping -n -v -c 5 10.0.2.4 - - echo -n "uptime: "; cat /proc/uptime - fi --- -2.14.3 - diff --git a/SOURCES/0008-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch b/SOURCES/0008-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch new file mode 100644 index 0000000..2644c91 --- /dev/null +++ b/SOURCES/0008-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch @@ -0,0 +1,74 @@ +From 2f258581f9c706c5c92d0986e7bae8583ce145dd Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 2 Oct 2014 16:44:00 +0100 +Subject: [PATCH] RHEL 7: Revert "tests: rsync: Skip this test when the backend + is libvirt." + +This reverts commit 765dc6237ce7b93dd2f33d99be53eae92e048a7a. +--- + tests/rsync/test-rsync.sh | 35 +++++++---------------------------- + 1 file changed, 7 insertions(+), 28 deletions(-) + +diff --git a/tests/rsync/test-rsync.sh b/tests/rsync/test-rsync.sh +index c6d98cfd1..246396276 100755 +--- a/tests/rsync/test-rsync.sh ++++ b/tests/rsync/test-rsync.sh +@@ -26,33 +26,10 @@ skip_if_skipped + skip_unless rsync --help + skip_unless_feature_available rsync + +-# Get host IP address. XXX Bit of a hack. +-backend="$(guestfish get-backend)" +-case "$backend" in +- direct) +- ip=169.254.2.2 +- listen_address=localhost +- ;; +- libvirt|libvirt:*) +- # This would work, except that the host firewall is effective +- # on virbr0, and that is likely to block the non-standard port +- # number that we listen on. +-# ip="$(ip -4 -o address show virbr0 | +-# awk '{print $4}' | +-# awk -F/ '{print $1}')" +-# listen_address="$ip" +- echo "$0: skipping test because host firewall will probably prevent this test from working" +- exit 77 +- ;; +- uml) +- echo "$0: skipping test because networking is not available in the UML backend" +- exit 77 +- ;; +- *) +- echo "$0: don't know how to get IP address of backend $backend" +- exit 77 +- ;; +-esac ++if [ "$(guestfish get-backend)" = "uml" ]; then ++ echo "$0: skipping test because networking is not available in the UML backend" ++ exit 77 ++fi + + pwd="$(pwd)" + datadir="$(cd ../../test-data/files && pwd)" +@@ -66,7 +43,7 @@ port="$(awk 'BEGIN{srand(); print 65000+int(500*rand())}' rsyncd.conf < +Date: Thu, 2 Oct 2014 16:44:04 +0100 +Subject: [PATCH] RHEL 7: Revert "appliance: Change example ping lines to ping + 8.8.8.8." + +This reverts commit 07c0926b588db5c86214917b609c2f477c817c0e. +--- + appliance/init | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/appliance/init b/appliance/init +index 6a61a8d6e..f530ad3d5 100755 +--- a/appliance/init ++++ b/appliance/init +@@ -160,7 +160,8 @@ if test "$guestfs_verbose" = 1 && test "$guestfs_boot_analysis" != 1; then + date + echo -n "clocksource: " + cat /sys/devices/system/clocksource/clocksource0/current_clocksource +- #ping -n -v -c 5 8.8.8.8 ++ #ping -n -v -c 5 10.0.2.2 ++ #ping -n -v -c 5 10.0.2.4 + + echo -n "uptime: "; cat /proc/uptime + fi +-- +2.17.1 + diff --git a/SOURCES/0009-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch b/SOURCES/0009-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch deleted file mode 100644 index 4ab9832..0000000 --- a/SOURCES/0009-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 5a411a67cf166eb44b8f88858eabaa80d6a0d504 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 2 Oct 2014 16:44:07 +0100 -Subject: [PATCH] RHEL 7: Revert "launch: libvirt: Use qemu-bridge-helper to - implement a full network (RHBZ#1148012)." - -This reverts commit 224de20b9a8d5ea56f6337f19b4ca237bb88eca0. ---- - lib/guestfs.pod | 10 ---------- - lib/launch-libvirt.c | 44 +++++++++++++++++++++----------------------- - 2 files changed, 21 insertions(+), 33 deletions(-) - -diff --git a/lib/guestfs.pod b/lib/guestfs.pod -index 41aa7ad83..6443e3bae 100644 ---- a/lib/guestfs.pod -+++ b/lib/guestfs.pod -@@ -1441,16 +1441,6 @@ On Fedora, install C for the C file - (containing symbols). Make sure the symbols precisely match the - kernel being used. - --=head3 network_bridge -- --The libvirt backend supports: -- -- export LIBGUESTFS_BACKEND_SETTINGS=network_bridge=virbrX -- --This allows you to override the bridge that is connected to when the --network is enabled. The default is C. See also --L. -- - =head2 ATTACHING TO RUNNING DAEMONS - - I This is B and has a tendency to eat -diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c -index 4ddf9b87f..def9cfe07 100644 ---- a/lib/launch-libvirt.c -+++ b/lib/launch-libvirt.c -@@ -115,7 +115,6 @@ struct backend_libvirt_data { - char *selinux_label; - char *selinux_imagelabel; - bool selinux_norelabel_disks; -- char *network_bridge; - char name[DOMAIN_NAME_LEN]; /* random name */ - bool is_kvm; /* false = qemu, true = kvm (from capabilities)*/ - struct version libvirt_version; /* libvirt version */ -@@ -435,12 +434,6 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) - guestfs_get_backend_setting (g, "internal_libvirt_imagelabel"); - data->selinux_norelabel_disks = - guestfs_int_get_backend_setting_bool (g, "internal_libvirt_norelabel_disks"); -- if (g->enable_network) { -- data->network_bridge = -- guestfs_get_backend_setting (g, "network_bridge"); -- if (!data->network_bridge) -- data->network_bridge = safe_strdup (g, "virbr0"); -- } - guestfs_pop_error_handler (g); - - if (g->enable_network && check_bridge_exists (g, data->network_bridge) == -1) -@@ -1383,19 +1376,6 @@ construct_libvirt_xml_devices (guestfs_h *g, - } end_element (); - } end_element (); - -- /* Connect to libvirt bridge (see: RHBZ#1148012). */ -- if (g->enable_network) { -- start_element ("interface") { -- attribute ("type", "bridge"); -- start_element ("source") { -- attribute ("bridge", params->data->network_bridge); -- } end_element (); -- start_element ("model") { -- attribute ("type", "virtio"); -- } end_element (); -- } end_element (); -- } -- - /* Libvirt adds some devices by default. Indicate to libvirt - * that we don't want them. - */ -@@ -1793,6 +1773,27 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g, - attribute ("value", tmpdir); - } end_element (); - -+ /* Workaround because libvirt user networking cannot specify "net=" -+ * parameter. -+ */ -+ if (g->enable_network) { -+ start_element ("qemu:arg") { -+ attribute ("value", "-netdev"); -+ } end_element (); -+ -+ start_element ("qemu:arg") { -+ attribute ("value", "user,id=usernet,net=169.254.0.0/16"); -+ } end_element (); -+ -+ start_element ("qemu:arg") { -+ attribute ("value", "-device"); -+ } end_element (); -+ -+ start_element ("qemu:arg") { -+ attribute ("value", VIRTIO_NET ",netdev=usernet"); -+ } end_element (); -+ } -+ - /* The qemu command line arguments requested by the caller. */ - for (hp = g->hv_params; hp; hp = hp->next) { - start_element ("qemu:arg") { -@@ -2118,9 +2119,6 @@ shutdown_libvirt (guestfs_h *g, void *datav, int check_for_errors) - free (data->selinux_imagelabel); - data->selinux_imagelabel = NULL; - -- free (data->network_bridge); -- data->network_bridge = NULL; -- - for (i = 0; i < data->nr_secrets; ++i) - free (data->secrets[i].secret); - free (data->secrets); --- -2.14.3 - diff --git a/SOURCES/0010-RHEL-7-Revert-launch-libvirt-Better-error-when-bridg.patch b/SOURCES/0010-RHEL-7-Revert-launch-libvirt-Better-error-when-bridg.patch deleted file mode 100644 index 85929df..0000000 --- a/SOURCES/0010-RHEL-7-Revert-launch-libvirt-Better-error-when-bridg.patch +++ /dev/null @@ -1,86 +0,0 @@ -From f725f168ec3019da2332e5cae91a518a7897f8ff Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 21 Sep 2015 12:38:50 -0400 -Subject: [PATCH] RHEL 7: Revert "launch: libvirt: Better error when bridge / - virbr0 doesn't exist (RHBZ#1262127)." - -This reverts commit edcd02a965ae6675c0ee9ecd8d98a1a641c6ef60. ---- - lib/launch-libvirt.c | 47 ----------------------------------------------- - 1 file changed, 47 deletions(-) - -diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c -index def9cfe07..681281b9b 100644 ---- a/lib/launch-libvirt.c -+++ b/lib/launch-libvirt.c -@@ -155,7 +155,6 @@ static int is_blk (const char *path); - static void ignore_errors (void *ignore, virErrorPtr ignore2); - static void set_socket_create_context (guestfs_h *g); - static void clear_socket_create_context (guestfs_h *g); --static int check_bridge_exists (guestfs_h *g, const char *brname); - - #if HAVE_LIBSELINUX - static void selinux_warning (guestfs_h *g, const char *func, const char *selinux_op, const char *data); -@@ -436,9 +435,6 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) - guestfs_int_get_backend_setting_bool (g, "internal_libvirt_norelabel_disks"); - guestfs_pop_error_handler (g); - -- if (g->enable_network && check_bridge_exists (g, data->network_bridge) == -1) -- goto cleanup; -- - /* Locate and/or build the appliance. */ - TRACE0 (launch_build_libvirt_appliance_start); - -@@ -2031,49 +2027,6 @@ is_blk (const char *path) - return S_ISBLK (statbuf.st_mode); - } - --static int --is_dir (const char *path) --{ -- struct stat statbuf; -- -- if (stat (path, &statbuf) == -1) -- return 0; -- return S_ISDIR (statbuf.st_mode); --} -- --/* Used to check the network_bridge exists, or give a useful error -- * message. -- */ --static int --check_bridge_exists (guestfs_h *g, const char *brname) --{ -- CLEANUP_FREE char *path = NULL; -- -- /* If this doesn't look like Linux, give up. */ -- if (!is_dir ("/sys/class/net")) -- return 0; -- -- /* Does the interface exist and is it a bridge? */ -- path = safe_asprintf (g, "/sys/class/net/%s/bridge", brname); -- if (is_dir (path)) -- return 0; -- -- error (g, -- _("bridge '%s' not found. Try running:\n" -- "\n" -- " brctl show\n" -- "\n" -- "to get a list of bridges on the host, and then selecting the\n" -- "bridge you wish the appliance network to connect to using:\n" -- "\n" -- " export LIBGUESTFS_BACKEND_SETTINGS=network_bridge=\n" -- "\n" -- "You may also need to allow the bridge in /etc/qemu/bridge.conf.\n" -- "For further information see guestfs(3)."), -- brname); -- return -1; --} -- - static void - ignore_errors (void *ignore, virErrorPtr ignore2) - { --- -2.14.3 - diff --git a/SOURCES/0010-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch b/SOURCES/0010-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch new file mode 100644 index 0000000..25e57cc --- /dev/null +++ b/SOURCES/0010-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch @@ -0,0 +1,119 @@ +From af775f107327930e5d81bd63b5c682bb6925ba21 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 2 Oct 2014 16:44:07 +0100 +Subject: [PATCH] RHEL 7: Revert "launch: libvirt: Use qemu-bridge-helper to + implement a full network (RHBZ#1148012)." + +This reverts commit 224de20b9a8d5ea56f6337f19b4ca237bb88eca0. +--- + lib/guestfs.pod | 10 ---------- + lib/launch-libvirt.c | 44 +++++++++++++++++++++----------------------- + 2 files changed, 21 insertions(+), 33 deletions(-) + +diff --git a/lib/guestfs.pod b/lib/guestfs.pod +index 684f8dc6c..0b8c9f7d2 100644 +--- a/lib/guestfs.pod ++++ b/lib/guestfs.pod +@@ -1451,16 +1451,6 @@ On Fedora, install C for the C file + (containing symbols). Make sure the symbols precisely match the + kernel being used. + +-=head3 network_bridge +- +-The libvirt backend supports: +- +- export LIBGUESTFS_BACKEND_SETTINGS=network_bridge=virbrX +- +-This allows you to override the bridge that is connected to when the +-network is enabled. The default is C. See also +-L. +- + =head2 ATTACHING TO RUNNING DAEMONS + + I This is B and has a tendency to eat +diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c +index 844023b80..f0f52fba0 100644 +--- a/lib/launch-libvirt.c ++++ b/lib/launch-libvirt.c +@@ -115,7 +115,6 @@ struct backend_libvirt_data { + char *selinux_label; + char *selinux_imagelabel; + bool selinux_norelabel_disks; +- char *network_bridge; + char name[DOMAIN_NAME_LEN]; /* random name */ + bool is_kvm; /* false = qemu, true = kvm (from capabilities)*/ + struct version libvirt_version; /* libvirt version */ +@@ -437,12 +436,6 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) + guestfs_get_backend_setting (g, "internal_libvirt_imagelabel"); + data->selinux_norelabel_disks = + guestfs_int_get_backend_setting_bool (g, "internal_libvirt_norelabel_disks"); +- if (g->enable_network) { +- data->network_bridge = +- guestfs_get_backend_setting (g, "network_bridge"); +- if (!data->network_bridge) +- data->network_bridge = safe_strdup (g, "virbr0"); +- } + guestfs_pop_error_handler (g); + + if (g->enable_network && check_bridge_exists (g, data->network_bridge) == -1) +@@ -1402,19 +1395,6 @@ construct_libvirt_xml_devices (guestfs_h *g, + } end_element (); + } end_element (); + +- /* Connect to libvirt bridge (see: RHBZ#1148012). */ +- if (g->enable_network) { +- start_element ("interface") { +- attribute ("type", "bridge"); +- start_element ("source") { +- attribute ("bridge", params->data->network_bridge); +- } end_element (); +- start_element ("model") { +- attribute ("type", "virtio"); +- } end_element (); +- } end_element (); +- } +- + /* Libvirt adds some devices by default. Indicate to libvirt + * that we don't want them. + */ +@@ -1810,6 +1790,27 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g, + attribute ("value", tmpdir); + } end_element (); + ++ /* Workaround because libvirt user networking cannot specify "net=" ++ * parameter. ++ */ ++ if (g->enable_network) { ++ start_element ("qemu:arg") { ++ attribute ("value", "-netdev"); ++ } end_element (); ++ ++ start_element ("qemu:arg") { ++ attribute ("value", "user,id=usernet,net=169.254.0.0/16"); ++ } end_element (); ++ ++ start_element ("qemu:arg") { ++ attribute ("value", "-device"); ++ } end_element (); ++ ++ start_element ("qemu:arg") { ++ attribute ("value", VIRTIO_DEVICE_NAME ("virtio-net") ",netdev=usernet"); ++ } end_element (); ++ } ++ + /* The qemu command line arguments requested by the caller. */ + for (hp = g->hv_params; hp; hp = hp->next) { + start_element ("qemu:arg") { +@@ -2135,9 +2136,6 @@ shutdown_libvirt (guestfs_h *g, void *datav, int check_for_errors) + free (data->selinux_imagelabel); + data->selinux_imagelabel = NULL; + +- free (data->network_bridge); +- data->network_bridge = NULL; +- + for (i = 0; i < data->nr_secrets; ++i) + free (data->secrets[i].secret); + free (data->secrets); +-- +2.17.1 + diff --git a/SOURCES/0011-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch b/SOURCES/0011-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch deleted file mode 100644 index 105081b..0000000 --- a/SOURCES/0011-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 88dc95888f15c353581d0e9779d654935d9e820b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 10 Oct 2014 17:45:39 +0100 -Subject: [PATCH] RHEL 7: Revert "appliance: add dhcp-client on Mageia" - -This reverts commit 8f3a2ca5358d5601be7a9247b6d08193c4e2da46. ---- - appliance/packagelist.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/appliance/packagelist.in b/appliance/packagelist.in -index a2f6107b8..8a71f6e98 100644 ---- a/appliance/packagelist.in -+++ b/appliance/packagelist.in -@@ -189,7 +189,7 @@ ifelse(MAGEIA,1, - chkconfig /* for /etc/init.d */ - cdrkit-genisoimage - cdrkit-isotools -- dhcp-client -+ dhclient - extlinux - gfs2-utils - grub --- -2.14.3 - diff --git a/SOURCES/0011-RHEL-7-Revert-launch-libvirt-Better-error-when-bridg.patch b/SOURCES/0011-RHEL-7-Revert-launch-libvirt-Better-error-when-bridg.patch new file mode 100644 index 0000000..5beeedc --- /dev/null +++ b/SOURCES/0011-RHEL-7-Revert-launch-libvirt-Better-error-when-bridg.patch @@ -0,0 +1,86 @@ +From cdc0aab726f8fc9145c264fb7277f622ae8b7956 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 21 Sep 2015 12:38:50 -0400 +Subject: [PATCH] RHEL 7: Revert "launch: libvirt: Better error when bridge / + virbr0 doesn't exist (RHBZ#1262127)." + +This reverts commit edcd02a965ae6675c0ee9ecd8d98a1a641c6ef60. +--- + lib/launch-libvirt.c | 47 -------------------------------------------- + 1 file changed, 47 deletions(-) + +diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c +index f0f52fba0..c709c4fe2 100644 +--- a/lib/launch-libvirt.c ++++ b/lib/launch-libvirt.c +@@ -155,7 +155,6 @@ static int is_blk (const char *path); + static void ignore_errors (void *ignore, virErrorPtr ignore2); + static void set_socket_create_context (guestfs_h *g); + static void clear_socket_create_context (guestfs_h *g); +-static int check_bridge_exists (guestfs_h *g, const char *brname); + + #if HAVE_LIBSELINUX + static void selinux_warning (guestfs_h *g, const char *func, const char *selinux_op, const char *data); +@@ -438,9 +437,6 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri) + guestfs_int_get_backend_setting_bool (g, "internal_libvirt_norelabel_disks"); + guestfs_pop_error_handler (g); + +- if (g->enable_network && check_bridge_exists (g, data->network_bridge) == -1) +- goto cleanup; +- + /* Locate and/or build the appliance. */ + TRACE0 (launch_build_libvirt_appliance_start); + +@@ -2048,49 +2044,6 @@ is_blk (const char *path) + return S_ISBLK (statbuf.st_mode); + } + +-static int +-is_dir (const char *path) +-{ +- struct stat statbuf; +- +- if (stat (path, &statbuf) == -1) +- return 0; +- return S_ISDIR (statbuf.st_mode); +-} +- +-/* Used to check the network_bridge exists, or give a useful error +- * message. +- */ +-static int +-check_bridge_exists (guestfs_h *g, const char *brname) +-{ +- CLEANUP_FREE char *path = NULL; +- +- /* If this doesn't look like Linux, give up. */ +- if (!is_dir ("/sys/class/net")) +- return 0; +- +- /* Does the interface exist and is it a bridge? */ +- path = safe_asprintf (g, "/sys/class/net/%s/bridge", brname); +- if (is_dir (path)) +- return 0; +- +- error (g, +- _("bridge ‘%s’ not found. Try running:\n" +- "\n" +- " brctl show\n" +- "\n" +- "to get a list of bridges on the host, and then selecting the\n" +- "bridge you wish the appliance network to connect to using:\n" +- "\n" +- " export LIBGUESTFS_BACKEND_SETTINGS=network_bridge=\n" +- "\n" +- "You may also need to allow the bridge in /etc/qemu/bridge.conf.\n" +- "For further information see guestfs(3)."), +- brname); +- return -1; +-} +- + static void + ignore_errors (void *ignore, virErrorPtr ignore2) + { +-- +2.17.1 + diff --git a/SOURCES/0012-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch b/SOURCES/0012-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch new file mode 100644 index 0000000..60cae8a --- /dev/null +++ b/SOURCES/0012-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch @@ -0,0 +1,26 @@ +From cfa7f9277cfafb5e461c03c2734c08d97b4a5d06 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 10 Oct 2014 17:45:39 +0100 +Subject: [PATCH] RHEL 7: Revert "appliance: add dhcp-client on Mageia" + +This reverts commit 8f3a2ca5358d5601be7a9247b6d08193c4e2da46. +--- + appliance/packagelist.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/appliance/packagelist.in b/appliance/packagelist.in +index 8ded2588a..d70451309 100644 +--- a/appliance/packagelist.in ++++ b/appliance/packagelist.in +@@ -200,7 +200,7 @@ ifelse(MAGEIA,1, + chkconfig /* for /etc/init.d */ + cdrkit-genisoimage + cdrkit-isotools +- dhcp-client ++ dhclient + extlinux + gfs2-utils + grub +-- +2.17.1 + diff --git a/SOURCES/0012-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch b/SOURCES/0012-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch deleted file mode 100644 index 50f5a2c..0000000 --- a/SOURCES/0012-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch +++ /dev/null @@ -1,28 +0,0 @@ -From b7640b6a60366d615f2b7bd24ed923a3c6c2eddb Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 10 Oct 2014 17:45:48 +0100 -Subject: [PATCH] RHEL 7: Revert "appliance: add dhcpcd and gptfdisk on - Archlinux" - -This reverts commit 979e7a49147f4ef1387337db262bf7ea12f627e3. ---- - appliance/packagelist.in | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/appliance/packagelist.in b/appliance/packagelist.in -index 8a71f6e98..e088ace30 100644 ---- a/appliance/packagelist.in -+++ b/appliance/packagelist.in -@@ -105,8 +105,7 @@ ifelse(ARCHLINUX,1, - cdrkit - cdrtools - cryptsetup -- dhcpcd -- gptfdisk -+ dhclient - grub - hivex - iproute2 --- -2.14.3 - diff --git a/SOURCES/0013-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch b/SOURCES/0013-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch deleted file mode 100644 index 5e69636..0000000 --- a/SOURCES/0013-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 169f16907f701d7d6eaf157eff0141bdf3632760 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 10 Oct 2014 17:46:02 +0100 -Subject: [PATCH] RHEL 7: Revert "appliance: Use dhclient or dhcpcd instead of - hard-coding IP address of appliance." - -This reverts commit 67e6f32a240c7c234e6af637c1cd324b36a82cd3. ---- - appliance/init | 15 ++++++--------- - appliance/packagelist.in | 7 ------- - 2 files changed, 6 insertions(+), 16 deletions(-) - -diff --git a/appliance/init b/appliance/init -index c6a269dd1..2c9aecd5f 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -120,15 +120,12 @@ shopt -u nullglob - ip addr add 127.0.0.1/8 brd + dev lo scope host - ip link set dev lo up - --if test "$guestfs_network" = 1; then -- iface=$(ls -I all -I default -I lo /proc/sys/net/ipv4/conf) -- touch /etc/fstab # Workaround for Ubuntu. -- if dhclient --version >/dev/null 2>&1; then -- dhclient $iface -- else -- dhcpcd $iface -- fi --fi -+ip addr add 169.254.2.10/16 brd + dev eth0 scope global -+ip link set dev eth0 up -+ -+ip route add default via 169.254.2.2 -+ -+echo nameserver 169.254.2.3 > /etc/resolv.conf - - # Scan for MDs. - mdadm -As --auto=yes --run -diff --git a/appliance/packagelist.in b/appliance/packagelist.in -index e088ace30..8019af158 100644 ---- a/appliance/packagelist.in -+++ b/appliance/packagelist.in -@@ -26,7 +26,6 @@ ifelse(REDHAT,1, - augeas-libs - cryptsetup - cryptsetup-luks dnl old name used before Fedora 17 -- dhclient - genisoimage - gfs-utils - gfs2-utils -@@ -73,7 +72,6 @@ dnl iproute has been renamed to iproute2 - iputils-ping - iputils-arping - iputils-tracepath -- isc-dhcp-client - ldmtool - libaugeas0 - libc-bin -@@ -105,7 +103,6 @@ ifelse(ARCHLINUX,1, - cdrkit - cdrtools - cryptsetup -- dhclient - grub - hivex - iproute2 -@@ -134,8 +131,6 @@ ifelse(SUSE,1, - btrfsprogs - cdrkit-cdrtools-compat - cryptsetup -- dhcpcd -- dhcp-client - genisoimage - glibc-locale - gptfdisk -@@ -161,7 +156,6 @@ ifelse(FRUGALWARE,1, - augeas - cryptsetup-luks - cdrkit -- dhclient - grub2 - hfsplus - iproute2 -@@ -188,7 +182,6 @@ ifelse(MAGEIA,1, - chkconfig /* for /etc/init.d */ - cdrkit-genisoimage - cdrkit-isotools -- dhclient - extlinux - gfs2-utils - grub --- -2.14.3 - diff --git a/SOURCES/0013-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch b/SOURCES/0013-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch new file mode 100644 index 0000000..db59217 --- /dev/null +++ b/SOURCES/0013-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch @@ -0,0 +1,28 @@ +From 612d0ee8454f6fb51779b3cc96e6414605f2c112 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 10 Oct 2014 17:45:48 +0100 +Subject: [PATCH] RHEL 7: Revert "appliance: add dhcpcd and gptfdisk on + Archlinux" + +This reverts commit 979e7a49147f4ef1387337db262bf7ea12f627e3. +--- + appliance/packagelist.in | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/appliance/packagelist.in b/appliance/packagelist.in +index d70451309..81a8f0dba 100644 +--- a/appliance/packagelist.in ++++ b/appliance/packagelist.in +@@ -110,8 +110,7 @@ ifelse(ARCHLINUX,1, + cdrkit + cdrtools + cryptsetup +- dhcpcd +- gptfdisk ++ dhclient + grub + hivex + iproute2 +-- +2.17.1 + diff --git a/SOURCES/0014-RHEL-7-Disable-alternate-Augeas-lenses.patch b/SOURCES/0014-RHEL-7-Disable-alternate-Augeas-lenses.patch deleted file mode 100644 index be866fb..0000000 --- a/SOURCES/0014-RHEL-7-Disable-alternate-Augeas-lenses.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 060fa25dd5046c3b6cea8c0d2c55ac9607042e9c Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Fri, 24 Oct 2014 16:33:50 +0100 -Subject: [PATCH] RHEL 7: Disable alternate Augeas lenses. - -These are included in the RHEL 7.1 augeas package, and therefore -not required in RHEL. - -See: -https://www.redhat.com/archives/libguestfs/2014-October/msg00220.html ---- - appliance/Makefile.am | 1 - - daemon/augeas.c | 5 ++++- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/appliance/Makefile.am b/appliance/Makefile.am -index 42896b9a7..6cc147a18 100644 ---- a/appliance/Makefile.am -+++ b/appliance/Makefile.am -@@ -91,7 +91,6 @@ supermin.d/daemon.tar.gz: ../daemon/guestfsd guestfs_shadow.aug - rm -rf tmp-d - mkdir -p tmp-d$(DAEMON_SUPERMIN_DIR) tmp-d/etc tmp-d/usr/share/guestfs - ln ../daemon/guestfsd tmp-d$(DAEMON_SUPERMIN_DIR)/guestfsd -- ln $(srcdir)/guestfs_shadow.aug tmp-d/usr/share/guestfs/guestfs_shadow.aug - ( cd tmp-d && tar zcf - * ) > $@-t - rm -r tmp-d - mv $@-t $@ -diff --git a/daemon/augeas.c b/daemon/augeas.c -index 5adc959a5..dc5266ee4 100644 ---- a/daemon/augeas.c -+++ b/daemon/augeas.c -@@ -134,7 +134,7 @@ do_aug_init (const char *root, int flags) - } - - /* Pass AUG_NO_ERR_CLOSE so we can display detailed errors. */ -- aug = aug_init (buf, "/usr/share/guestfs/", flags | AUG_NO_ERR_CLOSE); -+ aug = aug_init (buf, NULL, flags | AUG_NO_ERR_CLOSE); - - if (!aug) { - reply_with_error ("augeas initialization failed"); -@@ -148,6 +148,8 @@ do_aug_init (const char *root, int flags) - return -1; - } - -+ /* We already have the needed lenses in RHEL 7 */ -+#if 0 - if (!augeas_is_version (1, 2, 1)) { - int r = aug_transform (aug, "guestfs_shadow", "/etc/shadow", - 0 /* = included */); -@@ -166,6 +168,7 @@ do_aug_init (const char *root, int flags) - } - } - } -+#endif - - return 0; - } --- -2.14.3 - diff --git a/SOURCES/0014-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch b/SOURCES/0014-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch new file mode 100644 index 0000000..24a30bf --- /dev/null +++ b/SOURCES/0014-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch @@ -0,0 +1,94 @@ +From 88ccab22e0af7ffe4c2ffa9a01e39e5f6f693722 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 10 Oct 2014 17:46:02 +0100 +Subject: [PATCH] RHEL 7: Revert "appliance: Use dhclient or dhcpcd instead of + hard-coding IP address of appliance." + +This reverts commit 67e6f32a240c7c234e6af637c1cd324b36a82cd3. +--- + appliance/init | 15 ++++++--------- + appliance/packagelist.in | 7 ------- + 2 files changed, 6 insertions(+), 16 deletions(-) + +diff --git a/appliance/init b/appliance/init +index f530ad3d5..1cd264e08 100755 +--- a/appliance/init ++++ b/appliance/init +@@ -120,15 +120,12 @@ shopt -u nullglob + ip addr add 127.0.0.1/8 brd + dev lo scope host + ip link set dev lo up + +-if test "$guestfs_network" = 1; then +- iface=$(ls -I all -I default -I lo /proc/sys/net/ipv4/conf) +- touch /etc/fstab # Workaround for Ubuntu. +- if dhclient --version >/dev/null 2>&1; then +- dhclient $iface +- else +- dhcpcd $iface +- fi +-fi ++ip addr add 169.254.2.10/16 brd + dev eth0 scope global ++ip link set dev eth0 up ++ ++ip route add default via 169.254.2.2 ++ ++echo nameserver 169.254.2.3 > /etc/resolv.conf + + # Scan for MDs but don't run arrays unless all expected drives are present + mdadm -As --auto=yes --no-degraded +diff --git a/appliance/packagelist.in b/appliance/packagelist.in +index 81a8f0dba..1e7d53481 100644 +--- a/appliance/packagelist.in ++++ b/appliance/packagelist.in +@@ -26,7 +26,6 @@ ifelse(REDHAT,1, + augeas-libs + cryptsetup + cryptsetup-luks dnl old name used before Fedora 17 +- dhclient + genisoimage + gfs-utils + gfs2-utils +@@ -76,7 +75,6 @@ dnl iproute has been renamed to iproute2 + iputils-ping + iputils-arping + iputils-tracepath +- isc-dhcp-client + ldmtool + libaugeas0 + libc-bin +@@ -110,7 +108,6 @@ ifelse(ARCHLINUX,1, + cdrkit + cdrtools + cryptsetup +- dhclient + grub + hivex + iproute2 +@@ -141,8 +138,6 @@ ifelse(SUSE,1, + btrfsprogs + cdrkit-cdrtools-compat + cryptsetup +- dhcpcd +- dhcp-client + genisoimage + glibc-locale + gptfdisk +@@ -171,7 +166,6 @@ ifelse(FRUGALWARE,1, + augeas + cryptsetup-luks + cdrkit +- dhclient + grub2 + hfsplus + iproute2 +@@ -199,7 +193,6 @@ ifelse(MAGEIA,1, + chkconfig /* for /etc/init.d */ + cdrkit-genisoimage + cdrkit-isotools +- dhclient + extlinux + gfs2-utils + grub +-- +2.17.1 + diff --git a/SOURCES/0015-RHEL-7-Disable-alternate-Augeas-lenses.patch b/SOURCES/0015-RHEL-7-Disable-alternate-Augeas-lenses.patch new file mode 100644 index 0000000..3ecc36e --- /dev/null +++ b/SOURCES/0015-RHEL-7-Disable-alternate-Augeas-lenses.patch @@ -0,0 +1,60 @@ +From d7174bcc5290e4ef4996541bed93f0df7e680578 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 24 Oct 2014 16:33:50 +0100 +Subject: [PATCH] RHEL 7: Disable alternate Augeas lenses. + +These are included in the RHEL 7.1 augeas package, and therefore +not required in RHEL. + +See: +https://www.redhat.com/archives/libguestfs/2014-October/msg00220.html +--- + appliance/Makefile.am | 1 - + daemon/augeas.c | 5 ++++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/appliance/Makefile.am b/appliance/Makefile.am +index 6cba8d158..16714b197 100644 +--- a/appliance/Makefile.am ++++ b/appliance/Makefile.am +@@ -91,7 +91,6 @@ supermin.d/daemon.tar.gz: ../daemon/guestfsd guestfs_shadow.aug + rm -rf tmp-d + mkdir -p tmp-d$(DAEMON_SUPERMIN_DIR) tmp-d/etc tmp-d/usr/share/guestfs + ln ../daemon/guestfsd tmp-d$(DAEMON_SUPERMIN_DIR)/guestfsd +- ln $(srcdir)/guestfs_shadow.aug tmp-d/usr/share/guestfs/guestfs_shadow.aug + ( cd tmp-d && tar zcf - * ) > $@-t + rm -r tmp-d + mv $@-t $@ +diff --git a/daemon/augeas.c b/daemon/augeas.c +index 453251337..003fcd313 100644 +--- a/daemon/augeas.c ++++ b/daemon/augeas.c +@@ -134,7 +134,7 @@ do_aug_init (const char *root, int flags) + } + + /* Pass AUG_NO_ERR_CLOSE so we can display detailed errors. */ +- aug = aug_init (buf, "/usr/share/guestfs/", flags | AUG_NO_ERR_CLOSE); ++ aug = aug_init (buf, NULL, flags | AUG_NO_ERR_CLOSE); + + if (!aug) { + reply_with_error ("augeas initialization failed"); +@@ -148,6 +148,8 @@ do_aug_init (const char *root, int flags) + return -1; + } + ++ /* We already have the needed lenses in RHEL 7 */ ++#if 0 + if (!augeas_is_version (1, 2, 1)) { + int r = aug_transform (aug, "guestfs_shadow", "/etc/shadow", + 0 /* = included */); +@@ -166,6 +168,7 @@ do_aug_init (const char *root, int flags) + } + } + } ++#endif + + return 0; + } +-- +2.17.1 + diff --git a/SOURCES/0015-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch b/SOURCES/0015-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch deleted file mode 100644 index 656fd9f..0000000 --- a/SOURCES/0015-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch +++ /dev/null @@ -1,34 +0,0 @@ -From fcc0b3562ac001eaa93d216dcdf567108d96b8b8 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 24 Apr 2015 09:45:41 -0400 -Subject: [PATCH] RHEL 7: 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 56a35c7b9..d72dc3477 100644 ---- a/v2v/utils.ml -+++ b/v2v/utils.ml -@@ -40,13 +40,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.14.3 - diff --git a/SOURCES/0016-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch b/SOURCES/0016-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch new file mode 100644 index 0000000..00b1ee4 --- /dev/null +++ b/SOURCES/0016-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch @@ -0,0 +1,34 @@ +From a0219caff90b669ad9bc8f6fe8d043b3b44725e8 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 24 Apr 2015 09:45:41 -0400 +Subject: [PATCH] RHEL 7: 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 e880001eb..812d339e0 100644 +--- a/v2v/utils.ml ++++ b/v2v/utils.ml +@@ -51,13 +51,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.17.1 + diff --git a/SOURCES/0016-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch b/SOURCES/0016-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch deleted file mode 100644 index cb3e179..0000000 --- a/SOURCES/0016-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 6e6a8a32ab3c3ff33897a6883632a8887c7b508e Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 30 Apr 2015 17:20:26 -0400 -Subject: [PATCH] RHEL 7: v2v: efi: Remove references to Fedora / kraxel's OVMF - packages. - ---- - generator/UEFI.ml | 6 ------ - v2v/utils.ml | 1 - - 2 files changed, 7 deletions(-) - -diff --git a/generator/UEFI.ml b/generator/UEFI.ml -index 95797aad9..881009cfb 100644 ---- a/generator/UEFI.ml -+++ b/generator/UEFI.ml -@@ -30,12 +30,6 @@ open Docstrings - - (* Order is significant *within architectures only*. *) - let firmware = [ -- "i386", -- "/usr/share/edk2.git/ovmf-ia32/OVMF_CODE-pure-efi.fd", -- None, -- "/usr/share/edk2.git/ovmf-ia32/OVMF_VARS-pure-efi.fd", -- []; -- - "x86_64", - "/usr/share/OVMF/OVMF_CODE.fd", - None, -diff --git a/v2v/utils.ml b/v2v/utils.ml -index d72dc3477..2061eea61 100644 ---- a/v2v/utils.ml -+++ b/v2v/utils.ml -@@ -54,7 +54,6 @@ let find_uefi_firmware guest_arch = - let files = - (* The lists of firmware are actually defined in common/utils/uefi.c. *) - match guest_arch with -- | "i386" | "i486" | "i586" | "i686" -> Uefi.uefi_i386_firmware - | "x86_64" -> Uefi.uefi_x86_64_firmware - | "aarch64" -> Uefi.uefi_aarch64_firmware - | arch -> --- -2.14.3 - diff --git a/SOURCES/0017-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch b/SOURCES/0017-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch deleted file mode 100644 index 92b2d72..0000000 --- a/SOURCES/0017-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 7246417f3ba33616846d3c3f3ec097e1b9692de7 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 7 Jul 2015 09:28:03 -0400 -Subject: [PATCH] RHEL 7: Reject use of libguestfs-winsupport features except - for virt-* tools (RHBZ#1240276). - ---- - generator/c.ml | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/generator/c.ml b/generator/c.ml -index 606c89807..bba57c56f 100644 ---- a/generator/c.ml -+++ b/generator/c.ml -@@ -1856,12 +1856,29 @@ and generate_client_actions actions () = - pr " const uint64_t progress_hint = 0;\n"; - - pr "\n"; -+ - enter_event name; - check_null_strings c_name style; - reject_unknown_optargs c_name style; - check_args_validity c_name style; - trace_call name c_name style; - -+ (* RHEL 7 *) -+ if name = "mount" || name = "mount_ro" || name = "mount_options" || -+ name = "mount_vfs" then ( -+ pr " if (g->program && !STRPREFIX (g->program, \"virt-\")) {\n"; -+ pr " CLEANUP_FREE char *vfs_type = guestfs_vfs_type (g, mountable);\n"; -+ pr " if (vfs_type && STREQ (vfs_type, \"ntfs\")) {\n"; -+ pr " error (g, \"mount: unsupported filesystem type\");\n"; -+ pr " if (trace_flag)\n"; -+ pr " guestfs_int_trace (g, \"%%s = %%s (error)\",\n"; -+ pr " \"%s\", \"-1\");\n" name; -+ pr " return %s;\n" (string_of_errcode errcode); -+ pr " }\n"; -+ pr " }\n"; -+ pr "\n"; -+ ); -+ - (* Calculate the total size of all FileIn arguments to pass - * as a progress bar hint. - *) --- -2.14.3 - diff --git a/SOURCES/0017-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch b/SOURCES/0017-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch new file mode 100644 index 0000000..5e53af9 --- /dev/null +++ b/SOURCES/0017-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch @@ -0,0 +1,43 @@ +From ff8c65944b77224f6e3faa7e8f92f6300be075f2 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 30 Apr 2015 17:20:26 -0400 +Subject: [PATCH] RHEL 7: v2v: efi: Remove references to Fedora / kraxel's OVMF + packages. + +--- + generator/UEFI.ml | 6 ------ + v2v/utils.ml | 1 - + 2 files changed, 7 deletions(-) + +diff --git a/generator/UEFI.ml b/generator/UEFI.ml +index 5161e28ee..1ff3f84d2 100644 +--- a/generator/UEFI.ml ++++ b/generator/UEFI.ml +@@ -30,12 +30,6 @@ open Docstrings + + (* Order is significant *within architectures only*. *) + let firmware = [ +- "i386", +- "/usr/share/edk2.git/ovmf-ia32/OVMF_CODE-pure-efi.fd", +- None, +- "/usr/share/edk2.git/ovmf-ia32/OVMF_VARS-pure-efi.fd", +- []; +- + "x86_64", + "/usr/share/OVMF/OVMF_CODE.fd", + None, +diff --git a/v2v/utils.ml b/v2v/utils.ml +index 812d339e0..436acb5f1 100644 +--- a/v2v/utils.ml ++++ b/v2v/utils.ml +@@ -65,7 +65,6 @@ let find_uefi_firmware guest_arch = + let files = + (* The lists of firmware are actually defined in common/utils/uefi.c. *) + match guest_arch with +- | "i386" | "i486" | "i586" | "i686" -> Uefi.uefi_i386_firmware + | "x86_64" -> Uefi.uefi_x86_64_firmware + | "aarch64" -> Uefi.uefi_aarch64_firmware + | arch -> +-- +2.17.1 + diff --git a/SOURCES/0018-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch b/SOURCES/0018-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch new file mode 100644 index 0000000..363fa5f --- /dev/null +++ b/SOURCES/0018-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch @@ -0,0 +1,47 @@ +From 72f59ab23727b2b83bb9109d9ea2ea555c727321 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 7 Jul 2015 09:28:03 -0400 +Subject: [PATCH] RHEL 7: Reject use of libguestfs-winsupport features except + for virt-* tools (RHBZ#1240276). + +--- + generator/c.ml | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/generator/c.ml b/generator/c.ml +index 0366866e2..8ecc63d0b 100644 +--- a/generator/c.ml ++++ b/generator/c.ml +@@ -1826,12 +1826,29 @@ and generate_client_actions actions () = + pr " const uint64_t progress_hint = 0;\n"; + + pr "\n"; ++ + enter_event name; + check_null_strings c_name style; + reject_unknown_optargs c_name style; + check_args_validity c_name style; + trace_call name c_name style; + ++ (* RHEL 7 *) ++ if name = "mount" || name = "mount_ro" || name = "mount_options" || ++ name = "mount_vfs" then ( ++ pr " if (g->program && !STRPREFIX (g->program, \"virt-\")) {\n"; ++ pr " CLEANUP_FREE char *vfs_type = guestfs_vfs_type (g, mountable);\n"; ++ pr " if (vfs_type && STREQ (vfs_type, \"ntfs\")) {\n"; ++ pr " error (g, \"mount: unsupported filesystem type\");\n"; ++ pr " if (trace_flag)\n"; ++ pr " guestfs_int_trace (g, \"%%s = %%s (error)\",\n"; ++ pr " \"%s\", \"-1\");\n" name; ++ pr " return %s;\n" (string_of_errcode errcode); ++ pr " }\n"; ++ pr " }\n"; ++ pr "\n"; ++ ); ++ + (* Calculate the total size of all FileIn arguments to pass + * as a progress bar hint. + *) +-- +2.17.1 + diff --git a/SOURCES/0018-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch b/SOURCES/0018-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch deleted file mode 100644 index c010fa4..0000000 --- a/SOURCES/0018-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 5cd87d524afba59a3916f4c953a4e4b6bccf8c04 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 23 Jul 2015 18:15:36 -0400 -Subject: [PATCH] RHEL 7: daemon: umount-all: Hack to avoid umount: /sysroot: - target is busy (RHBZ#1246032). - -This bug is not properly understood (although readily reproducible). -However this hack makes it go away for now. - -https://bugzilla.redhat.com/show_bug.cgi?id=1246032 ---- - daemon/mount.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/daemon/mount.c b/daemon/mount.c -index 0ad9626a7..b44753441 100644 ---- a/daemon/mount.c -+++ b/daemon/mount.c -@@ -28,6 +28,8 @@ - #include - #include - -+#include "ignore-value.h" -+ - #include "daemon.h" - #include "actions.h" - -@@ -408,6 +410,9 @@ do_umount_all (void) - if (mounts.size > 0) - qsort (mounts.argv, mounts.size, sizeof (char *), compare_longest_first); - -+ /* Hack to work around RHBZ#1246032. */ -+ ignore_value (system ("lsof /sysroot")); -+ - /* Unmount them. */ - for (i = 0; i < mounts.size; ++i) { - CLEANUP_FREE char *err = NULL; --- -2.14.3 - diff --git a/SOURCES/0019-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch b/SOURCES/0019-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch deleted file mode 100644 index 24c4f22..0000000 --- a/SOURCES/0019-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 00ff00aa5a5ce998bd3cfe0457ace9f783e2e3ae Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 30 Aug 2015 03:21:57 -0400 -Subject: [PATCH] RHEL 7: Fix tests for libguestfs-winsupport 7.2. - -It doesn't let us use guestfish for arbitrary Windows edits. ---- - test-data/phony-guests/make-windows-img.sh | 1 + - tests/charsets/test-charset-fidelity.c | 2 ++ - v2v/test-v2v-virtio-win-iso.sh | 8 +++++++- - v2v/test-v2v-windows-conversion.sh | 8 +++++++- - 4 files changed, 17 insertions(+), 2 deletions(-) - -diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh -index 2d18ea489..9eed756d8 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/v2v/test-v2v-windows-conversion.sh b/v2v/test-v2v-windows-conversion.sh -index f1da222a9..ff94fe39b 100755 ---- a/v2v/test-v2v-windows-conversion.sh -+++ b/v2v/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.14.3 - diff --git a/SOURCES/0019-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch b/SOURCES/0019-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch new file mode 100644 index 0000000..ee443ae --- /dev/null +++ b/SOURCES/0019-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch @@ -0,0 +1,40 @@ +From 585cde451b1b6ba28765022f67731fafca3e1be5 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 23 Jul 2015 18:15:36 -0400 +Subject: [PATCH] RHEL 7: daemon: umount-all: Hack to avoid umount: /sysroot: + target is busy (RHBZ#1246032). + +This bug is not properly understood (although readily reproducible). +However this hack makes it go away for now. + +https://bugzilla.redhat.com/show_bug.cgi?id=1246032 +--- + daemon/mount.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/daemon/mount.c b/daemon/mount.c +index 61ce64449..b038a89c3 100644 +--- a/daemon/mount.c ++++ b/daemon/mount.c +@@ -28,6 +28,8 @@ + #include + #include + ++#include "ignore-value.h" ++ + #include "daemon.h" + #include "actions.h" + +@@ -306,6 +308,9 @@ do_umount_all (void) + if (mounts.size > 0) + qsort (mounts.argv, mounts.size, sizeof (char *), compare_longest_first); + ++ /* Hack to work around RHBZ#1246032. */ ++ ignore_value (system ("lsof /sysroot")); ++ + /* Unmount them. */ + for (i = 0; i < mounts.size; ++i) { + CLEANUP_FREE char *err = NULL; +-- +2.17.1 + diff --git a/SOURCES/0020-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch b/SOURCES/0020-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch new file mode 100644 index 0000000..e3232dd --- /dev/null +++ b/SOURCES/0020-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch @@ -0,0 +1,93 @@ +From 22230a37e8120a267567db8d74c7994b98aecdde Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sun, 30 Aug 2015 03:21:57 -0400 +Subject: [PATCH] RHEL 7: Fix tests for libguestfs-winsupport 7.2. + +It doesn't let us use guestfish for arbitrary Windows edits. +--- + test-data/phony-guests/make-windows-img.sh | 1 + + tests/charsets/test-charset-fidelity.c | 2 ++ + v2v/test-v2v-virtio-win-iso.sh | 8 +++++++- + v2v/test-v2v-windows-conversion.sh | 8 +++++++- + 4 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh +index d7c3ec9cf..9e556215a 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/v2v/test-v2v-windows-conversion.sh b/v2v/test-v2v-windows-conversion.sh +index f1da222a9..ff94fe39b 100755 +--- a/v2v/test-v2v-windows-conversion.sh ++++ b/v2v/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.17.1 + diff --git a/SOURCES/0020-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch b/SOURCES/0020-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch deleted file mode 100644 index abba042..0000000 --- a/SOURCES/0020-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 6af2d1ad18bfd41491c3415be64712b0f842b920 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 21 Sep 2015 15:49:17 +0100 -Subject: [PATCH] RHEL 7: Revert "v2v: Add a support matrix to the manual - page." - -This reverts commit a03bffa15a5357d5d0244595caf99607be1ec3ab. ---- - v2v/virt-v2v.pod | 97 -------------------------------------------------------- - 1 file changed, 97 deletions(-) - -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index ff91e29b8..5bef6ae8a 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -145,103 +145,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. - --=head1 SUPPORT MATRIX -- --=head2 Hypervisors (Input) -- --=over 4 -- --=item VMware ESXi -- --Must be managed by VMware vCenter E 5.0. Unmanaged, direct input --from ESXi is not supported. -- --=item OVA exported from VMware -- --OVAs from 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 Glance -- --=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 -- --=head2 Guest firmware -- --BIOS or UEFI for all guest types (but see L below). -- - =head1 OPTIONS - - =over 4 --- -2.14.3 - diff --git a/SOURCES/0021-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch b/SOURCES/0021-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch deleted file mode 100644 index eed5ec0..0000000 --- a/SOURCES/0021-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch +++ /dev/null @@ -1,46 +0,0 @@ -From ef6ad315f02830f04a467cd32be09e2b25ce3824 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 27 May 2015 10:03:00 -0400 -Subject: [PATCH] RHEL 7: All qemu-kvm in RHEL 7 supports discard of qcow2 - (RHBZ#1225467). - -For rationale behind this, see: - - https://bugzilla.redhat.com/show_bug.cgi?id=1225467#c2 ---- - lib/qemu.c | 12 ++---------- - 1 file changed, 2 insertions(+), 10 deletions(-) - -diff --git a/lib/qemu.c b/lib/qemu.c -index a5278129c..c9debe937 100644 ---- a/lib/qemu.c -+++ b/lib/qemu.c -@@ -963,10 +963,6 @@ guestfs_int_discard_possible (guestfs_h *g, struct drive *drv, - * discard option on -drive at all. - */ - bool qemu15 = guestfs_int_version_ge (qemu_version, 1, 5, 0); -- /* qemu >= 1.6. This was the first version that supported unmap on -- * qcow2 backing files. -- */ -- bool qemu16 = guestfs_int_version_ge (qemu_version, 1, 6, 0); - - if (!qemu15) - NOT_SUPPORTED (g, false, -@@ -991,12 +987,8 @@ guestfs_int_discard_possible (guestfs_h *g, struct drive *drv, - } - else if (STREQ (drv->src.format, "raw")) - /* OK */ ; -- else if (STREQ (drv->src.format, "qcow2")) { -- if (!qemu16) -- NOT_SUPPORTED (g, false, -- _("discard cannot be enabled on this drive: " -- "qemu < 1.6 cannot do discard on qcow2 files")); -- } -+ else if (STREQ (drv->src.format, "qcow2")) -+ /* OK */ ; - else { - /* It's possible in future other formats will support discard, but - * currently (qemu 1.7) none of them do. --- -2.14.3 - diff --git a/SOURCES/0021-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch b/SOURCES/0021-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch new file mode 100644 index 0000000..517e419 --- /dev/null +++ b/SOURCES/0021-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch @@ -0,0 +1,125 @@ +From 35f39fff27089d79c9f42d304b033b1aa14db430 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 21 Sep 2015 15:49:17 +0100 +Subject: [PATCH] RHEL 7: Revert "v2v: Add a support matrix to the manual + page." + +This reverts commit a03bffa15a5357d5d0244595caf99607be1ec3ab. +--- + v2v/virt-v2v.pod | 100 ----------------------------------------------- + 1 file changed, 100 deletions(-) + +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 1c06502ec..f33f9bf62 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -165,106 +165,6 @@ is only used when virt-v2v runs under VDSM control. + I<--in-place> instructs virt-v2v to customize the guest OS in the input + virtual machine, instead of creating a new VM in the target hypervisor. + +-=head1 SUPPORT MATRIX +- +-=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 Glance +- +-=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 +- +-=head2 Guest firmware +- +-BIOS or UEFI for all guest types (but see L below). +- + =head1 OPTIONS + + =over 4 +-- +2.17.1 + diff --git a/SOURCES/0022-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch b/SOURCES/0022-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch new file mode 100644 index 0000000..6dd39e1 --- /dev/null +++ b/SOURCES/0022-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch @@ -0,0 +1,46 @@ +From 22aa6ba208a06138fb482231877992c1cd31eb4f Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 27 May 2015 10:03:00 -0400 +Subject: [PATCH] RHEL 7: All qemu-kvm in RHEL 7 supports discard of qcow2 + (RHBZ#1225467). + +For rationale behind this, see: + + https://bugzilla.redhat.com/show_bug.cgi?id=1225467#c2 +--- + lib/qemu.c | 12 ++---------- + 1 file changed, 2 insertions(+), 10 deletions(-) + +diff --git a/lib/qemu.c b/lib/qemu.c +index 6159b5a52..1e52cf75b 100644 +--- a/lib/qemu.c ++++ b/lib/qemu.c +@@ -916,10 +916,6 @@ guestfs_int_discard_possible (guestfs_h *g, struct drive *drv, + * discard option on -drive at all. + */ + bool qemu15 = guestfs_int_version_ge (qemu_version, 1, 5, 0); +- /* qemu >= 1.6. This was the first version that supported unmap on +- * qcow2 backing files. +- */ +- bool qemu16 = guestfs_int_version_ge (qemu_version, 1, 6, 0); + + if (!qemu15) + NOT_SUPPORTED (g, false, +@@ -944,12 +940,8 @@ guestfs_int_discard_possible (guestfs_h *g, struct drive *drv, + } + else if (STREQ (drv->src.format, "raw")) + /* OK */ ; +- else if (STREQ (drv->src.format, "qcow2")) { +- if (!qemu16) +- NOT_SUPPORTED (g, false, +- _("discard cannot be enabled on this drive: " +- "qemu < 1.6 cannot do discard on qcow2 files")); +- } ++ else if (STREQ (drv->src.format, "qcow2")) ++ /* OK */ ; + else { + /* It's possible in future other formats will support discard, but + * currently (qemu 1.7) none of them do. +-- +2.17.1 + diff --git a/SOURCES/0022-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch b/SOURCES/0022-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch deleted file mode 100644 index 4bb5241..0000000 --- a/SOURCES/0022-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 6af62afc2e3287b1c87908f300167aeffac6017a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 21 Sep 2015 13:12:43 -0400 -Subject: [PATCH] RHEL 7: tests: Disable daemon tests that require the 'unix' - backend. - ---- - tests/daemon/Makefile.am | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/tests/daemon/Makefile.am b/tests/daemon/Makefile.am -index 053cad3e1..0d723fee4 100644 ---- a/tests/daemon/Makefile.am -+++ b/tests/daemon/Makefile.am -@@ -23,9 +23,7 @@ include $(top_srcdir)/subdir-rules.mk - - check_DATA = captive-daemon.pm - --TESTS = \ -- test-daemon-start.pl \ -- test-btrfs.pl -+TESTS = - - TESTS_ENVIRONMENT = $(top_builddir)/run --test - --- -2.14.3 - diff --git a/SOURCES/0023-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch b/SOURCES/0023-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch new file mode 100644 index 0000000..e3b56b9 --- /dev/null +++ b/SOURCES/0023-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch @@ -0,0 +1,28 @@ +From b2d12237ae3b1ffeb343cf40ef528a2c0caa97da Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 21 Sep 2015 13:12:43 -0400 +Subject: [PATCH] RHEL 7: tests: Disable daemon tests that require the 'unix' + backend. + +--- + tests/daemon/Makefile.am | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/tests/daemon/Makefile.am b/tests/daemon/Makefile.am +index 053cad3e1..0d723fee4 100644 +--- a/tests/daemon/Makefile.am ++++ b/tests/daemon/Makefile.am +@@ -23,9 +23,7 @@ include $(top_srcdir)/subdir-rules.mk + + check_DATA = captive-daemon.pm + +-TESTS = \ +- test-daemon-start.pl \ +- test-btrfs.pl ++TESTS = + + TESTS_ENVIRONMENT = $(top_builddir)/run --test + +-- +2.17.1 + diff --git a/SOURCES/0023-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch b/SOURCES/0023-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch deleted file mode 100644 index 89e3131..0000000 --- a/SOURCES/0023-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch +++ /dev/null @@ -1,273 +0,0 @@ -From 56aa0b649b144e78e791e134ee33422c273a8f22 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 14 Jan 2016 11:53:42 -0500 -Subject: [PATCH] RHEL 7: 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). ---- - v2v/Makefile.am | 2 - - v2v/cmdline.ml | 6 ++- - v2v/test-v2v-docs.sh | 2 +- - v2v/test-v2v-in-place.sh | 108 ----------------------------------------------- - v2v/virt-v2v.pod | 46 +------------------- - 5 files changed, 7 insertions(+), 157 deletions(-) - delete mode 100755 v2v/test-v2v-in-place.sh - -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index 133a411bc..297406496 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -291,7 +291,6 @@ if HAVE_LIBVIRT - TESTS += \ - test-v2v-cdrom.sh \ - test-v2v-floppy.sh \ -- test-v2v-in-place.sh \ - test-v2v-networks-and-bridges.sh \ - test-v2v-no-copy.sh \ - test-v2v-o-glance.sh \ -@@ -412,7 +411,6 @@ EXTRA_DIST += \ - test-v2v-i-ova.ovf \ - test-v2v-i-ova.sh \ - test-v2v-i-ova.xml \ -- test-v2v-in-place.sh \ - test-v2v-machine-readable.sh \ - test-v2v-networks-and-bridges-expected.xml \ - test-v2v-networks-and-bridges.sh \ -diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml -index 5a1ea04f3..3e3d5c312 100644 ---- a/v2v/cmdline.ml -+++ b/v2v/cmdline.ml -@@ -179,7 +179,7 @@ let parse_cmdline () = - s_"Libvirt URI"; - [ M"if" ], Getopt.String ("format", set_string_option_once "-if" input_format), - s_"Input format (for -i disk)"; -- [ L"in-place" ], Getopt.Set in_place, s_"Only tune the guest in the input VM"; -+ [ L"in-place" ], Getopt.Set in_place, ""; - [ L"machine-readable" ], Getopt.Set machine_readable, s_"Make output machine readable"; - [ S 'n'; L"network" ], Getopt.String ("in:out", add_network), s_"Map network 'in' to 'out'"; - [ L"no-copy" ], Getopt.Clear do_copy, s_"Just write the metadata"; -@@ -335,6 +335,10 @@ read the man page virt-v2v(1). - error (f_"expecting an OVA file name on the command line") in - Input_ova.input_ova filename in - -+ (* Prevent use of --in-place option in RHEL. *) -+ if in_place then -+ error (f_"--in-place cannot be used in RHEL 7"); -+ - (* 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 -diff --git a/v2v/test-v2v-docs.sh b/v2v/test-v2v-docs.sh -index d341852b7..c5d98de7f 100755 ---- a/v2v/test-v2v-docs.sh -+++ b/v2v/test-v2v-docs.sh -@@ -22,4 +22,4 @@ $TEST_FUNCTIONS - skip_if_skipped - - $top_srcdir/podcheck.pl virt-v2v.pod virt-v2v \ -- --ignore=--dcPath,--debug-overlay,--ic,--if,--no-trim,--oa,--oc,--of,--on,--os,--vmtype -+ --ignore=--dcPath,--debug-overlay,--ic,--if,--in-place,--no-trim,--oa,--oc,--of,--on,--os,--vmtype -diff --git a/v2v/test-v2v-in-place.sh b/v2v/test-v2v-in-place.sh -deleted file mode 100755 -index 6f7d78f39..000000000 ---- a/v2v/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/virt-v2v.pod b/v2v/virt-v2v.pod -index 5bef6ae8a..1c866e773 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -15,8 +15,6 @@ virt-v2v - Convert a guest to use KVM - - virt-v2v -i disk disk.img -o glance - -- virt-v2v -ic qemu:///system qemu_guest --in-place -- - =head1 DESCRIPTION - - Virt-v2v converts guests from a foreign hypervisor to run on KVM. It -@@ -77,9 +75,6 @@ booting the guest directly in qemu (mainly for testing). - I<-o rhv> is used to write to a RHV / oVirt target. I<-o vdsm> - is only used when virt-v2v runs under VDSM control. - --I<--in-place> instructs virt-v2v to customize the guest OS in the input --virtual machine, instead of creating a new VM in the target hypervisor. -- - =head1 EXAMPLES - - =head2 Convert from VMware vCenter server to local libvirt -@@ -251,20 +246,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<--machine-readable> - - This option is used to make the output more machine friendly -@@ -1657,7 +1638,7 @@ Minimum free space: 10 MB - =head2 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`" -@@ -1789,31 +1770,6 @@ that instead. - - - --=head1 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. -- - =head1 MACHINE READABLE OUTPUT - - The I<--machine-readable> option can be used to make the output more --- -2.14.3 - diff --git a/SOURCES/0024-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch b/SOURCES/0024-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch new file mode 100644 index 0000000..c1d762b --- /dev/null +++ b/SOURCES/0024-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch @@ -0,0 +1,282 @@ +From fb3e89b0fb2d0de3c12a668c00d07c5cfcac9ec0 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 14 Jan 2016 11:53:42 -0500 +Subject: [PATCH] RHEL 7: 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). +--- + v2v/Makefile.am | 2 - + v2v/cmdline.ml | 8 +-- + v2v/test-v2v-docs.sh | 2 +- + v2v/test-v2v-in-place.sh | 108 --------------------------------------- + v2v/virt-v2v.pod | 46 +---------------- + 5 files changed, 7 insertions(+), 159 deletions(-) + delete mode 100755 v2v/test-v2v-in-place.sh + +diff --git a/v2v/Makefile.am b/v2v/Makefile.am +index 0c3224b24..424530b1d 100644 +--- a/v2v/Makefile.am ++++ b/v2v/Makefile.am +@@ -330,7 +330,6 @@ if HAVE_LIBVIRT + TESTS += \ + test-v2v-cdrom.sh \ + test-v2v-floppy.sh \ +- test-v2v-in-place.sh \ + test-v2v-networks-and-bridges.sh \ + test-v2v-no-copy.sh \ + test-v2v-o-glance.sh \ +@@ -469,7 +468,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-machine-readable.sh \ + test-v2v-networks-and-bridges-expected.xml \ + test-v2v-networks-and-bridges.sh \ +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index d6f99fa00..0bc5e9055 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -194,8 +194,7 @@ let parse_cmdline () = + s_"Input format (for -i disk)"; + [ 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"machine-readable" ], Getopt.Set machine_readable, + s_"Make output machine readable"; + [ S 'n'; L"network" ], Getopt.String ("in:out", add_network), +@@ -338,7 +337,6 @@ read the man page virt-v2v(1). + printf "vddk\n"; + printf "colours-option\n"; + printf "vdsm-compat-option\n"; +- printf "in-place\n"; + List.iter (printf "input:%s\n") (Modules_list.input_modules ()); + List.iter (printf "output:%s\n") (Modules_list.output_modules ()); + List.iter (printf "convert:%s\n") (Modules_list.convert_modules ()); +@@ -438,6 +436,10 @@ read the man page virt-v2v(1). + error (f_"only ‘-it ssh’ can be used here") in + Input_vmx.input_vmx 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 7"); ++ + (* 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 +diff --git a/v2v/test-v2v-docs.sh b/v2v/test-v2v-docs.sh +index 5d034c465..c8ca193eb 100755 +--- a/v2v/test-v2v-docs.sh ++++ b/v2v/test-v2v-docs.sh +@@ -22,4 +22,4 @@ $TEST_FUNCTIONS + skip_if_skipped + + $top_srcdir/podcheck.pl virt-v2v.pod virt-v2v \ +- --ignore=--debug-overlay,--ic,--if,--it,--no-trim,--oa,--oc,--of,--on,--os,--vmtype ++ --ignore=--debug-overlay,--ic,--if,--in-place,--it,--no-trim,--oa,--oc,--of,--on,--os,--vmtype +diff --git a/v2v/test-v2v-in-place.sh b/v2v/test-v2v-in-place.sh +deleted file mode 100755 +index 6f7d78f39..000000000 +--- a/v2v/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/virt-v2v.pod b/v2v/virt-v2v.pod +index f33f9bf62..0e0fa0f64 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -15,8 +15,6 @@ virt-v2v - Convert a guest to use KVM + + virt-v2v -i disk disk.img -o glance + +- virt-v2v -ic qemu:///system qemu_guest --in-place +- + =head1 DESCRIPTION + + Virt-v2v converts guests from a foreign hypervisor to run on KVM. It +@@ -162,9 +160,6 @@ booting the guest directly in qemu (mainly for testing). + I<-o rhv> is used to write to a RHV / oVirt target. I<-o vdsm> + is only used when virt-v2v runs under VDSM control. + +-I<--in-place> instructs virt-v2v to customize the guest OS in the input +-virtual machine, instead of creating a new VM in the target hypervisor. +- + =head1 OPTIONS + + =over 4 +@@ -278,20 +273,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<-it> B + + When using I<-i vmx>, this enables the ssh transport. +@@ -1979,7 +1960,7 @@ Minimum free space: 10 MB + =head2 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`" +@@ -2111,31 +2092,6 @@ that instead. + + + +-=head1 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. +- + =head1 MACHINE READABLE OUTPUT + + The I<--machine-readable> option can be used to make the output more +-- +2.17.1 + diff --git a/SOURCES/0024-RHEL-7-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch b/SOURCES/0024-RHEL-7-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch deleted file mode 100644 index 3e457c0..0000000 --- a/SOURCES/0024-RHEL-7-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch +++ /dev/null @@ -1,26 +0,0 @@ -From f1905ec2781ed29bebbb2b6311d8c82261c09a88 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 2 Mar 2017 14:21:37 +0100 -Subject: [PATCH] RHEL 7: v2v: -i disk: force VNC as display (RHBZ#1372671) - -The SDL output mode is not supported in RHEL 7'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 27f855352..1f319a487 100644 ---- a/v2v/input_disk.ml -+++ b/v2v/input_disk.ml -@@ -83,7 +83,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.14.3 - diff --git a/SOURCES/0025-RHEL-7-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch b/SOURCES/0025-RHEL-7-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch deleted file mode 100644 index 57abe79..0000000 --- a/SOURCES/0025-RHEL-7-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch +++ /dev/null @@ -1,27 +0,0 @@ -From fa0f50b8a18a1265b3876de50fb720247e980ceb Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Wed, 8 Mar 2017 11:03:40 +0100 -Subject: [PATCH] RHEL 7: v2v: do not mention SUSE Xen hosts (RHBZ#1430203) - -They are not supported in RHEL 7. ---- - v2v/virt-v2v.pod | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 1c866e773..709075fba 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -1194,8 +1194,7 @@ Remove the F and F files. - - =head1 INPUT FROM XEN - --Virt-v2v is able to import Xen guests from RHEL 5 Xen or SLES and --openSUSE Xen hosts. -+Virt-v2v is able to import Xen guests from RHEL 5 Xen hosts. - - Virt-v2v uses libvirt for access to the remote Xen host, and therefore - the input mode should be I<-i libvirt>. As this is the default, you --- -2.14.3 - diff --git a/SOURCES/0025-RHEL-7-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch b/SOURCES/0025-RHEL-7-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch new file mode 100644 index 0000000..b31f43c --- /dev/null +++ b/SOURCES/0025-RHEL-7-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch @@ -0,0 +1,26 @@ +From 595de95272d40f7ddb47c22c187a4bf19982de35 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 2 Mar 2017 14:21:37 +0100 +Subject: [PATCH] RHEL 7: v2v: -i disk: force VNC as display (RHBZ#1372671) + +The SDL output mode is not supported in RHEL 7'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 7ecd19fd3..e2b16cf70 100644 +--- a/v2v/input_disk.ml ++++ b/v2v/input_disk.ml +@@ -87,7 +87,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.17.1 + diff --git a/SOURCES/0026-RHEL-7-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch b/SOURCES/0026-RHEL-7-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch new file mode 100644 index 0000000..31cd93d --- /dev/null +++ b/SOURCES/0026-RHEL-7-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch @@ -0,0 +1,27 @@ +From 353671bd139f52b55e9527ff6b3303463e421d81 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Wed, 8 Mar 2017 11:03:40 +0100 +Subject: [PATCH] RHEL 7: v2v: do not mention SUSE Xen hosts (RHBZ#1430203) + +They are not supported in RHEL 7. +--- + v2v/virt-v2v.pod | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 0e0fa0f64..f8a937960 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -1520,8 +1520,7 @@ verbose messages. + + =head1 INPUT FROM XEN + +-Virt-v2v is able to import Xen guests from RHEL 5 Xen or SLES and +-openSUSE Xen hosts. ++Virt-v2v is able to import Xen guests from RHEL 5 Xen hosts. + + Virt-v2v uses libvirt for access to the remote Xen host, and therefore + the input mode should be I<-i libvirt>. As this is the default, you +-- +2.17.1 + diff --git a/SOURCES/0026-sysprep-Remove-DHCP_HOSTNAME-from-ifcfg-files-RHBZ-1.patch b/SOURCES/0026-sysprep-Remove-DHCP_HOSTNAME-from-ifcfg-files-RHBZ-1.patch deleted file mode 100644 index e92d14d..0000000 --- a/SOURCES/0026-sysprep-Remove-DHCP_HOSTNAME-from-ifcfg-files-RHBZ-1.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 563085e246220a3e7e88309f82d2edf71cd3db5a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 28 Feb 2017 15:48:18 +0000 -Subject: [PATCH] sysprep: Remove DHCP_HOSTNAME= from ifcfg-* files - (RHBZ#1427529). - -(cherry picked from commit 0f99537cb69c88f7ceb6c69a9d9ae10baaaa3623) ---- - sysprep/sysprep_operation_net_hostname.ml | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/sysprep/sysprep_operation_net_hostname.ml b/sysprep/sysprep_operation_net_hostname.ml -index 3824d42ae..7284d630f 100644 ---- a/sysprep/sysprep_operation_net_hostname.ml -+++ b/sysprep/sysprep_operation_net_hostname.ml -@@ -30,10 +30,12 @@ let net_hostname_perform (g : Guestfs.guestfs) root side_effects = - let filenames = g#glob_expand "/etc/sysconfig/network-scripts/ifcfg-*" in - Array.iter ( - fun filename -> -- (* Replace HOSTNAME=... entry. *) -+ (* Remove HOSTNAME=... and DHCP_HOSTNAME=... entries. *) - let lines = Array.to_list (g#read_lines filename) in - let lines = List.filter ( -- fun line -> not (String.is_prefix line "HOSTNAME=") -+ fun line -> -+ not (String.is_prefix line "HOSTNAME=") && -+ not (String.is_prefix line "DHCP_HOSTNAME=") - ) lines in - let file = String.concat "\n" lines ^ "\n" in - g#write filename file; -@@ -46,7 +48,7 @@ let op = { - defaults with - name = "net-hostname"; - enabled_by_default = true; -- heading = s_"Remove HOSTNAME in network interface configuration"; -+ heading = s_"Remove HOSTNAME and DHCP_HOSTNAME in network interface configuration"; - pod_description = Some (s_"\ - For Fedora and Red Hat Enterprise Linux, - this is removed from C files."); --- -2.14.3 - diff --git a/SOURCES/0027-RHEL-7-v2v-disable-unconfig-of-manually-installed-VM.patch b/SOURCES/0027-RHEL-7-v2v-disable-unconfig-of-manually-installed-VM.patch new file mode 100644 index 0000000..25d2c2e --- /dev/null +++ b/SOURCES/0027-RHEL-7-v2v-disable-unconfig-of-manually-installed-VM.patch @@ -0,0 +1,36 @@ +From e4983bad21c2d188d1fb7d7e4cd4d58df1df74ae Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Mon, 14 Aug 2017 10:02:13 +0200 +Subject: [PATCH] RHEL 7: v2v: disable unconfig of manually installed VMware + tools (RHBZ#1477905) + +It looks like they may require connection to the VMware servers, which +is not always available during conversion. +--- + v2v/convert_linux.ml | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml +index 4a7447fe1..7588fbf8e 100644 +--- a/v2v/convert_linux.ml ++++ b/v2v/convert_linux.ml +@@ -352,6 +352,7 @@ let convert (g : G.guestfs) inspect source output rcaps = + let remove = !remove in + Linux.remove g inspect remove; + ++(* + (* VMware Tools may have been installed from a tarball, so the + * above code won't remove it. Look for the uninstall tool and run + * if present. +@@ -373,6 +374,8 @@ let convert (g : G.guestfs) inspect source output rcaps = + warning (f_"VMware tools was detected, but uninstallation failed. The error message was: %s (ignored)") + msg + ) ++*) ++ () + + and unconfigure_citrix () = + let pkgs = +-- +2.17.1 + diff --git a/SOURCES/0027-p2v-Run-fewer-scp-commands.patch b/SOURCES/0027-p2v-Run-fewer-scp-commands.patch deleted file mode 100644 index bcd0172..0000000 --- a/SOURCES/0027-p2v-Run-fewer-scp-commands.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 847f9845085f76be8a00eba10fd995fe5e25ea21 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 30 Mar 2017 13:13:03 +0100 -Subject: [PATCH] p2v: Run fewer 'scp' commands. - -Each scp command takes a considerable amount of time -- several -seconds -- because it must set up, authenticate and tear down a new -connection. Avoid this by combining several copies into a single -command. - -We still have to use two scp commands because we want to check that -some files are copied and ignore failures in a second set of -informational files. - -(cherry picked from commit d178deeeb814471b9d70431626b6cd515a21d0c1) ---- - p2v/conversion.c | 31 +++++++++++-------------------- - p2v/p2v.h | 2 +- - p2v/ssh.c | 25 +++++++++++++++++++++---- - 3 files changed, 33 insertions(+), 25 deletions(-) - -diff --git a/p2v/conversion.c b/p2v/conversion.c -index 94a466640..27c6b2f2d 100644 ---- a/p2v/conversion.c -+++ b/p2v/conversion.c -@@ -366,28 +366,19 @@ start_conversion (struct config *config, - } - - /* Copy the static files to the remote dir. */ -- if (scp_file (config, name_file, remote_dir) == -1) { -- set_conversion_error ("scp: %s to %s: %s", -- name_file, remote_dir, get_ssh_error ()); -+ -+ /* These three files must not fail, so check for errors here. */ -+ if (scp_file (config, remote_dir, -+ name_file, libvirt_xml_file, wrapper_script, NULL) == -1) { -+ set_conversion_error ("scp: %s: %s", -+ remote_dir, get_ssh_error ()); - goto out; - } -- if (scp_file (config, libvirt_xml_file, remote_dir) == -1) { -- set_conversion_error ("scp: %s to %s: %s", -- libvirt_xml_file, remote_dir, get_ssh_error ()); -- goto out; -- } -- if (scp_file (config, wrapper_script, remote_dir) == -1) { -- set_conversion_error ("scp: %s to %s: %s", -- wrapper_script, remote_dir, get_ssh_error ()); -- goto out; -- } -- /* It's not essential that these files are copied. */ -- ignore_value (scp_file (config, dmesg_file, remote_dir)); -- ignore_value (scp_file (config, lscpu_file, remote_dir)); -- ignore_value (scp_file (config, lspci_file, remote_dir)); -- ignore_value (scp_file (config, lsscsi_file, remote_dir)); -- ignore_value (scp_file (config, lsusb_file, remote_dir)); -- ignore_value (scp_file (config, p2v_version_file, remote_dir)); -+ -+ /* It's not essential that these files are copied, so ignore errors. */ -+ ignore_value (scp_file (config, remote_dir, -+ dmesg_file, lscpu_file, lspci_file, lsscsi_file, -+ lsusb_file, p2v_version_file, NULL)); - - /* Do the conversion. This runs until virt-v2v exits. */ - if (notify_ui) -diff --git a/p2v/p2v.h b/p2v/p2v.h -index 5223aa216..b26648a01 100644 ---- a/p2v/p2v.h -+++ b/p2v/p2v.h -@@ -128,7 +128,7 @@ extern int test_connection (struct config *); - extern mexp_h *open_data_connection (struct config *, const char *local_ipaddr, int local_port, int *remote_port); - extern mexp_h *start_remote_connection (struct config *, const char *remote_dir); - extern const char *get_ssh_error (void); --extern int scp_file (struct config *config, const char *localfile, const char *remotefile); -+extern int scp_file (struct config *config, const char *target, const char *local, ...) __attribute__((sentinel)); - - /* nbd.c */ - extern void set_nbd_option (const char *opt); -diff --git a/p2v/ssh.c b/p2v/ssh.c -index dfcab0e40..991888348 100644 ---- a/p2v/ssh.c -+++ b/p2v/ssh.c -@@ -572,14 +572,18 @@ start_ssh (unsigned spawn_flags, struct config *config, - #endif - - /** -- * Upload a file to remote using L. -+ * Upload file(s) to remote using L. -+ * -+ * Note that the target (directory or file) comes before the list of -+ * local files, because the list of local files is a varargs list. - * - * This is a simplified version of L above. - */ - int --scp_file (struct config *config, const char *localfile, const char *remotefile) -+scp_file (struct config *config, const char *target, const char *local, ...) - { - size_t i = 0; -+ va_list args; - const size_t MAX_ARGS = 64; - const char *argv[MAX_ARGS]; - char port_str[64]; -@@ -618,12 +622,25 @@ scp_file (struct config *config, const char *localfile, const char *remotefile) - ADD_ARG (argv, i, "-i"); - ADD_ARG (argv, i, config->identity_file); - } -- ADD_ARG (argv, i, localfile); -+ -+ /* Source files or directories. -+ * Strictly speaking this could abort() if the list of files is -+ * too long, but that never happens in virt-p2v. XXX -+ */ -+ va_start (args, local); -+ do ADD_ARG (argv, i, local); -+ while ((local = va_arg (args, const char *)) != NULL); -+ va_end (args); -+ -+ /* The target file or directory. We need to rewrite this as -+ * "username@server:target". -+ */ - if (asprintf (&remote, "%s@%s:%s", - config->username ? config->username : "root", -- config->server, remotefile) == -1) -+ config->server, target) == -1) - error (EXIT_FAILURE, errno, "asprintf"); - ADD_ARG (argv, i, remote); -+ - ADD_ARG (argv, i, NULL); - - #if DEBUG_STDERR --- -2.14.3 - diff --git a/SOURCES/0028-p2v-Fix-list-of-files-in-documentation.patch b/SOURCES/0028-p2v-Fix-list-of-files-in-documentation.patch deleted file mode 100644 index a0b8b01..0000000 --- a/SOURCES/0028-p2v-Fix-list-of-files-in-documentation.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 77faaa76368ecd4e758d0705a44c1afc25c95796 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 30 Mar 2017 14:45:47 +0100 -Subject: [PATCH] p2v: Fix list of files in documentation. - -(cherry picked from commit 38e7a1e038a91e34010ca0f89b0da077be821421) ---- - p2v/virt-p2v.pod | 28 +++++++++++++--------------- - 1 file changed, 13 insertions(+), 15 deletions(-) - -diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod -index ee870fdd9..7fd637152 100644 ---- a/p2v/virt-p2v.pod -+++ b/p2v/virt-p2v.pod -@@ -724,18 +724,6 @@ Into this directory are written various files which include: - - =item F - --I<(before conversion)> -- --The dmesg output from the physical machine. Useful for detecting --problems such as missing device drivers or firmware on the virt-p2v --ISO. -- --=item F -- --I<(before conversion)> -- --The content of the environment where L will run. -- - =item F - - =item F -@@ -746,8 +734,18 @@ The content of the environment where L will run. - - I<(before conversion)> - --The output of the corresponding commands (ie L etc) on the --physical machine. Useful for debugging novel hardware configurations. -+The output of the corresponding commands (ie L, L -+etc) on the physical machine. -+ -+The dmesg output is useful for detecting problems such as missing -+device drivers or firmware on the virt-p2v ISO. The others are useful -+for debugging novel hardware configurations. -+ -+=item F -+ -+I<(before conversion)> -+ -+The content of the environment where L will run. - - =item F - -@@ -799,7 +797,7 @@ B log file in any bug reports or support tickets. - - =item F - --I<(during/after conversion)> -+I<(before conversion)> - - This is the wrapper script which is used when running virt-v2v. For - interest only, do not attempt to run this script yourself. --- -2.14.3 - diff --git a/SOURCES/0028-v2v-Use-Std_utils.qemu_input_filename-instead-of-pre.patch b/SOURCES/0028-v2v-Use-Std_utils.qemu_input_filename-instead-of-pre.patch new file mode 100644 index 0000000..67a8577 --- /dev/null +++ b/SOURCES/0028-v2v-Use-Std_utils.qemu_input_filename-instead-of-pre.patch @@ -0,0 +1,33 @@ +From d3fd52a8e1241bace8d149ef31f6404dd61f89df Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 22 May 2018 08:09:28 +0100 +Subject: [PATCH] v2v: Use Std_utils.qemu_input_filename instead of prefixing + "file:" to filename (RHBZ#1580292). + +This also allows us to use virt-v2v with the old version of qemu in +RHEL 7. + +Fixes commit e29296cfa20dd691995832940a30fe2e6b98149a. + +Thanks: Pino Toscano for suggesting the fix. +(cherry picked from commit 0c934144eb8ea0ee1e1f68d4975415c001a62556) +--- + v2v/v2v.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/v2v.ml b/v2v/v2v.ml +index 90173b018..6b9bdadf6 100644 +--- a/v2v/v2v.ml ++++ b/v2v/v2v.ml +@@ -726,7 +726,7 @@ and copy_targets cmdline targets input output = + let cmd = + let filename = + match t.target_file with +- | TargetFile filename -> "file:" ^ filename ++ | TargetFile filename -> qemu_input_filename filename + | TargetURI uri -> uri in + [ "qemu-img"; "convert" ] @ + (if not (quiet ()) then [ "-p" ] else []) @ +-- +2.17.1 + diff --git a/SOURCES/0029-p2v-tests-Fix-fake-scp-command-so-it-can-handle-mult.patch b/SOURCES/0029-p2v-tests-Fix-fake-scp-command-so-it-can-handle-mult.patch deleted file mode 100644 index 17bd1cf..0000000 --- a/SOURCES/0029-p2v-tests-Fix-fake-scp-command-so-it-can-handle-mult.patch +++ /dev/null @@ -1,46 +0,0 @@ -From f06fc3401bc88206502f6f876a553634c8acf220 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 30 Mar 2017 19:34:29 +0100 -Subject: [PATCH] p2v: tests: Fix fake scp command so it can handle multiple - local files. - -Fixes commit d178deeeb814471b9d70431626b6cd515a21d0c1. - -(cherry picked from commit b417c877f4ea848af8f8538957ab677c65637027) ---- - p2v/test-virt-p2v-scp.sh | 16 ++++++++++------ - 1 file changed, 10 insertions(+), 6 deletions(-) - -diff --git a/p2v/test-virt-p2v-scp.sh b/p2v/test-virt-p2v-scp.sh -index c8a405db4..29900b663 100755 ---- a/p2v/test-virt-p2v-scp.sh -+++ b/p2v/test-virt-p2v-scp.sh -@@ -44,15 +44,19 @@ while true ; do - esac - done - --# Hopefully there are two arguments left, the source (local) file --# and a remote file of the form user@server:remote. --if [ $# -ne 2 ]; then -+# Hopefully there are >= two arguments left, the source (local) -+# file(s) and a remote file of the form user@server:remote. -+if [ $# -lt 2 ]; then - echo "$0: incorrect number of arguments found:" "$@" - exit 1 - fi - --local="$1" --remote="$(echo $2 | awk -F: '{print $2}')" -+# https://stackoverflow.com/questions/1853946/getting-the-last-argument-passed-to-a-shell-script/1854031#1854031 -+remote="${@: -1}" -+# https://stackoverflow.com/questions/20398499/remove-last-argument-from-argument-list-of-shell-script-bash/26163980#26163980 -+set -- "${@:1:$(($#-1))}" -+ -+remote="$(echo $remote | awk -F: '{print $2}')" - - # Use the copy command. --exec cp "$local" "$remote" -+exec cp "$@" "$remote" --- -2.14.3 - diff --git a/SOURCES/0029-v2v-o-null-support-older-qemu-img-RHBZ-1580309.patch b/SOURCES/0029-v2v-o-null-support-older-qemu-img-RHBZ-1580309.patch new file mode 100644 index 0000000..f2a351e --- /dev/null +++ b/SOURCES/0029-v2v-o-null-support-older-qemu-img-RHBZ-1580309.patch @@ -0,0 +1,110 @@ +From 62dce61f73b9f0ea9e75a65713a21f4f8368381e Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Mon, 21 May 2018 17:19:25 +0200 +Subject: [PATCH] v2v: -o null: support older qemu-img (RHBZ#1580309) + +Commit 4699c7b6e126e07c95b67fb95df58aed87a680dd converted the null +output to use the null-co qemu driver with a JSON URL syntax -- +especially the latter is only available in newer versions of qemu. + +Even if this output mode is mostly for testing, check at runtime whether +the null-co + JSON way is possible, falling back to the creation of +thrown-away temporary files as before. + +(cherry picked from commit 1b6a2b221d04e455bdd31cff09015f74487882c1) +--- + v2v/output_null.ml | 66 ++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 55 insertions(+), 11 deletions(-) + +diff --git a/v2v/output_null.ml b/v2v/output_null.ml +index b93d53dc5..228c0b631 100644 +--- a/v2v/output_null.ml ++++ b/v2v/output_null.ml +@@ -40,9 +40,45 @@ open Utils + * too small, so we have to set the size. We could set it to + * match the input size but it's easier to set it to some huge + * size instead. ++ * ++ * In case neither the null-co driver nor the JSON syntax for URLs ++ * is supported, fall back by writing the disks to a temporary ++ * directory removed at exit. + *) + ++let can_use_qemu_null_co_device () = ++ (* We actually attempt to convert a raw file to the null-co device ++ * using a JSON URL. ++ *) ++ let tmp = Filename.temp_file "v2vqemunullcotst" ".img" in ++ Unix.truncate tmp 1024; ++ ++ let json = [ ++ "file.driver", JSON.String "null-co"; ++ "file.size", JSON.String "1E"; ++ ] in ++ ++ let cmd = ++ sprintf "qemu-img convert -n -f raw -O raw %s json:%s >/dev/null%s" ++ (quote tmp) ++ (quote (JSON.string_of_doc ~fmt:JSON.Compact json)) ++ (if verbose () then "" else " 2>&1") in ++ debug "%s" cmd; ++ let r = 0 = Sys.command cmd in ++ Unix.unlink tmp; ++ debug "qemu-img supports the null-co device: %b" r; ++ r ++ + class output_null = ++ (* Create a temporary directory which is always deleted at exit, ++ * so we can put the drives there in case qemu does not support ++ * 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 ++ rmdir_on_exit t; ++ t in + object + inherit output + +@@ -51,19 +87,27 @@ object + method supported_firmware = [ TargetBIOS; TargetUEFI ] + + method prepare_targets source targets = +- let json_params = [ +- "file.driver", JSON.String "null-co"; +- "file.size", JSON.String "1E"; +- ] in +- let target_file = TargetURI ("json:" ^ JSON.string_of_doc json_params) in ++ if can_use_qemu_null_co_device () then ( ++ let json_params = [ ++ "file.driver", JSON.String "null-co"; ++ "file.size", JSON.String "1E"; ++ ] in ++ let target_file = TargetURI ("json:" ^ JSON.string_of_doc json_params) in + +- (* While it's not intended that output drivers can set the +- * target_format field (thus overriding the -of option), in +- * this special case of -o null it is reasonable. +- *) +- let target_format = "raw" in ++ (* While it's not intended that output drivers can set the ++ * target_format field (thus overriding the -of option), in ++ * this special case of -o null it is reasonable. ++ *) ++ let target_format = "raw" in + +- List.map (fun t -> { t with target_file; target_format }) targets ++ List.map (fun t -> { t with target_file; target_format }) targets ++ ) else ( ++ List.map ( ++ fun t -> ++ let target_file = tmpdir // t.target_overlay.ov_sd in ++ { t with target_file = TargetFile target_file } ++ ) targets ++ ) + + method create_metadata _ _ _ _ _ _ = () + end +-- +2.17.1 + diff --git a/SOURCES/0030-v2v-Implement-i-vmx-to-read-VMware-vmx-files-directl.patch b/SOURCES/0030-v2v-Implement-i-vmx-to-read-VMware-vmx-files-directl.patch deleted file mode 100644 index 643a430..0000000 --- a/SOURCES/0030-v2v-Implement-i-vmx-to-read-VMware-vmx-files-directl.patch +++ /dev/null @@ -1,1942 +0,0 @@ -From e43fe85f28ba6fb184e6894db019668f0515c38d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 10 Apr 2017 15:24:26 +0100 -Subject: [PATCH] v2v: Implement -i vmx to read VMware vmx files directly - (RHBZ#1441197). - -This is a mostly complete implementation of a VMX parser and input -class for virt-v2v. It parses the name, memory size, CPU topology, -firmware, video, sound, hard disks, removable disks and network -interfaces from the VMX file. It only omits support for floppies and -SCSI CD-ROMs. - -The input class is split into two major parts: a generic VMX file -parser (Parse_vmx), and the Input_vmx module which translates the VMX -tree into the source device model. - -This also contains tests. There are simple unit tests of the -Parse_vmx module, and also some more complete parsing tests taken from -real guests. - -(cherry picked from commit ca40078cdda9167d4658ddfe24c828c7ee76be37) ---- - v2v/Makefile.am | 15 ++ - v2v/cmdline.ml | 12 +- - v2v/input_vmx.ml | 349 ++++++++++++++++++++++++++++++++++++++ - v2v/input_vmx.mli | 22 +++ - v2v/name_from_disk.ml | 2 +- - v2v/parse_vmx.ml | 381 ++++++++++++++++++++++++++++++++++++++++++ - v2v/parse_vmx.mli | 89 ++++++++++ - v2v/test-v2v-i-vmx-1.expected | 39 +++++ - v2v/test-v2v-i-vmx-1.vmx | 172 +++++++++++++++++++ - v2v/test-v2v-i-vmx-2.expected | 19 +++ - v2v/test-v2v-i-vmx-2.vmx | 84 ++++++++++ - v2v/test-v2v-i-vmx-3.expected | 19 +++ - v2v/test-v2v-i-vmx-3.vmx | 91 ++++++++++ - v2v/test-v2v-i-vmx-4.expected | 19 +++ - v2v/test-v2v-i-vmx-4.vmx | 88 ++++++++++ - v2v/test-v2v-i-vmx.sh | 48 ++++++ - v2v/v2v_unit_tests.ml | 143 ++++++++++++++++ - v2v/virt-v2v.pod | 72 +++++++- - 18 files changed, 1655 insertions(+), 9 deletions(-) - create mode 100644 v2v/input_vmx.ml - create mode 100644 v2v/input_vmx.mli - create mode 100644 v2v/parse_vmx.ml - create mode 100644 v2v/parse_vmx.mli - create mode 100644 v2v/test-v2v-i-vmx-1.expected - create mode 100644 v2v/test-v2v-i-vmx-1.vmx - create mode 100644 v2v/test-v2v-i-vmx-2.expected - create mode 100644 v2v/test-v2v-i-vmx-2.vmx - create mode 100644 v2v/test-v2v-i-vmx-3.expected - create mode 100644 v2v/test-v2v-i-vmx-3.vmx - create mode 100644 v2v/test-v2v-i-vmx-4.expected - create mode 100644 v2v/test-v2v-i-vmx-4.vmx - create mode 100755 v2v/test-v2v-i-vmx.sh - -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index 297406496..0df759eca 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -38,6 +38,7 @@ SOURCES_MLI = \ - input_libvirt_xen_ssh.mli \ - input_libvirtxml.mli \ - input_ova.mli \ -+ input_vmx.mli \ - inspect_source.mli \ - libvirt_utils.mli \ - linux.mli \ -@@ -55,6 +56,7 @@ SOURCES_MLI = \ - OVF.mli \ - parse_ovf_from_ova.mli \ - parse_libvirt_xml.mli \ -+ parse_vmx.mli \ - qemu_command.mli \ - target_bus_assignment.mli \ - types.mli \ -@@ -80,6 +82,7 @@ SOURCES_ML = \ - windows_virtio.ml \ - modules_list.ml \ - input_disk.ml \ -+ parse_vmx.ml \ - parse_libvirt_xml.ml \ - create_libvirt_xml.ml \ - qemu_command.ml \ -@@ -89,6 +92,7 @@ SOURCES_ML = \ - input_libvirt_xen_ssh.ml \ - input_libvirt.ml \ - input_ova.ml \ -+ input_vmx.ml \ - linux_bootloaders.ml \ - linux_kernels.ml \ - convert_linux.ml \ -@@ -268,6 +272,7 @@ TESTS = \ - test-v2v-i-ova-subfolders.sh \ - test-v2v-i-ova-tar.sh \ - test-v2v-i-ova-two-disks.sh \ -+ test-v2v-i-vmx.sh \ - test-v2v-bad-networks-and-bridges.sh - - if HAVE_LIBVIRT -@@ -411,6 +416,15 @@ EXTRA_DIST += \ - test-v2v-i-ova.ovf \ - test-v2v-i-ova.sh \ - test-v2v-i-ova.xml \ -+ test-v2v-i-vmx.sh \ -+ test-v2v-i-vmx-1.expected \ -+ test-v2v-i-vmx-2.expected \ -+ test-v2v-i-vmx-3.expected \ -+ test-v2v-i-vmx-4.expected \ -+ test-v2v-i-vmx-1.vmx \ -+ test-v2v-i-vmx-2.vmx \ -+ test-v2v-i-vmx-3.vmx \ -+ test-v2v-i-vmx-4.vmx \ - test-v2v-machine-readable.sh \ - test-v2v-networks-and-bridges-expected.xml \ - test-v2v-networks-and-bridges.sh \ -@@ -450,6 +464,7 @@ v2v_unit_tests_BOBJECTS = \ - windows.cmo \ - windows_virtio.cmo \ - linux.cmo \ -+ parse_vmx.cmo \ - v2v_unit_tests.cmo - v2v_unit_tests_XOBJECTS = $(v2v_unit_tests_BOBJECTS:.cmo=.cmx) - -diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml -index 3e3d5c312..db2346a38 100644 ---- a/v2v/cmdline.ml -+++ b/v2v/cmdline.ml -@@ -86,6 +86,7 @@ let parse_cmdline () = - | "libvirt" -> input_mode := `Libvirt - | "libvirtxml" -> input_mode := `LibvirtXML - | "ova" -> input_mode := `OVA -+ | "vmx" -> input_mode := `VMX - | s -> - error (f_"unknown -i option: %s") s - in -@@ -333,7 +334,16 @@ read the man page virt-v2v(1). - | [filename] -> filename - | _ -> - error (f_"expecting an OVA file name on the command line") in -- Input_ova.input_ova filename in -+ Input_ova.input_ova filename -+ -+ | `VMX -> -+ (* -i vmx: Expecting an vmx filename. *) -+ let filename = -+ match args with -+ | [filename] -> filename -+ | _ -> -+ error (f_"expecting a VMX file name on the command line") in -+ Input_vmx.input_vmx filename in - - (* Prevent use of --in-place option in RHEL. *) - if in_place then -diff --git a/v2v/input_vmx.ml b/v2v/input_vmx.ml -new file mode 100644 -index 000000000..bb09f0bf8 ---- /dev/null -+++ b/v2v/input_vmx.ml -@@ -0,0 +1,349 @@ -+(* virt-v2v -+ * Copyright (C) 2017 Red Hat Inc. -+ * -+ * 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. -+ *) -+ -+open Printf -+open Scanf -+ -+open Common_gettext.Gettext -+open Common_utils -+ -+open Types -+open Utils -+open Name_from_disk -+ -+external identity : 'a -> 'a = "%identity" -+ -+let rec find_disks vmx vmx_filename = -+ find_scsi_disks vmx vmx_filename @ find_ide_disks vmx vmx_filename -+ -+(* Find all SCSI hard disks. -+ * -+ * In the VMX file: -+ * scsi0.virtualDev = "pvscsi" # or may be "lsilogic" etc. -+ * scsi0:0.deviceType = "scsi-hardDisk" -+ * scsi0:0.fileName = "guest.vmdk" -+ *) -+and find_scsi_disks vmx vmx_filename = -+ let get_scsi_controller_target ns = -+ sscanf ns "scsi%d:%d" (fun c t -> c, t) -+ in -+ let is_scsi_controller_target ns = -+ try ignore (get_scsi_controller_target ns); true -+ with Scanf.Scan_failure _ | End_of_file | Failure _ -> false -+ in -+ let scsi_device_types = [ "scsi-harddisk" ] in -+ let scsi_controller = Source_SCSI in -+ -+ find_hdds vmx vmx_filename -+ get_scsi_controller_target is_scsi_controller_target -+ scsi_device_types scsi_controller -+ -+(* Find all IDE hard disks. -+ * -+ * In the VMX file: -+ * ide0:0.deviceType = "ata-hardDisk" -+ * ide0:0.fileName = "guest.vmdk" -+ *) -+and find_ide_disks vmx vmx_filename = -+ let get_ide_controller_target ns = -+ sscanf ns "ide%d:%d" (fun c t -> c, t) -+ in -+ let is_ide_controller_target ns = -+ try ignore (get_ide_controller_target ns); true -+ with Scanf.Scan_failure _ | End_of_file | Failure _ -> false -+ in -+ let ide_device_types = [ "ata-harddisk" ] in -+ let ide_controller = Source_IDE in -+ -+ find_hdds vmx vmx_filename -+ get_ide_controller_target is_ide_controller_target -+ ide_device_types ide_controller -+ -+and find_hdds vmx vmx_filename -+ get_controller_target is_controller_target -+ device_types controller = -+ (* Find namespaces matching '(ide|scsi)X:Y' with suitable deviceType. *) -+ let hdds = -+ Parse_vmx.select_namespaces ( -+ function -+ | [ns] -> -+ (* Check the namespace is '(ide|scsi)X:Y' *) -+ if not (is_controller_target ns) then false -+ else ( -+ (* Check the deviceType is one we are looking for. *) -+ match Parse_vmx.get_string vmx [ns; "deviceType"] with -+ | Some str -> -+ let str = String.lowercase_ascii str in -+ List.mem str device_types -+ | None -> false -+ ) -+ | _ -> false -+ ) vmx in -+ -+ (* Map the subset to a list of disks. *) -+ let hdds = -+ Parse_vmx.map ( -+ fun path v -> -+ match path, v with -+ | [ns; "filename"], Some filename -> -+ let c, t = get_controller_target ns in -+ let s = { s_disk_id = (-1); -+ s_qemu_uri = qemu_uri_of_filename vmx_filename filename; -+ s_format = Some "vmdk"; -+ s_controller = Some controller } in -+ Some (c, t, s) -+ | _ -> None -+ ) hdds in -+ let hdds = filter_map identity hdds in -+ -+ (* We don't have a way to return the controllers and targets, so -+ * just make sure the disks are sorted into order, since Parse_vmx -+ * won't return them in any particular order. -+ *) -+ let hdds = List.sort compare hdds in -+ let hdds = List.map (fun (_, _, source) -> source) hdds in -+ -+ (* Set the s_disk_id field to an incrementing number. *) -+ let hdds = mapi (fun i source -> { source with s_disk_id = i }) hdds in -+ -+ hdds -+ -+(* The filename can be an absolute path, but is more often a -+ * path relative to the location of the vmx file. -+ * -+ * Note that we always end up with an absolute path, which is -+ * also useful because it means we won't have any paths that -+ * could be misinterpreted by qemu. -+ *) -+and qemu_uri_of_filename vmx_filename filename = -+ if not (Filename.is_relative filename) then -+ filename -+ else ( -+ let dir = Filename.dirname (absolute_path vmx_filename) in -+ dir // filename -+ ) -+ -+(* Find all removable disks. -+ * -+ * In the VMX file: -+ * ide1:0.deviceType = "cdrom-image" -+ * ide1:0.fileName = "boot.iso" -+ * -+ * XXX This only supports IDE CD-ROMs, but we could support SCSI -+ * CD-ROMs and floppies in future. -+ *) -+and find_removables vmx = -+ let get_ide_controller_target ns = -+ sscanf ns "ide%d:%d" (fun c t -> c, t) -+ in -+ let is_ide_controller_target ns = -+ try ignore (get_ide_controller_target ns); true -+ with Scanf.Scan_failure _ | End_of_file | Failure _ -> false -+ in -+ let device_types = [ "atapi-cdrom"; -+ "cdrom-image"; "cdrom-raw" ] in -+ -+ (* Find namespaces matching 'ideX:Y' with suitable deviceType. *) -+ let devs = -+ Parse_vmx.select_namespaces ( -+ function -+ | [ns] -> -+ (* Check the namespace is 'ideX:Y' *) -+ if not (is_ide_controller_target ns) then false -+ else ( -+ (* Check the deviceType is one we are looking for. *) -+ match Parse_vmx.get_string vmx [ns; "deviceType"] with -+ | Some str -> -+ let str = String.lowercase_ascii str in -+ List.mem str device_types -+ | None -> false -+ ) -+ | _ -> false -+ ) vmx in -+ -+ (* Map the subset to a list of CD-ROMs. *) -+ let devs = -+ Parse_vmx.map ( -+ fun path v -> -+ match path, v with -+ | [ns], None -> -+ let c, t = get_ide_controller_target ns in -+ let s = { s_removable_type = CDROM; -+ s_removable_controller = Some Source_IDE; -+ s_removable_slot = Some (ide_slot c t) } in -+ Some s -+ | _ -> None -+ ) devs in -+ let devs = filter_map identity devs in -+ -+ (* Sort by slot. *) -+ let devs = -+ List.sort -+ (fun { s_removable_slot = s1 } { s_removable_slot = s2 } -> -+ compare s1 s2) -+ devs in -+ -+ devs -+ -+and ide_slot c t = -+ (* Assuming the old master/slave arrangement. *) -+ c * 2 + t -+ -+(* Find all ethernet cards. -+ * -+ * In the VMX file: -+ * ethernet0.virtualDev = "vmxnet3" -+ * ethernet0.networkName = "VM Network" -+ * ethernet0.generatedAddress = "00:01:02:03:04:05" -+ * ethernet0.connectionType = "bridged" # also: "custom", "nat" or not present -+ *) -+and find_nics vmx = -+ let get_ethernet_port ns = -+ sscanf ns "ethernet%d" (fun p -> p) -+ in -+ let is_ethernet_port ns = -+ try ignore (get_ethernet_port ns); true -+ with Scanf.Scan_failure _ | End_of_file | Failure _ -> false -+ in -+ -+ (* Find namespaces matching 'ethernetX'. *) -+ let nics = -+ Parse_vmx.select_namespaces ( -+ function -+ | [ns] -> is_ethernet_port ns -+ | _ -> false -+ ) vmx in -+ -+ (* Map the subset to a list of NICs. *) -+ let nics = -+ Parse_vmx.map ( -+ fun path v -> -+ match path, v with -+ | [ns], None -> -+ let port = get_ethernet_port ns in -+ let mac = Parse_vmx.get_string vmx [ns; "generatedAddress"] in -+ let model = Parse_vmx.get_string vmx [ns; "virtualDev"] in -+ let model = -+ match model with -+ | Some m when String.lowercase_ascii m = "e1000" -> -+ Some Source_e1000 -+ | Some model -> -+ Some (Source_other_nic (String.lowercase_ascii model)) -+ | None -> None in -+ let vnet = Parse_vmx.get_string vmx [ns; "networkName"] in -+ let vnet = -+ match vnet with -+ | Some vnet -> vnet -+ | None -> ns (* "ethernetX" *) in -+ let vnet_type = -+ match Parse_vmx.get_string vmx [ns; "connectionType"] with -+ | Some b when String.lowercase_ascii b = "bridged" -> -+ Bridge -+ | Some _ | None -> Network in -+ Some (port, -+ { s_mac = mac; s_nic_model = model; -+ s_vnet = vnet; s_vnet_orig = vnet; -+ s_vnet_type = vnet_type }) -+ | _ -> None -+ ) nics in -+ let nics = filter_map identity nics in -+ -+ (* Sort by port. *) -+ let nics = List.sort compare nics in -+ -+ let nics = List.map (fun (_, source) -> source) nics in -+ nics -+ -+class input_vmx vmx_filename = object -+ inherit input -+ -+ method as_options = "-i vmx " ^ vmx_filename -+ -+ method source () = -+ (* Parse the VMX file. *) -+ let vmx = Parse_vmx.parse_file vmx_filename in -+ -+ let name = -+ match Parse_vmx.get_string vmx ["displayName"] with -+ | None -> -+ warning (f_"no displayName key found in VMX file"); -+ name_from_disk vmx_filename -+ | Some s -> s in -+ -+ let memory_mb = -+ match Parse_vmx.get_int64 vmx ["memSize"] with -+ | None -> 32_L (* default is really 32 MB! *) -+ | Some i -> i in -+ let memory = memory_mb *^ 1024L *^ 1024L in -+ -+ let vcpu = -+ match Parse_vmx.get_int vmx ["numvcpus"] with -+ | None -> 1 -+ | Some i -> i in -+ -+ let firmware = -+ match Parse_vmx.get_string vmx ["firmware"] with -+ | None -> BIOS -+ | Some "efi" -> UEFI -+ (* Other values are not documented for this field ... *) -+ | Some fw -> -+ warning (f_"unknown firmware value '%s', assuming BIOS") fw; -+ BIOS in -+ -+ let video = -+ if Parse_vmx.namespace_present vmx ["svga"] then -+ (* We could also parse svga.vramSize. *) -+ Some (Source_other_video "vmvga") -+ else -+ None in -+ -+ let sound = -+ match Parse_vmx.get_string vmx ["sound"; "virtualDev"] with -+ | Some ("sb16") -> Some { s_sound_model = SB16 } -+ | Some ("es1371") -> Some { s_sound_model = ES1370 (* hmmm ... *) } -+ | Some "hdaudio" -> Some { s_sound_model = ICH6 (* intel-hda *) } -+ | Some model -> -+ warning (f_"unknown sound device '%s' ignored") model; -+ None -+ | None -> None in -+ -+ let disks = find_disks vmx vmx_filename in -+ let removables = find_removables vmx in -+ let nics = find_nics vmx in -+ -+ let source = { -+ s_hypervisor = VMware; -+ s_name = name; -+ s_orig_name = name; -+ s_memory = memory; -+ s_vcpu = vcpu; -+ s_features = []; -+ s_firmware = firmware; -+ s_display = None; -+ s_video = video; -+ s_sound = sound; -+ s_disks = disks; -+ s_removables = removables; -+ s_nics = nics; -+ } in -+ -+ source -+end -+ -+let input_vmx = new input_vmx -+let () = Modules_list.register_input_module "vmx" -diff --git a/v2v/input_vmx.mli b/v2v/input_vmx.mli -new file mode 100644 -index 000000000..f236f8716 ---- /dev/null -+++ b/v2v/input_vmx.mli -@@ -0,0 +1,22 @@ -+(* virt-v2v -+ * Copyright (C) 2017 Red Hat Inc. -+ * -+ * 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. -+ *) -+ -+(** [-i vmx] source. *) -+ -+val input_vmx : string -> Types.input -+(** [input_vmx filename] sets up an input from vmware vmx file. *) -diff --git a/v2v/name_from_disk.ml b/v2v/name_from_disk.ml -index 82f09250a..452d9462c 100644 ---- a/v2v/name_from_disk.ml -+++ b/v2v/name_from_disk.ml -@@ -24,7 +24,7 @@ let name_from_disk disk = - (* Remove the extension (or suffix), only if it's one usually - * used for disk images. *) - let suffixes = [ -- ".img"; ".ova"; ".qcow2"; ".raw"; ".vmdk"; -+ ".img"; ".ova"; ".qcow2"; ".raw"; ".vmdk"; ".vmx"; - "-sda"; - ] in - let rec loop = function -diff --git a/v2v/parse_vmx.ml b/v2v/parse_vmx.ml -new file mode 100644 -index 000000000..33ec17d3d ---- /dev/null -+++ b/v2v/parse_vmx.ml -@@ -0,0 +1,381 @@ -+(* virt-v2v -+ * Copyright (C) 2017 Red Hat Inc. -+ * -+ * 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. -+ *) -+ -+open Printf -+ -+open Common_utils -+open Common_gettext.Gettext -+ -+(* As far as I can tell the VMX format is totally unspecified. -+ * However libvirt has a useful selection of .vmx files in the -+ * sources which explore some of the darker regions of this -+ * format. -+ * -+ * So here are some facts about VMX derived from libvirt and -+ * other places: -+ * -+ * - Keys are compared case insensitively. We assume here -+ * that keys are 7-bit ASCII. -+ * -+ * - Multiple keys with the same name are not allowed. -+ * -+ * - Escaping in the value string is possible using a very weird -+ * escape format: "|22" means the character '\x22'. To write -+ * a pipe character you must use "|7C". -+ * -+ * - Boolean values are written "TRUE", "FALSE", "True", "true", etc. -+ * Because of the quotes they cannot be distinguished from strings. -+ * -+ * - Comments (#...) and blank lines are ignored. Some files start -+ * with a hash-bang path, but we ignore those as comments. This -+ * parser also ignores any other line which it doesn't understand, -+ * but will print a warning. -+ * -+ * - Multi-line values are not permitted. -+ * -+ * - Keys are namespaced using dots, eg. scsi0:0.deviceType has -+ * the namespace "scsi0:0" and the key name "deviceType". -+ * -+ * - Using namespace.present = "FALSE" means that all other keys -+ * in and under the namespace are ignored. -+ * -+ * - You cannot have a namespace and a key with the same name, eg. -+ * this is not allowed: -+ * namespace = "some value" -+ * namespace.foo = "another value" -+ * -+ * - The Hashicorp packer VMX writer considers some special keys -+ * as not requiring any quotes around their values, but I'm -+ * ignoring that for now. -+ *) -+ -+(* This VMX file: -+ * -+ * foo.a = "abc" -+ * foo.b = "def" -+ * foo.bar.c = "abc" -+ * foo.bar.d = "def" -+ * -+ * would be represented by this structure: -+ * -+ * "foo" => Namespace ( # "foo" is a namespace -+ * "a" => Key "abc"; # "foo.a" is a key with value "abc" -+ * "b" => Key "def"; -+ * "bar" => Namespace ( # "foo.bar" is another namespace -+ * "c" => Key "abc"; -+ * "d" => Key "def"; -+ * ) -+ * ) -+ * ‘( => )’s represent the StringMap type. -+ *) -+type t = key StringMap.t -+ -+and key = -+ | Key of string -+ | Namespace of t -+ -+let empty = StringMap.empty -+ -+(* Compare two trees for equality. *) -+let rec equal vmx1 vmx2 = -+ let cmp k1 k2 = -+ match k1, k2 with -+ | Key v1, Key v2 -> v1 = v2 -+ | Key _, Namespace _ -> false -+ | Namespace _, Key _ -> false -+ | Namespace vmx1, Namespace vmx2 -> equal vmx1 vmx2 -+ in -+ StringMap.equal cmp vmx1 vmx2 -+ -+(* Higher-order functions. *) -+let rec select_namespaces pred vmx = -+ _select_namespaces [] pred vmx -+ -+and _select_namespaces path pred vmx = -+ StringMap.fold ( -+ fun k v new_vmx -> -+ let path = path @ [k] in -+ match v with -+ | Key _ -> new_vmx -+ | Namespace _ when pred path -> -+ StringMap.add k v new_vmx -+ | Namespace t -> -+ let t = _select_namespaces path pred t in -+ if not (equal t empty) then -+ StringMap.add k (Namespace t) new_vmx -+ else -+ new_vmx -+ ) vmx empty -+ -+let rec map f vmx = -+ _map [] f vmx -+ -+and _map path f vmx = -+ StringMap.fold ( -+ fun k v r -> -+ let path = path @ [k] in -+ match v with -+ | Key v -> r @ [ f path (Some v) ] -+ | Namespace t -> r @ [ f path None ] @ _map path f t -+ ) vmx [] -+ -+let rec namespace_present vmx = function -+ | [] -> false -+ | [ns] -> -+ let ns = String.lowercase_ascii ns in -+ (try -+ let v = StringMap.find ns vmx in -+ match v with -+ | Key _ -> false -+ | Namespace _ -> true -+ with -+ Not_found -> false -+ ) -+ | ns :: path -> -+ let ns = String.lowercase_ascii ns in -+ (try -+ let v = StringMap.find ns vmx in -+ match v with -+ | Key _ -> false -+ | Namespace vmx -> namespace_present vmx path -+ with -+ Not_found -> false -+ ) -+ -+(* Dump the vmx structure to [chan]. Used for debugging. *) -+let rec print chan indent vmx = -+ StringMap.iter (print_key chan indent) vmx -+ -+and print_key chan indent k = function -+ | Key v -> -+ output_spaces chan indent; -+ fprintf chan "%s = \"%s\"\n" k v -+ | Namespace vmx -> -+ output_spaces chan indent; -+ fprintf chan "namespace '%s':\n" k; -+ print chan (indent+4) vmx -+ -+(* As above, but creates a string instead. *) -+let rec to_string indent vmx = -+ StringMap.fold (fun k v str -> str ^ to_string_key indent k v) vmx "" -+ -+and to_string_key indent k = function -+ | Key v -> -+ String.spaces indent ^ sprintf "%s = \"%s\"\n" k v -+ | Namespace vmx -> -+ String.spaces indent ^ sprintf "namespace '%s':\n" k ^ -+ to_string (indent+4) vmx -+ -+(* Access keys in the tree. *) -+let rec get_string vmx = function -+ | [] -> None -+ | [k] -> -+ let k = String.lowercase_ascii k in -+ (try -+ let v = StringMap.find k vmx in -+ match v with -+ | Key v -> Some v -+ | Namespace _ -> None -+ with Not_found -> None -+ ) -+ | ns :: path -> -+ let ns = String.lowercase_ascii ns in -+ (try -+ let v = StringMap.find ns vmx in -+ match v with -+ | Key v -> None -+ | Namespace vmx -> get_string vmx path -+ with -+ Not_found -> None -+ ) -+ -+let get_int64 vmx path = -+ match get_string vmx path with -+ | None -> None -+ | Some i -> Some (Int64.of_string i) -+ -+let get_int vmx path = -+ match get_string vmx path with -+ | None -> None -+ | Some i -> Some (int_of_string i) -+ -+let rec get_bool vmx path = -+ match get_string vmx path with -+ | None -> None -+ | Some t -> Some (vmx_bool_of_string t) -+ -+and vmx_bool_of_string t = -+ if String.lowercase_ascii t = "true" then true -+ else if String.lowercase_ascii t = "false" then false -+ else failwith "bool_of_string" -+ -+(* Regular expression used to match key = "value" in VMX file. *) -+let rex = Str.regexp "^\\([^ \t=]+\\)[ \t]*=[ \t]*\"\\(.*\\)\"$" -+ -+(* Remove the weird escapes used in value strings. See description above. *) -+let remove_vmx_escapes str = -+ let len = String.length str in -+ let out = Bytes.make len '\000' in -+ let j = ref 0 in -+ -+ let rec loop i = -+ if i >= len then () -+ else ( -+ let c = String.unsafe_get str i in -+ if i <= len-3 && c = '|' then ( -+ let c1 = str.[i+1] and c2 = str.[i+2] in -+ if Char.isxdigit c1 && Char.isxdigit c2 then ( -+ let x = Char.hexdigit c1 * 0x10 + Char.hexdigit c2 in -+ Bytes.set out !j (Char.chr x); -+ incr j; -+ loop (i+3) -+ ) -+ else ( -+ Bytes.set out !j c; -+ incr j; -+ loop (i+1) -+ ) -+ ) -+ else ( -+ Bytes.set out !j c; -+ incr j; -+ loop (i+1) -+ ) -+ ) -+ in -+ loop 0; -+ -+ (* Truncate the output string to its real size and return it -+ * as an immutable string. -+ *) -+ Bytes.sub_string out 0 !j -+ -+(* Parsing. *) -+let rec parse_file vmx_filename = -+ (* Read the whole file as a list of lines. *) -+ let str = read_whole_file vmx_filename in -+ if verbose () then eprintf "VMX file:\n%s\n" str; -+ parse_string str -+ -+and parse_string str = -+ let lines = String.nsplit "\n" str in -+ -+ (* I've never seen any VMX file with CR-LF endings, and VMware -+ * itself is Linux-based, but to be on the safe side ... -+ *) -+ let lines = List.map (String.trimr ~test:((=) '\r')) lines in -+ -+ (* Ignore blank lines and comments. *) -+ let lines = List.filter ( -+ fun line -> -+ let line = String.triml line in -+ let len = String.length line in -+ len > 0 && line.[0] != '#' -+ ) lines in -+ -+ (* Parse the lines into key = "value". *) -+ let lines = filter_map ( -+ fun line -> -+ if Str.string_match rex line 0 then ( -+ let key = Str.matched_group 1 line in -+ let key = String.lowercase_ascii key in -+ let value = Str.matched_group 2 line in -+ let value = remove_vmx_escapes value in -+ Some (key, value) -+ ) -+ else ( -+ warning (f_"vmx parser: cannot parse this line, ignoring: %s") line; -+ None -+ ) -+ ) lines in -+ -+ (* Split the keys into namespace paths. *) -+ let lines = -+ List.map (fun (key, value) -> String.nsplit "." key, value) lines in -+ -+ (* Build a tree from the flat list and return it. This is horribly -+ * inefficient, at least O(n²), possibly even O(n².log n). Hope -+ * there are no large VMX files! (XXX) -+ *) -+ let vmx = -+ List.fold_left ( -+ fun vmx (path, value) -> insert vmx value path -+ ) empty lines in -+ -+ (* If we're verbose, dump the parsed VMX for debugging purposes. *) -+ if verbose () then ( -+ eprintf "parsed VMX tree:\n"; -+ print stderr 0 vmx -+ ); -+ -+ (* Drop all present = "FALSE" namespaces. *) -+ let vmx = drop_not_present vmx in -+ -+ vmx -+ -+and insert vmx value = function -+ | [] -> assert false -+ | [k] -> -+ if StringMap.mem k vmx then ( -+ warning (f_"vmx parser: duplicate key '%s' ignored") k; -+ vmx -+ ) else -+ StringMap.add k (Key value) vmx -+ | ns :: path -> -+ let v = -+ try -+ (match StringMap.find ns vmx with -+ | Namespace vmx -> Some vmx -+ | Key _ -> None -+ ) -+ with Not_found -> None in -+ let v = -+ match v with -+ | None -> -+ (* Completely new namespace. *) -+ insert empty value path -+ | Some v -> -+ (* Insert the subkey into the previously created namespace. *) -+ insert v value path in -+ StringMap.add ns (Namespace v) vmx -+ -+(* Find any "present" keys. If we find present = "FALSE", then -+ * drop the containing namespace and all subkeys and subnamespaces. -+ *) -+and drop_not_present vmx = -+ StringMap.fold ( -+ fun k v new_vmx -> -+ match v with -+ | Key _ -> -+ StringMap.add k v new_vmx -+ | Namespace vmx when contains_key_present_false vmx -> -+ (* drop this namespace and all sub-spaces *) -+ new_vmx -+ | Namespace v -> -+ (* recurse into sub-namespace and do the same check *) -+ let v = drop_not_present v in -+ StringMap.add k (Namespace v) new_vmx -+ ) vmx empty -+ -+and contains_key_present_false vmx = -+ try -+ match StringMap.find "present" vmx with -+ | Key v when vmx_bool_of_string v = false -> true -+ | Key _ | Namespace _ -> false -+ with -+ Failure _ | Not_found -> false -diff --git a/v2v/parse_vmx.mli b/v2v/parse_vmx.mli -new file mode 100644 -index 000000000..0e4f21f07 ---- /dev/null -+++ b/v2v/parse_vmx.mli -@@ -0,0 +1,89 @@ -+(* virt-v2v -+ * Copyright (C) 2017 Red Hat Inc. -+ * -+ * 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. -+ *) -+ -+(** A simple parser for VMware [.vmx] files. *) -+ -+type t -+ -+val parse_file : string -> t -+(** [parse_file filename] parses a VMX file. *) -+ -+val parse_string : string -> t -+(** [parse_string s] parses VMX from a string. *) -+ -+val get_string : t -> string list -> string option -+(** Find a key and return it as a string. If not present, returns [None]. -+ -+ Note that if [namespace.present = "FALSE"] is found in the file -+ then all keys in [namespace] and below it are ignored. This -+ applies to all [get_*] functions. *) -+ -+val get_int64 : t -> string list -> int64 option -+(** Find a key and return it as an [int64]. -+ If not present, returns [None]. -+ -+ Raises [Failure _] if the key is present but was not parseable -+ as an integer. *) -+ -+val get_int : t -> string list -> int option -+(** Find a key and return it as an [int]. -+ If not present, returns [None]. -+ -+ Raises [Failure _] if the key is present but was not parseable -+ as an integer. *) -+ -+val get_bool : t -> string list -> bool option -+(** Find a key and return it as a boolean. -+ -+ You cannot return [namespace.present = "FALSE"] booleans this way. -+ They are processed by the parser and the namespace and anything -+ below it are removed from the tree. -+ -+ Raises [Failure _] if the key is present but was not parseable -+ as a boolean. *) -+ -+val namespace_present : t -> string list -> bool -+(** Returns true iff the namespace ({b note:} not key) is present. *) -+ -+val select_namespaces : (string list -> bool) -> t -> t -+(** Filter the VMX file, selecting exactly namespaces (and their -+ keys) matching the predicate. The predicate is a function which -+ is called on each {i namespace} path ({b note:} not on -+ namespace + key paths). If the predicate matches a -+ namespace, then all sub-namespaces under that namespace are -+ selected implicitly. *) -+ -+val map : (string list -> string option -> 'a) -> t -> 'a list -+(** Map all the entries in the VMX file into a list using the -+ map function. The map function takes two arguments. The -+ first is the path to the namespace or key, and the second -+ is the key value (or [None] if the path refers to a namespace). *) -+ -+val equal : t -> t -> bool -+(** Compare two VMX files for equality. This is mainly used for -+ testing the parser. *) -+ -+val empty : t -+(** An empty VMX file. *) -+ -+val print : out_channel -> int -> t -> unit -+(** [print chan indent] prints the VMX file to the output channel. -+ [indent] is the indentation applied to each line of output. *) -+ -+val to_string : int -> t -> string -+(** Same as {!print} but it creates a printable (multiline) string. *) -diff --git a/v2v/test-v2v-i-vmx-1.expected b/v2v/test-v2v-i-vmx-1.expected -new file mode 100644 -index 000000000..c7ef1f5d5 ---- /dev/null -+++ b/v2v/test-v2v-i-vmx-1.expected -@@ -0,0 +1,39 @@ -+[ 0.0] Opening the source -i vmx test-v2v-i-vmx-1.vmx -+Source guest information (--print-source option): -+ -+ source name: BZ1308535_21disks -+hypervisor type: vmware -+ memory: 2147483648 (bytes) -+ nr vCPUs: 1 -+ CPU features: -+ firmware: bios -+ display: -+ video: vmvga -+ sound: -+disks: -+ /BZ1308535_21disks.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_1.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_2.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_3.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_4.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_5.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_6.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_7.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_8.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_9.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_10.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_11.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_12.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_13.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_14.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_15.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_16.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_17.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_18.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_19.vmdk (vmdk) [scsi] -+ /BZ1308535_21disks_20.vmdk (vmdk) [scsi] -+removable media: -+ CD-ROM [ide] in slot 2 -+NICs: -+ Network "VM Network" mac: 00:0c:29:36:ef:31 [vmxnet3] -+ -diff --git a/v2v/test-v2v-i-vmx-1.vmx b/v2v/test-v2v-i-vmx-1.vmx -new file mode 100644 -index 000000000..3f2f060a5 ---- /dev/null -+++ b/v2v/test-v2v-i-vmx-1.vmx -@@ -0,0 +1,172 @@ -+.encoding = "UTF-8" -+config.version = "8" -+virtualHW.version = "8" -+nvram = "BZ1308535_21disks.nvram" -+pciBridge0.present = "TRUE" -+svga.present = "TRUE" -+pciBridge4.present = "TRUE" -+pciBridge4.virtualDev = "pcieRootPort" -+pciBridge4.functions = "8" -+pciBridge5.present = "TRUE" -+pciBridge5.virtualDev = "pcieRootPort" -+pciBridge5.functions = "8" -+pciBridge6.present = "TRUE" -+pciBridge6.virtualDev = "pcieRootPort" -+pciBridge6.functions = "8" -+pciBridge7.present = "TRUE" -+pciBridge7.virtualDev = "pcieRootPort" -+pciBridge7.functions = "8" -+vmci0.present = "TRUE" -+hpet0.present = "TRUE" -+displayName = "BZ1308535_21disks" -+extendedConfigFile = "BZ1308535_21disks.vmxf" -+virtualHW.productCompatibility = "hosted" -+memSize = "2048" -+sched.cpu.units = "mhz" -+powerType.powerOff = "soft" -+powerType.suspend = "hard" -+powerType.reset = "soft" -+scsi0.virtualDev = "pvscsi" -+scsi0.present = "TRUE" -+scsi1.virtualDev = "pvscsi" -+scsi1.present = "TRUE" -+ide1:0.deviceType = "cdrom-image" -+ide1:0.fileName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/ISOs/RHEL-7.1-20150219.1-Server-x86_64-boot.iso" -+ide1:0.present = "TRUE" -+floppy0.startConnected = "FALSE" -+floppy0.clientDevice = "TRUE" -+floppy0.fileName = "vmware-null-remote-floppy" -+ethernet0.virtualDev = "vmxnet3" -+ethernet0.networkName = "VM Network" -+ethernet0.addressType = "generated" -+ethernet0.present = "TRUE" -+scsi0:0.deviceType = "scsi-hardDisk" -+scsi0:0.fileName = "BZ1308535_21disks.vmdk" -+scsi0:0.present = "TRUE" -+scsi0:1.deviceType = "scsi-hardDisk" -+scsi0:1.fileName = "BZ1308535_21disks_1.vmdk" -+scsi0:1.present = "TRUE" -+scsi0:2.deviceType = "scsi-hardDisk" -+scsi0:2.fileName = "BZ1308535_21disks_2.vmdk" -+scsi0:2.present = "TRUE" -+scsi0:3.deviceType = "scsi-hardDisk" -+scsi0:3.fileName = "BZ1308535_21disks_3.vmdk" -+scsi0:3.present = "TRUE" -+scsi0:4.deviceType = "scsi-hardDisk" -+scsi0:4.fileName = "BZ1308535_21disks_4.vmdk" -+scsi0:4.present = "TRUE" -+scsi0:5.deviceType = "scsi-hardDisk" -+scsi0:5.fileName = "BZ1308535_21disks_5.vmdk" -+scsi0:5.present = "TRUE" -+scsi0:6.deviceType = "scsi-hardDisk" -+scsi0:6.fileName = "BZ1308535_21disks_6.vmdk" -+scsi0:6.present = "TRUE" -+scsi0:8.deviceType = "scsi-hardDisk" -+scsi0:8.fileName = "BZ1308535_21disks_7.vmdk" -+scsi0:8.present = "TRUE" -+scsi0:9.deviceType = "scsi-hardDisk" -+scsi0:9.fileName = "BZ1308535_21disks_8.vmdk" -+scsi0:9.present = "TRUE" -+scsi0:10.deviceType = "scsi-hardDisk" -+scsi0:10.fileName = "BZ1308535_21disks_9.vmdk" -+scsi0:10.present = "TRUE" -+scsi0:11.deviceType = "scsi-hardDisk" -+scsi0:11.fileName = "BZ1308535_21disks_10.vmdk" -+scsi0:11.present = "TRUE" -+scsi0:12.deviceType = "scsi-hardDisk" -+scsi0:12.fileName = "BZ1308535_21disks_11.vmdk" -+scsi0:12.present = "TRUE" -+scsi0:13.deviceType = "scsi-hardDisk" -+scsi0:13.fileName = "BZ1308535_21disks_12.vmdk" -+scsi0:13.present = "TRUE" -+scsi0:14.deviceType = "scsi-hardDisk" -+scsi0:14.fileName = "BZ1308535_21disks_13.vmdk" -+scsi0:14.present = "TRUE" -+scsi0:15.deviceType = "scsi-hardDisk" -+scsi0:15.fileName = "BZ1308535_21disks_14.vmdk" -+scsi0:15.present = "TRUE" -+scsi1:0.deviceType = "scsi-hardDisk" -+scsi1:0.fileName = "BZ1308535_21disks_15.vmdk" -+scsi1:0.present = "TRUE" -+scsi1:1.deviceType = "scsi-hardDisk" -+scsi1:1.fileName = "BZ1308535_21disks_16.vmdk" -+scsi1:1.present = "TRUE" -+scsi1:2.deviceType = "scsi-hardDisk" -+scsi1:2.fileName = "BZ1308535_21disks_17.vmdk" -+scsi1:2.present = "TRUE" -+scsi1:3.deviceType = "scsi-hardDisk" -+scsi1:3.fileName = "BZ1308535_21disks_18.vmdk" -+scsi1:3.present = "TRUE" -+scsi1:4.deviceType = "scsi-hardDisk" -+scsi1:4.fileName = "BZ1308535_21disks_19.vmdk" -+scsi1:4.present = "TRUE" -+scsi1:5.deviceType = "scsi-hardDisk" -+scsi1:5.fileName = "BZ1308535_21disks_20.vmdk" -+scsi1:5.present = "TRUE" -+guestOS = "rhel6-64" -+toolScripts.afterPowerOn = "TRUE" -+toolScripts.afterResume = "TRUE" -+toolScripts.beforeSuspend = "TRUE" -+toolScripts.beforePowerOff = "TRUE" -+uuid.bios = "56 4d 96 af e6 46 bd 86-5c 4d 65 4e 77 36 ef 31" -+uuid.location = "56 4d 96 af e6 46 bd 86-5c 4d 65 4e 77 36 ef 31" -+vc.uuid = "52 31 cb fc c1 3f 96 32-83 c0 bb 70 6c 90 5c fd" -+chipset.onlineStandby = "FALSE" -+sched.cpu.min = "0" -+sched.cpu.shares = "normal" -+sched.mem.min = "0" -+sched.mem.minSize = "0" -+sched.mem.shares = "normal" -+svga.vramSize = "8388608" -+sched.swap.derivedName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/BZ1308535_21disks/BZ1308535_21disks-6a024f8a.vswp" -+replay.supported = "FALSE" -+replay.filename = "" -+scsi0:0.redo = "" -+scsi0:1.redo = "" -+scsi0:2.redo = "" -+scsi0:3.redo = "" -+scsi0:4.redo = "" -+scsi0:5.redo = "" -+scsi0:6.redo = "" -+scsi0:8.redo = "" -+scsi0:9.redo = "" -+scsi0:10.redo = "" -+scsi0:11.redo = "" -+scsi0:12.redo = "" -+scsi0:13.redo = "" -+scsi0:14.redo = "" -+scsi0:15.redo = "" -+scsi1:0.redo = "" -+scsi1:1.redo = "" -+scsi1:2.redo = "" -+scsi1:3.redo = "" -+scsi1:4.redo = "" -+scsi1:5.redo = "" -+pciBridge0.pciSlotNumber = "17" -+pciBridge4.pciSlotNumber = "21" -+pciBridge5.pciSlotNumber = "22" -+pciBridge6.pciSlotNumber = "23" -+pciBridge7.pciSlotNumber = "24" -+scsi0.pciSlotNumber = "160" -+scsi1.pciSlotNumber = "192" -+ethernet0.pciSlotNumber = "224" -+vmci0.pciSlotNumber = "32" -+scsi0.sasWWID = "50 05 05 6f e6 46 bd 80" -+scsi1.sasWWID = "50 05 05 6f e6 46 bc 80" -+ethernet0.generatedAddress = "00:0c:29:36:ef:31" -+ethernet0.generatedAddressOffset = "0" -+vmci0.id = "2000088881" -+hostCPUID.0 = "0000000d756e65476c65746e49656e69" -+hostCPUID.1 = "000206a700100800179ae3bfbfebfbff" -+hostCPUID.80000001 = "00000000000000000000000128100800" -+guestCPUID.0 = "0000000d756e65476c65746e49656e69" -+guestCPUID.1 = "000206a700010800969822030fabfbff" -+guestCPUID.80000001 = "00000000000000000000000128100800" -+userCPUID.0 = "0000000d756e65476c65746e49656e69" -+userCPUID.1 = "000206a700100800169822030fabfbff" -+userCPUID.80000001 = "00000000000000000000000128100800" -+evcCompatibilityMode = "FALSE" -+vmotion.checkpointFBSize = "8388608" -+cleanShutdown = "TRUE" -+softPowerOff = "TRUE" -+tools.remindInstall = "TRUE" -diff --git a/v2v/test-v2v-i-vmx-2.expected b/v2v/test-v2v-i-vmx-2.expected -new file mode 100644 -index 000000000..a04bd0f62 ---- /dev/null -+++ b/v2v/test-v2v-i-vmx-2.expected -@@ -0,0 +1,19 @@ -+[ 0.0] Opening the source -i vmx test-v2v-i-vmx-2.vmx -+Source guest information (--print-source option): -+ -+ source name: Fedora 20 -+hypervisor type: vmware -+ memory: 2147483648 (bytes) -+ nr vCPUs: 1 -+ CPU features: -+ firmware: bios -+ display: -+ video: vmvga -+ sound: -+disks: -+ /Fedora 20.vmdk (vmdk) [scsi] -+removable media: -+ -+NICs: -+ Network "VM Network" mac: 00:50:56:9b:5f:0d [vmxnet3] -+ -diff --git a/v2v/test-v2v-i-vmx-2.vmx b/v2v/test-v2v-i-vmx-2.vmx -new file mode 100644 -index 000000000..d9dcf3a5c ---- /dev/null -+++ b/v2v/test-v2v-i-vmx-2.vmx -@@ -0,0 +1,84 @@ -+.encoding = "UTF-8" -+config.version = "8" -+virtualHW.version = "10" -+nvram = "Fedora 20.nvram" -+pciBridge0.present = "TRUE" -+svga.present = "TRUE" -+pciBridge4.present = "TRUE" -+pciBridge4.virtualDev = "pcieRootPort" -+pciBridge4.functions = "8" -+pciBridge5.present = "TRUE" -+pciBridge5.virtualDev = "pcieRootPort" -+pciBridge5.functions = "8" -+pciBridge6.present = "TRUE" -+pciBridge6.virtualDev = "pcieRootPort" -+pciBridge6.functions = "8" -+pciBridge7.present = "TRUE" -+pciBridge7.virtualDev = "pcieRootPort" -+pciBridge7.functions = "8" -+vmci0.present = "TRUE" -+hpet0.present = "TRUE" -+displayName = "Fedora 20" -+extendedConfigFile = "Fedora 20.vmxf" -+virtualHW.productCompatibility = "hosted" -+svga.vramSize = "8388608" -+memSize = "2048" -+sched.cpu.units = "mhz" -+sched.cpu.affinity = "all" -+powerType.powerOff = "soft" -+powerType.suspend = "hard" -+powerType.reset = "soft" -+scsi0.virtualDev = "pvscsi" -+scsi0.present = "TRUE" -+sata0.present = "TRUE" -+scsi0:0.deviceType = "scsi-hardDisk" -+scsi0:0.fileName = "Fedora 20.vmdk" -+sched.scsi0:0.shares = "normal" -+sched.scsi0:0.throughputCap = "off" -+scsi0:0.present = "TRUE" -+ethernet0.virtualDev = "vmxnet3" -+ethernet0.networkName = "VM Network" -+ethernet0.addressType = "vpx" -+ethernet0.generatedAddress = "00:50:56:9b:5f:0d" -+ethernet0.present = "TRUE" -+sata0:0.startConnected = "FALSE" -+sata0:0.deviceType = "cdrom-image" -+sata0:0.fileName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/ISOs/Fedora-20-x86_64-netinst.iso" -+sata0:0.present = "TRUE" -+floppy0.startConnected = "FALSE" -+floppy0.clientDevice = "TRUE" -+floppy0.fileName = "vmware-null-remote-floppy" -+vmci.filter.enable = "TRUE" -+guestOS = "rhel7-64" -+toolScripts.afterPowerOn = "TRUE" -+toolScripts.afterResume = "TRUE" -+toolScripts.beforeSuspend = "TRUE" -+toolScripts.beforePowerOff = "TRUE" -+uuid.bios = "42 1b 4b 87 e6 b7 d8 81-07 a0 c9 d2 21 cd 3c 6b" -+vc.uuid = "50 1b 1f 1b 73 00 32 bf-93 a1 1c b2 b4 e6 17 d6" -+sched.cpu.min = "0" -+sched.cpu.shares = "normal" -+sched.mem.min = "0" -+sched.mem.minSize = "0" -+sched.mem.shares = "normal" -+sched.swap.derivedName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/Fedora 20/Fedora 20-c71e4118.vswp" -+uuid.location = "56 4d 0f 53 00 63 d5 55-41 01 4c f7 55 ce 03 0e" -+replay.supported = "TRUE" -+replay.filename = "" -+scsi0:0.redo = "" -+pciBridge0.pciSlotNumber = "17" -+pciBridge4.pciSlotNumber = "21" -+pciBridge5.pciSlotNumber = "22" -+pciBridge6.pciSlotNumber = "23" -+pciBridge7.pciSlotNumber = "24" -+scsi0.pciSlotNumber = "160" -+ethernet0.pciSlotNumber = "192" -+vmci0.pciSlotNumber = "32" -+sata0.pciSlotNumber = "33" -+scsi0.sasWWID = "50 05 05 67 e6 b7 d8 80" -+vmci0.id = "567098475" -+vmotion.checkpointFBSize = "8388608" -+cleanShutdown = "TRUE" -+softPowerOff = "TRUE" -+sata0:0.allowGuestConnectionControl = "TRUE" -+tools.syncTime = "FALSE" -diff --git a/v2v/test-v2v-i-vmx-3.expected b/v2v/test-v2v-i-vmx-3.expected -new file mode 100644 -index 000000000..64808a77b ---- /dev/null -+++ b/v2v/test-v2v-i-vmx-3.expected -@@ -0,0 +1,19 @@ -+[ 0.0] Opening the source -i vmx test-v2v-i-vmx-3.vmx -+Source guest information (--print-source option): -+ -+ source name: RHEL 7.1 UEFI -+hypervisor type: vmware -+ memory: 2147483648 (bytes) -+ nr vCPUs: 1 -+ CPU features: -+ firmware: uefi -+ display: -+ video: vmvga -+ sound: -+disks: -+ /RHEL 7.1 UEFI.vmdk (vmdk) [scsi] -+removable media: -+ CD-ROM [ide] in slot 2 -+NICs: -+ Network "VM Network" mac: 00:0c:29:4b:2b:8c [vmxnet3] -+ -diff --git a/v2v/test-v2v-i-vmx-3.vmx b/v2v/test-v2v-i-vmx-3.vmx -new file mode 100644 -index 000000000..c39215555 ---- /dev/null -+++ b/v2v/test-v2v-i-vmx-3.vmx -@@ -0,0 +1,91 @@ -+.encoding = "UTF-8" -+config.version = "8" -+virtualHW.version = "8" -+nvram = "RHEL 7.1 UEFI.nvram" -+pciBridge0.present = "TRUE" -+svga.present = "TRUE" -+pciBridge4.present = "TRUE" -+pciBridge4.virtualDev = "pcieRootPort" -+pciBridge4.functions = "8" -+pciBridge5.present = "TRUE" -+pciBridge5.virtualDev = "pcieRootPort" -+pciBridge5.functions = "8" -+pciBridge6.present = "TRUE" -+pciBridge6.virtualDev = "pcieRootPort" -+pciBridge6.functions = "8" -+pciBridge7.present = "TRUE" -+pciBridge7.virtualDev = "pcieRootPort" -+pciBridge7.functions = "8" -+vmci0.present = "TRUE" -+hpet0.present = "TRUE" -+displayName = "RHEL 7.1 UEFI" -+extendedConfigFile = "RHEL 7.1 UEFI.vmxf" -+virtualHW.productCompatibility = "hosted" -+memSize = "2048" -+firmware = "efi" -+sched.cpu.units = "mhz" -+powerType.powerOff = "soft" -+powerType.suspend = "hard" -+powerType.reset = "soft" -+scsi0.virtualDev = "pvscsi" -+scsi0.present = "TRUE" -+ide1:0.startConnected = "FALSE" -+ide1:0.deviceType = "cdrom-image" -+ide1:0.fileName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/ISOs/RHEL-7.1-20150219.1-Server-x86_64-boot.iso" -+ide1:0.present = "TRUE" -+floppy0.startConnected = "FALSE" -+floppy0.clientDevice = "TRUE" -+floppy0.fileName = "vmware-null-remote-floppy" -+ethernet0.virtualDev = "vmxnet3" -+ethernet0.networkName = "VM Network" -+ethernet0.addressType = "generated" -+ethernet0.present = "TRUE" -+scsi0:0.deviceType = "scsi-hardDisk" -+scsi0:0.fileName = "RHEL 7.1 UEFI.vmdk" -+scsi0:0.present = "TRUE" -+guestOS = "rhel6-64" -+toolScripts.afterPowerOn = "TRUE" -+toolScripts.afterResume = "TRUE" -+toolScripts.beforeSuspend = "TRUE" -+toolScripts.beforePowerOff = "TRUE" -+uuid.bios = "56 4d 99 89 a7 21 91 0d-cc 28 e2 db d5 4b 2b 8c" -+uuid.location = "56 4d 99 89 a7 21 91 0d-cc 28 e2 db d5 4b 2b 8c" -+vc.uuid = "52 3f 29 10 d3 81 16 43-fa b0 e3 af 3b ba 36 e5" -+chipset.onlineStandby = "FALSE" -+sched.cpu.min = "0" -+sched.cpu.shares = "normal" -+sched.mem.min = "0" -+sched.mem.minSize = "0" -+sched.mem.shares = "normal" -+svga.vramSize = "8388608" -+sched.swap.derivedName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/RHEL 7.1 UEFI/RHEL 7.1 UEFI-58ff6e6f.vswp" -+replay.supported = "FALSE" -+replay.filename = "" -+scsi0:0.redo = "" -+pciBridge0.pciSlotNumber = "17" -+pciBridge4.pciSlotNumber = "21" -+pciBridge5.pciSlotNumber = "22" -+pciBridge6.pciSlotNumber = "23" -+pciBridge7.pciSlotNumber = "24" -+scsi0.pciSlotNumber = "160" -+ethernet0.pciSlotNumber = "192" -+vmci0.pciSlotNumber = "32" -+scsi0.sasWWID = "50 05 05 69 a7 21 91 00" -+ethernet0.generatedAddress = "00:0c:29:4b:2b:8c" -+ethernet0.generatedAddressOffset = "0" -+vmci0.id = "-716493940" -+hostCPUID.0 = "0000000d756e65476c65746e49656e69" -+hostCPUID.1 = "000206a700100800179ae3bfbfebfbff" -+hostCPUID.80000001 = "00000000000000000000000128100800" -+guestCPUID.0 = "0000000d756e65476c65746e49656e69" -+guestCPUID.1 = "000206a700010800969822030fabfbff" -+guestCPUID.80000001 = "00000000000000000000000128100800" -+userCPUID.0 = "0000000d756e65476c65746e49656e69" -+userCPUID.1 = "000206a700100800169822030fabfbff" -+userCPUID.80000001 = "00000000000000000000000128100800" -+evcCompatibilityMode = "FALSE" -+vmotion.checkpointFBSize = "8388608" -+cleanShutdown = "TRUE" -+softPowerOff = "TRUE" -+ide1:0.allowGuestConnectionControl = "TRUE" -+tools.syncTime = "FALSE" -diff --git a/v2v/test-v2v-i-vmx-4.expected b/v2v/test-v2v-i-vmx-4.expected -new file mode 100644 -index 000000000..208920b29 ---- /dev/null -+++ b/v2v/test-v2v-i-vmx-4.expected -@@ -0,0 +1,19 @@ -+[ 0.0] Opening the source -i vmx test-v2v-i-vmx-4.vmx -+Source guest information (--print-source option): -+ -+ source name: Windows 7 x64 -+hypervisor type: vmware -+ memory: 2147483648 (bytes) -+ nr vCPUs: 1 -+ CPU features: -+ firmware: bios -+ display: -+ video: vmvga -+ sound: -+disks: -+ /Windows 7 x64.vmdk (vmdk) [scsi] -+removable media: -+ CD-ROM [ide] in slot 2 -+NICs: -+ Network "VM Network" mac: 00:0c:29:94:89:23 [e1000] -+ -diff --git a/v2v/test-v2v-i-vmx-4.vmx b/v2v/test-v2v-i-vmx-4.vmx -new file mode 100644 -index 000000000..7756cf248 ---- /dev/null -+++ b/v2v/test-v2v-i-vmx-4.vmx -@@ -0,0 +1,88 @@ -+.encoding = "UTF-8" -+config.version = "8" -+virtualHW.version = "8" -+nvram = "Windows 7 x64.nvram" -+pciBridge0.present = "TRUE" -+svga.present = "TRUE" -+pciBridge4.present = "TRUE" -+pciBridge4.virtualDev = "pcieRootPort" -+pciBridge4.functions = "8" -+pciBridge5.present = "TRUE" -+pciBridge5.virtualDev = "pcieRootPort" -+pciBridge5.functions = "8" -+pciBridge6.present = "TRUE" -+pciBridge6.virtualDev = "pcieRootPort" -+pciBridge6.functions = "8" -+pciBridge7.present = "TRUE" -+pciBridge7.virtualDev = "pcieRootPort" -+pciBridge7.functions = "8" -+vmci0.present = "TRUE" -+hpet0.present = "TRUE" -+displayName = "Windows 7 x64" -+extendedConfigFile = "Windows 7 x64.vmxf" -+virtualHW.productCompatibility = "hosted" -+memSize = "2048" -+sched.cpu.units = "mhz" -+powerType.powerOff = "soft" -+powerType.suspend = "hard" -+powerType.reset = "soft" -+scsi0.virtualDev = "lsisas1068" -+scsi0.present = "TRUE" -+ide1:0.deviceType = "cdrom-image" -+ide1:0.fileName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/ISOs/en_windows_7_ultimate_with_sp1_x64_dvd_u_677332.iso" -+ide1:0.present = "TRUE" -+floppy0.startConnected = "FALSE" -+floppy0.clientDevice = "TRUE" -+floppy0.fileName = "vmware-null-remote-floppy" -+ethernet0.virtualDev = "e1000" -+ethernet0.networkName = "VM Network" -+ethernet0.addressType = "generated" -+ethernet0.present = "TRUE" -+scsi0:0.deviceType = "scsi-hardDisk" -+scsi0:0.fileName = "Windows 7 x64.vmdk" -+scsi0:0.present = "TRUE" -+guestOS = "windows7-64" -+toolScripts.afterPowerOn = "TRUE" -+toolScripts.afterResume = "TRUE" -+toolScripts.beforeSuspend = "TRUE" -+toolScripts.beforePowerOff = "TRUE" -+uuid.bios = "56 4d 6f ca 63 a5 a8 3e-13 ec 73 89 1d 94 89 23" -+uuid.location = "56 4d 6f ca 63 a5 a8 3e-13 ec 73 89 1d 94 89 23" -+vc.uuid = "52 7a 63 e1 2c 2f 50 46-91 66 3a e8 fa f9 c4 65" -+chipset.onlineStandby = "FALSE" -+sched.cpu.min = "0" -+sched.cpu.shares = "normal" -+sched.mem.min = "0" -+sched.mem.minSize = "0" -+sched.mem.shares = "normal" -+svga.vramSize = "8388608" -+sched.swap.derivedName = "/vmfs/volumes/5458b680-34ec3500-9f36-001320f5f6ca/Windows 7 x64/Windows 7 x64-8e3b0929.vswp" -+replay.supported = "FALSE" -+replay.filename = "" -+scsi0:0.redo = "" -+pciBridge0.pciSlotNumber = "17" -+pciBridge4.pciSlotNumber = "21" -+pciBridge5.pciSlotNumber = "22" -+pciBridge6.pciSlotNumber = "23" -+pciBridge7.pciSlotNumber = "24" -+scsi0.pciSlotNumber = "160" -+ethernet0.pciSlotNumber = "32" -+vmci0.pciSlotNumber = "33" -+scsi0.sasWWID = "50 05 05 6a 63 a5 a8 30" -+ethernet0.generatedAddress = "00:0c:29:94:89:23" -+ethernet0.generatedAddressOffset = "0" -+vmci0.id = "496273699" -+hostCPUID.0 = "0000000b756e65476c65746e49656e69" -+hostCPUID.1 = "000206c220200800029ee3ffbfebfbff" -+hostCPUID.80000001 = "0000000000000000000000012c100800" -+guestCPUID.0 = "0000000b756e65476c65746e49656e69" -+guestCPUID.1 = "000206c200010800829822030fabfbff" -+guestCPUID.80000001 = "00000000000000000000000128100800" -+userCPUID.0 = "0000000b756e65476c65746e49656e69" -+userCPUID.1 = "000206c220200800029822030fabfbff" -+userCPUID.80000001 = "00000000000000000000000128100800" -+evcCompatibilityMode = "FALSE" -+vmotion.checkpointFBSize = "8388608" -+cleanShutdown = "TRUE" -+softPowerOff = "TRUE" -+tools.remindInstall = "TRUE" -diff --git a/v2v/test-v2v-i-vmx.sh b/v2v/test-v2v-i-vmx.sh -new file mode 100755 -index 000000000..5353e7e2a ---- /dev/null -+++ b/v2v/test-v2v-i-vmx.sh -@@ -0,0 +1,48 @@ -+#!/bin/bash - -+# libguestfs virt-v2v test script -+# Copyright (C) 2017 Red Hat Inc. -+# -+# 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 -i ova option. -+ -+set -e -+ -+$TEST_FUNCTIONS -+skip_if_skipped -+skip_if_backend uml -+ -+export VIRT_TOOLS_DATA_DIR="$top_srcdir/test-data/fake-virt-tools" -+export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win" -+ -+rm -f test-v2v-i-vmx-*.actual -+ -+for i in 1 2 3 4; do -+ $VG virt-v2v --debug-gc \ -+ -i vmx test-v2v-i-vmx-$i.vmx \ -+ --print-source > test-v2v-i-vmx-$i.actual -+ -+ # Normalize the print-source output. -+ mv test-v2v-i-vmx-$i.actual test-v2v-i-vmx-$i.actual.old -+ sed \ -+ -e "s,$(pwd),," \ -+ < test-v2v-i-vmx-$i.actual.old > test-v2v-i-vmx-$i.actual -+ rm test-v2v-i-vmx-$i.actual.old -+ -+ # Check the output. -+ diff -u test-v2v-i-vmx-$i.expected test-v2v-i-vmx-$i.actual -+done -+ -+rm test-v2v-i-vmx-*.actual -diff --git a/v2v/v2v_unit_tests.ml b/v2v/v2v_unit_tests.ml -index 873610a7c..1b4332a9e 100644 ---- a/v2v/v2v_unit_tests.ml -+++ b/v2v/v2v_unit_tests.ml -@@ -787,6 +787,148 @@ let test_qemu_img_supports ctx = - *) - ignore (Utils.qemu_img_supports_offset_and_size ()) - -+(* Test the VMX file parser in the Parse_vmx module. *) -+let test_vmx_parse_string ctx = -+ let cmp = Parse_vmx.equal in -+ let printer = Parse_vmx.to_string 0 in -+ -+ (* This should be identical to the empty file. *) -+ let t = Parse_vmx.parse_string "\ -+test.foo = \"a\" -+test.bar = \"b\" -+test.present = \"FALSE\" -+" in -+ assert_equal ~cmp ~printer Parse_vmx.empty t; -+ -+ (* Test weird escapes. *) -+ let t1 = Parse_vmx.parse_string "\ -+foo = \"a|20|21b\" -+" in -+ let t2 = Parse_vmx.parse_string "\ -+foo = \"a !b\" -+" in -+ assert_equal ~cmp ~printer t1 t2; -+ -+ (* Test case insensitivity. *) -+ let t1 = Parse_vmx.parse_string "\ -+foo = \"abc\" -+" in -+ let t2 = Parse_vmx.parse_string "\ -+fOO = \"abc\" -+" in -+ assert_equal ~cmp ~printer t1 t2; -+ let t = Parse_vmx.parse_string "\ -+flag = \"true\" -+" in -+ assert_bool "parse_vmx: failed case insensitivity test for booleans #1" -+ (Parse_vmx.get_bool t ["FLAG"] = Some true); -+ let t = Parse_vmx.parse_string "\ -+flag = \"TRUE\" -+" in -+ assert_bool "parse_vmx: failed case insensitivity test for booleans #2" -+ (Parse_vmx.get_bool t ["Flag"] = Some true); -+ -+ (* Missing keys. *) -+ let t = Parse_vmx.parse_string "\ -+foo = \"a\" -+" in -+ assert_bool "parse_vmx: failed missing key test" -+ (Parse_vmx.get_string t ["bar"] = None); -+ -+ (* namespace_present function *) -+ let t = Parse_vmx.parse_string "\ -+foo.bar.present = \"TRUE\" -+foo.baz.present = \"FALSE\" -+foo.a.b = \"abc\" -+foo.a.c = \"abc\" -+foo.b = \"abc\" -+foo.c.a = \"abc\" -+foo.c.b = \"abc\" -+" in -+ assert_bool "parse_vmx: namespace_present #1" -+ (Parse_vmx.namespace_present t ["foo"] = true); -+ assert_bool "parse_vmx: namespace_present #2" -+ (Parse_vmx.namespace_present t ["foo"; "bar"] = true); -+ assert_bool "parse_vmx: namespace_present #3" -+ (* this whole namespace should have been culled *) -+ (Parse_vmx.namespace_present t ["foo"; "baz"] = false); -+ assert_bool "parse_vmx: namespace_present #4" -+ (Parse_vmx.namespace_present t ["foo"; "a"] = true); -+ assert_bool "parse_vmx: namespace_present #5" -+ (* this is a key, not a namespace *) -+ (Parse_vmx.namespace_present t ["foo"; "a"; "b"] = false); -+ assert_bool "parse_vmx: namespace_present #6" -+ (Parse_vmx.namespace_present t ["foo"; "b"] = false); -+ assert_bool "parse_vmx: namespace_present #7" -+ (Parse_vmx.namespace_present t ["foo"; "c"] = true); -+ assert_bool "parse_vmx: namespace_present #8" -+ (Parse_vmx.namespace_present t ["foo"; "d"] = false); -+ -+ (* map function *) -+ let t = Parse_vmx.parse_string "\ -+foo.bar.present = \"TRUE\" -+foo.baz.present = \"FALSE\" -+foo.a.b = \"abc\" -+foo.a.c = \"abc\" -+foo.b = \"abc\" -+foo.c.a = \"abc\" -+foo.c.b = \"abc\" -+" in -+ let xs = -+ Parse_vmx.map ( -+ fun path -> -+ let path = String.concat "." path in -+ function -+ | None -> sprintf "%s.present = \"true\"\n" path -+ | Some v -> sprintf "%s = \"%s\"\n" path v -+ ) t in -+ let xs = List.sort compare xs in -+ let s = String.concat "" xs in -+ assert_equal ~printer:identity "\ -+foo.a.b = \"abc\" -+foo.a.c = \"abc\" -+foo.a.present = \"true\" -+foo.b = \"abc\" -+foo.bar.present = \"TRUE\" -+foo.bar.present = \"true\" -+foo.c.a = \"abc\" -+foo.c.b = \"abc\" -+foo.c.present = \"true\" -+foo.present = \"true\" -+" s; -+ -+ (* select_namespaces function *) -+ let t1 = Parse_vmx.parse_string "\ -+foo.bar.present = \"TRUE\" -+foo.a.b = \"abc\" -+foo.a.c = \"abc\" -+foo.b = \"abc\" -+foo.c.a = \"abc\" -+foo.c.b = \"abc\" -+" in -+ let t2 = -+ Parse_vmx.select_namespaces -+ (function ["foo"] -> true | _ -> false) t1 in -+ assert_equal ~cmp ~printer t1 t2; -+ -+ let t1 = Parse_vmx.parse_string "\ -+foo.bar.present = \"TRUE\" -+foo.a.b = \"abc\" -+foo.a.c = \"abc\" -+foo.b = \"abc\" -+foo.c.a = \"abc\" -+foo.c.b = \"abc\" -+foo.c.c.d.e.f = \"abc\" -+" in -+ let t1 = -+ Parse_vmx.select_namespaces -+ (function ["foo"; "a"] -> true | _ -> false) t1 in -+ let t2 = Parse_vmx.parse_string "\ -+foo.a.b = \"abc\" -+foo.a.c = \"abc\" -+" in -+ assert_equal ~cmp ~printer t2 t1 -+ - (* Suites declaration. *) - let suite = - "virt-v2v" >::: -@@ -798,6 +940,7 @@ let suite = - test_virtio_iso_path_matches_guest_os; - "Utils.shell_unquote" >:: test_shell_unquote; - "Utils.qemu_img_supports" >:: test_qemu_img_supports; -+ "Parse_vmx.parse_string" >::test_vmx_parse_string; - ] - - let () = -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 709075fba..7ed5c5d86 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -41,7 +41,8 @@ libguestfs E 1.28. - ... ───▶│ (default) │ │ │ ──┐ └────────────┘ - └────────────┘ │ │ ─┐└──────▶ -o glance - -i libvirtxml ─────────▶ │ │ ┐└─────────▶ -o rhv -- └────────────┘ └──────────▶ -o vdsm -+ -i vmx ────────────────▶ │ │ └──────────▶ -o vdsm -+ └────────────┘ - - Virt-v2v has a number of possible input and output modes, selected - using the I<-i> and I<-o> options. Only one input and output mode can -@@ -60,6 +61,8 @@ method used by L behind the scenes. - - I<-i ova> is used for reading from a VMware ova source file. - -+I<-i vmx> is used for reading from a VMware vmx file. -+ - I<-o glance> is used for writing to OpenStack Glance. - - I<-o libvirt> is used for writing to any libvirt target. Libvirt can -@@ -228,6 +231,14 @@ ova manifest file and check the vmdk volumes for validity (checksums) - as well as analyzing the ovf file, and then convert the guest. See - L below - -+=item B<-i> B -+ -+Set the input method to I. -+ -+In this mode you can read a VMware vmx file directly. This is useful -+when VMware VMs are stored on an NFS server which you can mount -+directly. See L below -+ - =item B<-ic> libvirtURI - - Specify a libvirt connection URI to use when reading the guest. This -@@ -859,9 +870,10 @@ I<--bridge> option instead. For example: - - Virt-v2v is able to import guests from VMware vCenter Server. - --vCenter E 5.0 is required. If you don't have vCenter, using OVA --is recommended instead (see L below), or if --that is not possible then see L. -+vCenter E 5.0 is required. If you don’t have vCenter, using OVA -+or VMX is recommended instead (see L and/or -+L below), or if that is not possible then see -+L. - - Virt-v2v uses libvirt for access to vCenter, and therefore the input - mode should be I<-i libvirt>. As this is the default, you don't need -@@ -1132,12 +1144,58 @@ directory containing the files: - - $ virt-v2v -i ova /path/to/files -o local -os /var/tmp - -+=head1 INPUT FROM VMWARE VMX -+ -+Virt-v2v is able to import guests from VMware’s vmx files. This is -+useful where VMware virtual machines are stored on a separate NFS -+server and you are able to mount the NFS storage directly. -+ -+If you find a folder of files called F.vmx>, -+F.vmxf>, F.nvram> and one or more F<.vmdk> disk -+images, then you can use this method. -+ -+=head2 VMX: REMOVE VMWARE TOOLS FROM WINDOWS GUESTS -+ -+For Windows guests, you should remove VMware tools before conversion. -+Although this is not strictly necessary, and the guest will still be -+able to run, if you don't do this then the converted guest will -+complain on every boot. The tools cannot be removed after conversion -+because the uninstaller checks if it is running on VMware and refuses -+to start (which is also the reason that virt-v2v cannot remove them). -+ -+This is not necessary for Linux guests, as virt-v2v is able to remove -+VMware tools. -+ -+=head2 VMX: GUEST MUST BE SHUT DOWN -+ -+B. If you don't -+shut it down, you will end up with a corrupted VM disk on the target. -+With other methods, virt-v2v tries to prevent concurrent access, but -+because the I<-i vmx> method works directly against the storage, -+checking for concurrent access is not possible. -+ -+=head2 VMX: MOUNT THE NFS STORAGE ON THE CONVERSION SERVER -+ -+Virt-v2v must be able to access the F<.vmx> file and any local -+F<.vmdk> disks. Normally this means you must mount the NFS storage -+containing these files. -+ -+=head2 VMX: IMPORTING A GUEST -+ -+To import a vmx file, do: -+ -+ $ virt-v2v -i vmx guest.vmx -o local -os /var/tmp -+ -+Virt-v2v processes the vmx file and uses it to find the location of -+any vmdk disks. -+ - =head1 INPUT FROM VMWARE ESXi HYPERVISOR - - Virt-v2v cannot access an ESXi hypervisor directly. You should use --the OVA method above (see L) if possible, as --it is much faster and requires much less disk space than the method --described in this section. -+the OVA or VMX methods above (see L and/or -+L) if possible, as it is much faster and -+requires much less disk space than the method described in this -+section. - - You can use the L tool to copy the guest - off the hypervisor into a local file, and then convert it. --- -2.14.3 - diff --git a/SOURCES/0030-v2v-ovf-Create-OVF-more-aligned-with-the-standard.patch b/SOURCES/0030-v2v-ovf-Create-OVF-more-aligned-with-the-standard.patch new file mode 100644 index 0000000..d8d6ffa --- /dev/null +++ b/SOURCES/0030-v2v-ovf-Create-OVF-more-aligned-with-the-standard.patch @@ -0,0 +1,342 @@ +From 02a7daa696bcfd0d7e1999718324d0c1e32873b9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= +Date: Thu, 22 Feb 2018 11:41:07 +0100 +Subject: [PATCH] v2v: ovf: Create OVF more aligned with the standard +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For historical reasons the OVF used in RHV export domain contains some +deviations from the OVF standard. The format used in -o rhv has to +remain fixed but for -o vdsm and we could produce much nicer OVF. This +patch serves as a preparatory step to this. + +The main reason for creating different OVF is that it can be used to +create VM by oVirt REST API. The RHV export domain flavor cannot be used +that way. + +For now the virt-v2v behavior is unchanged. The modified output will be +enabled in some later patch. + +Signed-off-by: Tomáš Golembiovský +(cherry picked from commit a52ed4b4454396eb13d2cdf5762292bff3104f66) +--- + v2v/create_ovf.ml | 152 ++++++++++++++++++++++++++++++++------------- + v2v/create_ovf.mli | 12 +++- + v2v/output_rhv.ml | 3 +- + v2v/output_vdsm.ml | 3 +- + 4 files changed, 121 insertions(+), 49 deletions(-) + +diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml +index 18956fed1..b9858ff93 100644 +--- a/v2v/create_ovf.ml ++++ b/v2v/create_ovf.ml +@@ -29,6 +29,10 @@ open Types + open Utils + open DOM + ++type ovf_flavour = ++ | OVirt ++ | RHVExportStorageDomain ++ + (* We set the creation time to be the same for all dates in + * all metadata files. All dates in OVF are UTC. + *) +@@ -295,7 +299,7 @@ let create_meta_files output_alloc sd_uuid image_uuids targets = + + (* Create the OVF file. *) + let rec create_ovf source targets guestcaps inspect +- output_alloc sd_uuid image_uuids vol_uuids vm_uuid = ++ output_alloc sd_uuid image_uuids vol_uuids vm_uuid ovf_flavour = + assert (List.length targets = List.length vol_uuids); + + let memsize_mb = source.s_memory /^ 1024L /^ 1024L in +@@ -314,12 +318,26 @@ let rec create_ovf source targets guestcaps inspect + ] [ + Comment generated_by; + e "References" [] []; +- e "Section" ["xsi:type", "ovf:NetworkSection_Type"] [ +- e "Info" [] [PCData "List of networks"] +- ]; +- e "Section" ["xsi:type", "ovf:DiskSection_Type"] [ +- e "Info" [] [PCData "List of Virtual Disks"] +- ]; ++ (match ovf_flavour with ++ | OVirt -> ++ e "NetworkSection" [] [ ++ e "Info" [] [PCData "List of networks"] ++ ] ++ | RHVExportStorageDomain -> ++ e "Section" ["xsi:type", "ovf:NetworkSection_Type"] [ ++ e "Info" [] [PCData "List of networks"] ++ ] ++ ); ++ (match ovf_flavour with ++ | OVirt -> ++ e "DiskSection" [] [ ++ e "Info" [] [PCData "List of Virtual Disks"] ++ ] ++ | RHVExportStorageDomain -> ++ e "Section" ["xsi:type", "ovf:DiskSection_Type"] [ ++ e "Info" [] [PCData "List of Virtual Disks"] ++ ] ++ ); + + let content_subnodes = ref [ + e "Name" [] [PCData source.s_name]; +@@ -352,11 +370,20 @@ let rec create_ovf source targets guestcaps inspect + ); + + List.push_back content_subnodes ( +- e "Section" ["ovf:id", vm_uuid; "ovf:required", "false"; +- "xsi:type", "ovf:OperatingSystemSection_Type"] [ ++ let osinfo_subnodes = [ + e "Info" [] [PCData inspect.i_product_name]; + e "Description" [] [PCData ostype]; +- ] ++ ] in ++ (match ovf_flavour with ++ | OVirt -> ++ e "OperatingSystemSection" ["ovf:id", vm_uuid; ++ "ovf:required", "false"] ++ osinfo_subnodes ++ | RHVExportStorageDomain -> ++ e "Section" ["ovf:id", vm_uuid; "ovf:required", "false"; ++ "xsi:type", "ovf:OperatingSystemSection_Type"] ++ osinfo_subnodes ++ ) + ); + + let virtual_hardware_section_items = ref [ +@@ -444,24 +471,34 @@ let rec create_ovf source targets guestcaps inspect + ); + + List.push_back content_subnodes ( +- e "Section" ["xsi:type", "ovf:VirtualHardwareSection_Type"] +- !virtual_hardware_section_items ++ match ovf_flavour with ++ | OVirt -> ++ e "VirtualHardwareSection" [] !virtual_hardware_section_items ++ | RHVExportStorageDomain -> ++ e "Section" ["xsi:type", "ovf:VirtualHardwareSection_Type"] ++ !virtual_hardware_section_items + ); + +- e "Content" ["ovf:id", "out"; "xsi:type", "ovf:VirtualSystem_Type"] +- !content_subnodes ++ (match ovf_flavour with ++ | OVirt -> ++ e "VirtualSystem" ["ovf:id", "out"] !content_subnodes ++ | RHVExportStorageDomain -> ++ e "Content" ["ovf:id", "out"; "xsi:type", "ovf:VirtualSystem_Type"] ++ !content_subnodes ++ ) + ] in + + (* Add disks to the OVF XML. *) +- add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf; ++ add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ++ ovf_flavour ovf; + + (* Old virt-v2v ignored removable media. XXX *) + + (* Add networks to the OVF XML. *) +- add_networks source.s_nics guestcaps ovf; ++ add_networks source.s_nics guestcaps ovf_flavour ovf; + + (* Add sound card to the OVF XML. *) +- add_sound_card source.s_sound ovf; ++ add_sound_card source.s_sound ovf_flavour ovf; + + (* Old virt-v2v didn't really look at the video and display + * metadata, instead just adding a single standard display (see +@@ -481,21 +518,42 @@ let rec create_ovf source targets guestcaps inspect + (* Return the OVF document. *) + ovf + ++(* Find appropriate section depending on the OVF flavour being generated. ++ * ++ * For example normal disk section is in node whereas in case of ++ * RHV export storage domain it is
. ++ *) ++and get_flavoured_section ovf ovf_flavour ovirt_path rhv_path rhv_path_attr = ++ let nodes = ++ match ovf_flavour with ++ | OVirt -> ++ let nodes = path_to_nodes ovf ovirt_path in ++ (match nodes with ++ | [node] -> node ++ | [] | _::_::_ -> assert false) ++ | RHVExportStorageDomain -> ++ let nodes = path_to_nodes ovf rhv_path in ++ try find_node_by_attr nodes rhv_path_attr ++ with Not_found -> assert false ++ in ++ nodes ++ + (* This modifies the OVF DOM, adding a section for each disk. *) +-and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf = ++and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ++ ovf_flavour ovf = + let references = + let nodes = path_to_nodes ovf ["ovf:Envelope"; "References"] in + match nodes with + | [] | _::_::_ -> assert false + | [node] -> node in +- let disk_section = +- let sections = path_to_nodes ovf ["ovf:Envelope"; "Section"] in +- try find_node_by_attr sections ("xsi:type", "ovf:DiskSection_Type") +- with Not_found -> assert false in +- let virtualhardware_section = +- let sections = path_to_nodes ovf ["ovf:Envelope"; "Content"; "Section"] in +- try find_node_by_attr sections ("xsi:type", "ovf:VirtualHardwareSection_Type") +- with Not_found -> assert false in ++ let disk_section = get_flavoured_section ovf ovf_flavour ++ ["ovf:Envelope"; "DiskSection"] ++ ["ovf:Envelope"; "Section"] ++ ("xsi:type", "ovf:DiskSection_Type") in ++ let virtualhardware_section = get_flavoured_section ovf ovf_flavour ++ ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"] ++ ["ovf:Envelope"; "Content"; "Section"] ++ ("xsi:type", "ovf:VirtualHardwareSection_Type") in + + (* Iterate over the disks, adding them to the OVF document. *) + List.iteri ( +@@ -509,7 +567,12 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf = + let is_bootable_drive = i == 0 in + let boot_order = i+1 in + +- let fileref = sprintf "%s/%s" image_uuid vol_uuid in ++ let fileref = ++ match ovf_flavour with ++ | OVirt -> ++ vol_uuid ++ | RHVExportStorageDomain -> ++ sprintf "%s/%s" image_uuid vol_uuid in + + (* ovf:size and ovf:actual_size fields are integer GBs. If you + * use floating point numbers then RHV will fail to parse them. +@@ -555,7 +618,10 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf = + (* Add disk to DiskSection. *) + let disk = + let attrs = ref [ +- "ovf:diskId", vol_uuid; ++ "ovf:diskId", ++ (match ovf_flavour with ++ | OVirt -> image_uuid ++ | RHVExportStorageDomain -> vol_uuid); + "ovf:size", Int64.to_string size_gb; + "ovf:fileRef", fileref; + "ovf:parentRef", ""; +@@ -613,15 +679,15 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf = + ) (List.combine3 targets image_uuids vol_uuids) + + (* This modifies the OVF DOM, adding a section for each NIC. *) +-and add_networks nics guestcaps ovf = +- let network_section = +- let sections = path_to_nodes ovf ["ovf:Envelope"; "Section"] in +- try find_node_by_attr sections ("xsi:type", "ovf:NetworkSection_Type") +- with Not_found -> assert false in +- let virtualhardware_section = +- let sections = path_to_nodes ovf ["ovf:Envelope"; "Content"; "Section"] in +- try find_node_by_attr sections ("xsi:type", "ovf:VirtualHardwareSection_Type") +- with Not_found -> assert false in ++and add_networks nics guestcaps ovf_flavour ovf = ++ let network_section = get_flavoured_section ovf ovf_flavour ++ ["ovf:Envelope"; "NetworkSection"] ++ ["ovf:Envelope"; "Section"] ++ ("xsi:type", "ovf:NetworkSection_Type") in ++ let virtualhardware_section = get_flavoured_section ovf ovf_flavour ++ ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"] ++ ["ovf:Envelope"; "Content"; "Section"] ++ ("xsi:type", "ovf:VirtualHardwareSection_Type") in + + (* Iterate over the NICs, adding them to the OVF document. *) + List.iteri ( +@@ -669,7 +735,7 @@ and add_networks nics guestcaps ovf = + ) nics + + (* This modifies the OVF DOM, adding a sound card, if oVirt can emulate it. *) +-and add_sound_card sound ovf = ++and add_sound_card sound ovf_flavour ovf = + let device = + match sound with + | None -> None +@@ -682,12 +748,10 @@ and add_sound_card sound ovf = + + match device with + | Some device -> +- let virtualhardware_section = +- let sections = +- path_to_nodes ovf ["ovf:Envelope"; "Content"; "Section"] in +- try find_node_by_attr sections +- ("xsi:type", "ovf:VirtualHardwareSection_Type") +- with Not_found -> assert false in ++ let virtualhardware_section = get_flavoured_section ovf ovf_flavour ++ ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"] ++ ["ovf:Envelope"; "Content"; "Section"] ++ ("xsi:type", "ovf:VirtualHardwareSection_Type") in + + let item = + e "Item" [] [ +diff --git a/v2v/create_ovf.mli b/v2v/create_ovf.mli +index 07e8af6a0..8a8c7dd12 100644 +--- a/v2v/create_ovf.mli ++++ b/v2v/create_ovf.mli +@@ -16,16 +16,22 @@ + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *) + ++type ovf_flavour = ++ | OVirt ++ | RHVExportStorageDomain ++ + (** Create OVF and related files for RHV. + +- The format is described in +- http://www.ovirt.org/images/8/86/Ovirt_ovf_format.odt ++ The format for RHV export storage domain is described in: ++ http://resources.ovirt.org/old-site-files/Ovirt_ovf_format.odt ++ ++ The format understood by oVirt has no known documentation. + + OVF isn't a real standard, so it's likely that if we ever had to + create OVF for another target management system then we would need + to heavily modify or even duplicate this code. *) + +-val create_ovf : Types.source -> Types.target list -> Types.guestcaps -> Types.inspect -> Types.output_allocation -> string -> string list -> string list -> string -> DOM.doc ++val create_ovf : Types.source -> Types.target list -> Types.guestcaps -> Types.inspect -> Types.output_allocation -> string -> string list -> string list -> string -> ovf_flavour -> DOM.doc + (** Create the OVF file. + + Actually a {!DOM} document is created, not a file. It can be written +diff --git a/v2v/output_rhv.ml b/v2v/output_rhv.ml +index 0b732e4cf..5260ab030 100644 +--- a/v2v/output_rhv.ml ++++ b/v2v/output_rhv.ml +@@ -275,7 +275,8 @@ object + + (* Create the metadata. *) + let ovf = Create_ovf.create_ovf source targets guestcaps inspect +- output_alloc esd_uuid image_uuids vol_uuids vm_uuid in ++ output_alloc esd_uuid image_uuids vol_uuids vm_uuid ++ Create_ovf.RHVExportStorageDomain in + + (* Write it to the metadata file. *) + let dir = esd_mp // esd_uuid // "master" // "vms" // vm_uuid in +diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml +index c5e904ba1..ce286d327 100644 +--- a/v2v/output_vdsm.ml ++++ b/v2v/output_vdsm.ml +@@ -175,7 +175,8 @@ object + output_alloc dd_uuid + vdsm_options.image_uuids + vdsm_options.vol_uuids +- vdsm_options.vm_uuid in ++ vdsm_options.vm_uuid ++ Create_ovf.RHVExportStorageDomain in + + (* Write it to the metadata file. *) + let file = vdsm_options.ovf_output // vdsm_options.vm_uuid ^ ".ovf" in +-- +2.17.1 + diff --git a/SOURCES/0031-v2v-tests-Fix-i-vmx-test-so-it-is-more-stable.patch b/SOURCES/0031-v2v-tests-Fix-i-vmx-test-so-it-is-more-stable.patch deleted file mode 100644 index 35078ba..0000000 --- a/SOURCES/0031-v2v-tests-Fix-i-vmx-test-so-it-is-more-stable.patch +++ /dev/null @@ -1,75 +0,0 @@ -From f5ce5692f4701fc122af82759a790cfe01a18c35 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 12 Apr 2017 08:32:58 +0100 -Subject: [PATCH] v2v: tests: Fix -i vmx test so it is more stable. - -When running under valgrind, the process takes a fraction of a second -to start up, changing the "Opening the guest" timestamp, which broke -the test. - -Fixes commit ca40078cdda9167d4658ddfe24c828c7ee76be37. - -(cherry picked from commit ec61873d397f050fe28987f10ec919778d27818a) ---- - v2v/test-v2v-i-vmx-1.expected | 2 +- - v2v/test-v2v-i-vmx-2.expected | 2 +- - v2v/test-v2v-i-vmx-3.expected | 2 +- - v2v/test-v2v-i-vmx-4.expected | 2 +- - v2v/test-v2v-i-vmx.sh | 1 + - 5 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/v2v/test-v2v-i-vmx-1.expected b/v2v/test-v2v-i-vmx-1.expected -index c7ef1f5d5..128c34762 100644 ---- a/v2v/test-v2v-i-vmx-1.expected -+++ b/v2v/test-v2v-i-vmx-1.expected -@@ -1,4 +1,4 @@ --[ 0.0] Opening the source -i vmx test-v2v-i-vmx-1.vmx -+ - Source guest information (--print-source option): - - source name: BZ1308535_21disks -diff --git a/v2v/test-v2v-i-vmx-2.expected b/v2v/test-v2v-i-vmx-2.expected -index a04bd0f62..7f3ee8154 100644 ---- a/v2v/test-v2v-i-vmx-2.expected -+++ b/v2v/test-v2v-i-vmx-2.expected -@@ -1,4 +1,4 @@ --[ 0.0] Opening the source -i vmx test-v2v-i-vmx-2.vmx -+ - Source guest information (--print-source option): - - source name: Fedora 20 -diff --git a/v2v/test-v2v-i-vmx-3.expected b/v2v/test-v2v-i-vmx-3.expected -index 64808a77b..4664efdec 100644 ---- a/v2v/test-v2v-i-vmx-3.expected -+++ b/v2v/test-v2v-i-vmx-3.expected -@@ -1,4 +1,4 @@ --[ 0.0] Opening the source -i vmx test-v2v-i-vmx-3.vmx -+ - Source guest information (--print-source option): - - source name: RHEL 7.1 UEFI -diff --git a/v2v/test-v2v-i-vmx-4.expected b/v2v/test-v2v-i-vmx-4.expected -index 208920b29..d6dcda5b6 100644 ---- a/v2v/test-v2v-i-vmx-4.expected -+++ b/v2v/test-v2v-i-vmx-4.expected -@@ -1,4 +1,4 @@ --[ 0.0] Opening the source -i vmx test-v2v-i-vmx-4.vmx -+ - Source guest information (--print-source option): - - source name: Windows 7 x64 -diff --git a/v2v/test-v2v-i-vmx.sh b/v2v/test-v2v-i-vmx.sh -index 5353e7e2a..997103d41 100755 ---- a/v2v/test-v2v-i-vmx.sh -+++ b/v2v/test-v2v-i-vmx.sh -@@ -37,6 +37,7 @@ for i in 1 2 3 4; do - # Normalize the print-source output. - mv test-v2v-i-vmx-$i.actual test-v2v-i-vmx-$i.actual.old - sed \ -+ -e "s,.*Opening the source.*,," \ - -e "s,$(pwd),," \ - < test-v2v-i-vmx-$i.actual.old > test-v2v-i-vmx-$i.actual - rm test-v2v-i-vmx-$i.actual.old --- -2.14.3 - diff --git a/SOURCES/0031-v2v-vdsm-add-vdsm-fixed-ovf-option.patch b/SOURCES/0031-v2v-vdsm-add-vdsm-fixed-ovf-option.patch new file mode 100644 index 0000000..afe07b4 --- /dev/null +++ b/SOURCES/0031-v2v-vdsm-add-vdsm-fixed-ovf-option.patch @@ -0,0 +1,213 @@ +From 7566786efa4e67b64c4160baccbc5be136e485e1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= +Date: Thu, 22 Feb 2018 11:41:08 +0100 +Subject: [PATCH] v2v: vdsm: add --vdsm-fixed-ovf option +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add option for -o vdsm that enables output of the modified OVF. oVirt +engine should already be able to consume the OVF, but let's not take any +chances and enable it only by command line argument. It can be made +default later when it receives proper testing. + +Signed-off-by: Tomáš Golembiovský +(cherry picked from commit 285014b290507865fd2020e44ea453af0262b624) +--- + v2v/cmdline.ml | 10 ++++++++++ + v2v/create_ovf.ml | 7 +++++++ + v2v/create_ovf.mli | 9 +++++++++ + v2v/output_vdsm.ml | 9 +++++++-- + v2v/output_vdsm.mli | 1 + + v2v/test-v2v-o-vdsm-options.sh | 3 ++- + v2v/virt-v2v.pod | 20 ++++++++++++++++++++ + 7 files changed, 56 insertions(+), 3 deletions(-) + +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index 0bc5e9055..e80b0689b 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -79,6 +79,11 @@ let parse_cmdline () = + let vdsm_compat = ref "0.10" in + let set_vdsm_compat s = vdsm_compat := s in + ++ let vdsm_ovf_flavour = ref Create_ovf.RHVExportStorageDomain in ++ let ovf_flavours_str = String.concat "|" Create_ovf.ovf_flavours in ++ let set_vdsm_ovf_flavour arg = ++ vdsm_ovf_flavour := Create_ovf.ovf_flavour_of_string arg in ++ + let set_string_option_once optname optref arg = + match !optref with + | Some _ -> +@@ -249,6 +254,8 @@ let parse_cmdline () = + s_"Output VM UUID"; + [ L"vdsm-ovf-output" ], Getopt.String ("-", set_string_option_once "--vdsm-ovf-output" vdsm_ovf_output), + s_"Output OVF file"; ++ [ L"vdsm-ovf-flavour" ], Getopt.Symbol (ovf_flavours_str, Create_ovf.ovf_flavours, set_vdsm_ovf_flavour), ++ s_"Set the type of generated OVF (default rhvexp)"; + [ L"vmtype" ], Getopt.String ("-", vmtype_warning), + s_"Ignored for backwards compatibility"; + ] in +@@ -325,6 +332,7 @@ read the man page virt-v2v(1). + let vdsm_vol_uuids = List.rev !vdsm_vol_uuids in + let vdsm_vm_uuid = !vdsm_vm_uuid in + let vdsm_ovf_output = Option.default "." !vdsm_ovf_output in ++ let vdsm_ovf_flavour = !vdsm_ovf_flavour in + + (* No arguments and machine-readable mode? Print out some facts + * about what this binary supports. +@@ -340,6 +348,7 @@ read the man page virt-v2v(1). + List.iter (printf "input:%s\n") (Modules_list.input_modules ()); + List.iter (printf "output:%s\n") (Modules_list.output_modules ()); + List.iter (printf "convert:%s\n") (Modules_list.convert_modules ()); ++ List.iter (printf "ovf:%s\n") Create_ovf.ovf_flavours; + exit 0 + ); + +@@ -545,6 +554,7 @@ read the man page virt-v2v(1). + vm_uuid = vdsm_vm_uuid; + ovf_output = vdsm_ovf_output; + compat = vdsm_compat; ++ ovf_flavour = vdsm_ovf_flavour; + } in + Output_vdsm.output_vdsm os vdsm_options output_alloc, + output_format, output_alloc in +diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml +index b9858ff93..f1985ea86 100644 +--- a/v2v/create_ovf.ml ++++ b/v2v/create_ovf.ml +@@ -33,6 +33,13 @@ type ovf_flavour = + | OVirt + | RHVExportStorageDomain + ++let ovf_flavours = ["ovirt"; "rhvexp"] ++ ++let ovf_flavour_of_string = function ++ | "ovirt" -> OVirt ++ | "rhvexp" -> RHVExportStorageDomain ++ | flav -> invalid_arg flav ++ + (* We set the creation time to be the same for all dates in + * all metadata files. All dates in OVF are UTC. + *) +diff --git a/v2v/create_ovf.mli b/v2v/create_ovf.mli +index 8a8c7dd12..2d80660e3 100644 +--- a/v2v/create_ovf.mli ++++ b/v2v/create_ovf.mli +@@ -20,6 +20,15 @@ type ovf_flavour = + | OVirt + | RHVExportStorageDomain + ++(** The string representation of available OVF flavours. *) ++val ovf_flavours : string list ++ ++(** Convert from a string to the corresponding OVF flavour. ++ ++ Throw [Invalid_argument] if the string does not match any ++ valid flavour. *) ++val ovf_flavour_of_string : string -> ovf_flavour ++ + (** Create OVF and related files for RHV. + + The format for RHV export storage domain is described in: +diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml +index ce286d327..b76a2e930 100644 +--- a/v2v/output_vdsm.ml ++++ b/v2v/output_vdsm.ml +@@ -32,6 +32,7 @@ type vdsm_options = { + vm_uuid : string; + ovf_output : string; + compat : string; ++ ovf_flavour : Create_ovf.ovf_flavour; + } + + class output_vdsm os vdsm_options output_alloc = +@@ -39,7 +40,7 @@ object + inherit output + + method as_options = +- sprintf "-o vdsm -os %s%s%s --vdsm-vm-uuid %s --vdsm-ovf-output %s%s" os ++ sprintf "-o vdsm -os %s%s%s --vdsm-vm-uuid %s --vdsm-ovf-output %s%s%s" os + (String.concat "" + (List.map (sprintf " --vdsm-image-uuid %s") vdsm_options.image_uuids)) + (String.concat "" +@@ -49,6 +50,10 @@ object + (match vdsm_options.compat with + | "0.10" -> "" (* currently this is the default, so don't print it *) + | s -> sprintf " --vdsm-compat=%s" s) ++ (match vdsm_options.ovf_flavour with ++ | Create_ovf.OVirt -> "--vdsm-ovf-flavour=ovf" ++ (* currently this is the default, so don't print it *) ++ | Create_ovf.RHVExportStorageDomain -> "") + + method supported_firmware = [ TargetBIOS ] + +@@ -176,7 +181,7 @@ object + vdsm_options.image_uuids + vdsm_options.vol_uuids + vdsm_options.vm_uuid +- Create_ovf.RHVExportStorageDomain in ++ vdsm_options.ovf_flavour in + + (* Write it to the metadata file. *) + let file = vdsm_options.ovf_output // vdsm_options.vm_uuid ^ ".ovf" in +diff --git a/v2v/output_vdsm.mli b/v2v/output_vdsm.mli +index 401a71ec4..6ed684638 100644 +--- a/v2v/output_vdsm.mli ++++ b/v2v/output_vdsm.mli +@@ -24,6 +24,7 @@ type vdsm_options = { + vm_uuid : string; (* --vdsm-vm-uuid *) + ovf_output : string; (* --vdsm-ovf-output *) + compat : string; (* --vdsm-compat=0.10|1.1 *) ++ ovf_flavour : Create_ovf.ovf_flavour; + } + (** Miscellaneous extra command line parameters used by VDSM. *) + +diff --git a/v2v/test-v2v-o-vdsm-options.sh b/v2v/test-v2v-o-vdsm-options.sh +index 753efc4e7..4ad5d4aad 100755 +--- a/v2v/test-v2v-o-vdsm-options.sh ++++ b/v2v/test-v2v-o-vdsm-options.sh +@@ -55,7 +55,8 @@ $VG virt-v2v --debug-gc \ + --vdsm-vol-uuid VOL \ + --vdsm-vm-uuid VM \ + --vdsm-ovf-output $d/12345678-1234-1234-1234-123456789abc/master/vms/VM \ +- --vdsm-compat=1.1 ++ --vdsm-compat=1.1 \ ++ --vdsm-ovf-flavour=ovirt + + # Test the OVF metadata was created. + test -f $d/12345678-1234-1234-1234-123456789abc/master/vms/VM/VM.ovf +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index f8a937960..d81a2339c 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -627,6 +627,26 @@ hex digit can be C<0-9> or C), conforming to S. + + These options can only be used with I<-o vdsm>. + ++=item B<--vdsm-ovf-flavour> flavour ++ ++This option controls the format of the OVF generated at the end of conversion. ++Currently there are two possible flavours: ++ ++=over 4 ++ ++=item rhevexp ++ ++The OVF format used in RHV export storage domain. ++ ++=item ovirt ++ ++The OVF format understood by oVirt REST API. ++ ++=back ++ ++For backward compatibility the default is I, but this may change in ++the future. ++ + =item B<-v> + + =item B<--verbose> +-- +2.17.1 + diff --git a/SOURCES/0032-RHEL-7-v2v-disable-unconfig-of-manually-installed-VM.patch b/SOURCES/0032-RHEL-7-v2v-disable-unconfig-of-manually-installed-VM.patch deleted file mode 100644 index 251c462..0000000 --- a/SOURCES/0032-RHEL-7-v2v-disable-unconfig-of-manually-installed-VM.patch +++ /dev/null @@ -1,36 +0,0 @@ -From e70e7d95ed6130152186b88d9341c5c715cf29bf Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Mon, 14 Aug 2017 10:02:13 +0200 -Subject: [PATCH] RHEL 7: v2v: disable unconfig of manually installed VMware - tools (RHBZ#1477905) - -It looks like they may require connection to the VMware servers, which -is not always available during conversion. ---- - v2v/convert_linux.ml | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml -index 32e08fa30..cd8a20d31 100644 ---- a/v2v/convert_linux.ml -+++ b/v2v/convert_linux.ml -@@ -293,6 +293,7 @@ let rec convert (g : G.guestfs) inspect source output rcaps = - let remove = !remove in - Linux.remove g inspect remove; - -+(* - (* VMware Tools may have been installed from a tarball, so the - * above code won't remove it. Look for the uninstall tool and run - * if present. -@@ -314,6 +315,8 @@ let rec convert (g : G.guestfs) inspect source output rcaps = - warning (f_"VMware tools was detected, but uninstallation failed. The error message was: %s (ignored)") - msg - ) -+*) -+ () - - and unconfigure_citrix () = - let pkgs = --- -2.14.3 - diff --git a/SOURCES/0032-v2v-OVF-Code-formatting.patch b/SOURCES/0032-v2v-OVF-Code-formatting.patch new file mode 100644 index 0000000..030e3d4 --- /dev/null +++ b/SOURCES/0032-v2v-OVF-Code-formatting.patch @@ -0,0 +1,124 @@ +From 84f74f74a398164a8b6d102633b58b690874fa00 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 22 Feb 2018 14:22:12 +0000 +Subject: [PATCH] v2v: OVF: Code formatting. + +Updates commit a52ed4b4454396eb13d2cdf5762292bff3104f66 +("v2v: ovf: Create OVF more aligned with the standard") with some +small code refactoring and formatting. + +(cherry picked from commit 9e83f3a2ccef4e91b0b3275b712df8b16e233cff) +--- + v2v/create_ovf.ml | 73 ++++++++++++++++++++++++++--------------------- + 1 file changed, 41 insertions(+), 32 deletions(-) + +diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml +index f1985ea86..bf3741e0f 100644 +--- a/v2v/create_ovf.ml ++++ b/v2v/create_ovf.ml +@@ -530,20 +530,16 @@ let rec create_ovf source targets guestcaps inspect + * For example normal disk section is in node whereas in case of + * RHV export storage domain it is
. + *) +-and get_flavoured_section ovf ovf_flavour ovirt_path rhv_path rhv_path_attr = +- let nodes = +- match ovf_flavour with +- | OVirt -> +- let nodes = path_to_nodes ovf ovirt_path in +- (match nodes with ++and get_flavoured_section ovf ovirt_path rhv_path rhv_path_attr = function ++ | OVirt -> ++ let nodes = path_to_nodes ovf ovirt_path in ++ (match nodes with + | [node] -> node + | [] | _::_::_ -> assert false) +- | RHVExportStorageDomain -> +- let nodes = path_to_nodes ovf rhv_path in +- try find_node_by_attr nodes rhv_path_attr +- with Not_found -> assert false +- in +- nodes ++ | RHVExportStorageDomain -> ++ let nodes = path_to_nodes ovf rhv_path in ++ try find_node_by_attr nodes rhv_path_attr ++ with Not_found -> assert false + + (* This modifies the OVF DOM, adding a section for each disk. *) + and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids +@@ -553,14 +549,19 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids + match nodes with + | [] | _::_::_ -> assert false + | [node] -> node in +- let disk_section = get_flavoured_section ovf ovf_flavour +- ["ovf:Envelope"; "DiskSection"] +- ["ovf:Envelope"; "Section"] +- ("xsi:type", "ovf:DiskSection_Type") in +- let virtualhardware_section = get_flavoured_section ovf ovf_flavour +- ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"] +- ["ovf:Envelope"; "Content"; "Section"] +- ("xsi:type", "ovf:VirtualHardwareSection_Type") in ++ let disk_section = ++ get_flavoured_section ovf ++ ["ovf:Envelope"; "DiskSection"] ++ ["ovf:Envelope"; "Section"] ++ ("xsi:type", "ovf:DiskSection_Type") ++ ovf_flavour in ++ let virtualhardware_section = ++ get_flavoured_section ovf ++ ["ovf:Envelope"; "VirtualSystem"; ++ "VirtualHardwareSection"] ++ ["ovf:Envelope"; "Content"; "Section"] ++ ("xsi:type", "ovf:VirtualHardwareSection_Type") ++ ovf_flavour in + + (* Iterate over the disks, adding them to the OVF document. *) + List.iteri ( +@@ -687,14 +688,19 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids + + (* This modifies the OVF DOM, adding a section for each NIC. *) + and add_networks nics guestcaps ovf_flavour ovf = +- let network_section = get_flavoured_section ovf ovf_flavour +- ["ovf:Envelope"; "NetworkSection"] +- ["ovf:Envelope"; "Section"] +- ("xsi:type", "ovf:NetworkSection_Type") in +- let virtualhardware_section = get_flavoured_section ovf ovf_flavour +- ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"] +- ["ovf:Envelope"; "Content"; "Section"] +- ("xsi:type", "ovf:VirtualHardwareSection_Type") in ++ let network_section = ++ get_flavoured_section ovf ++ ["ovf:Envelope"; "NetworkSection"] ++ ["ovf:Envelope"; "Section"] ++ ("xsi:type", "ovf:NetworkSection_Type") ++ ovf_flavour in ++ let virtualhardware_section = ++ get_flavoured_section ovf ++ ["ovf:Envelope"; "VirtualSystem"; ++ "VirtualHardwareSection"] ++ ["ovf:Envelope"; "Content"; "Section"] ++ ("xsi:type", "ovf:VirtualHardwareSection_Type") ++ ovf_flavour in + + (* Iterate over the NICs, adding them to the OVF document. *) + List.iteri ( +@@ -755,10 +761,13 @@ and add_sound_card sound ovf_flavour ovf = + + match device with + | Some device -> +- let virtualhardware_section = get_flavoured_section ovf ovf_flavour +- ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"] +- ["ovf:Envelope"; "Content"; "Section"] +- ("xsi:type", "ovf:VirtualHardwareSection_Type") in ++ let virtualhardware_section = ++ get_flavoured_section ovf ++ ["ovf:Envelope"; "VirtualSystem"; ++ "VirtualHardwareSection"] ++ ["ovf:Envelope"; "Content"; "Section"] ++ ("xsi:type", "ovf:VirtualHardwareSection_Type") ++ ovf_flavour in + + let item = + e "Item" [] [ +-- +2.17.1 + diff --git a/SOURCES/0033-v2v-DOM-Add-doc_to_string-function.patch b/SOURCES/0033-v2v-DOM-Add-doc_to_string-function.patch new file mode 100644 index 0000000..c760766 --- /dev/null +++ b/SOURCES/0033-v2v-DOM-Add-doc_to_string-function.patch @@ -0,0 +1,127 @@ +From 4b5304704a5fa4cad1e5869ce97f27ff64ac492f Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 20 Feb 2018 15:21:48 +0000 +Subject: [PATCH] v2v: DOM: Add doc_to_string function. + +Convert a document to an in-memory string. + +(cherry picked from commit 802c8635cc2537a7d4b7af8981c670e2fdbb2675) +--- + v2v/DOM.ml | 61 +++++++++++++++++++++++++++++++++-------------------- + v2v/DOM.mli | 3 +++ + 2 files changed, 41 insertions(+), 23 deletions(-) + +diff --git a/v2v/DOM.ml b/v2v/DOM.ml +index 7f66e0920..8b106224b 100644 +--- a/v2v/DOM.ml ++++ b/v2v/DOM.ml +@@ -46,43 +46,48 @@ let e name attrs children = + * we will be writing, ie. libvirt XML and OVF metadata, where + * whitespace is generally not significant, but readability is useful. + *) +-let rec node_to_chan ?(indent = 0) chan = function +- | PCData str -> output_string chan (xml_quote_pcdata str) ++let rec node_to_buf ?(indent = 0) buf = function ++ | PCData str -> ++ Buffer.add_string buf (xml_quote_pcdata str) + | Comment str -> +- output_spaces chan indent; +- fprintf chan "" (xml_quote_pcdata str) +- | Element e -> element_to_chan ~indent chan e +-and element_to_chan ?(indent = 0) chan ++ buffer_add_spaces buf indent; ++ bprintf buf "" (xml_quote_pcdata str) ++ | Element e -> ++ element_to_buf ~indent buf e ++and element_to_buf ?(indent = 0) buf + { e_name = name; e_attrs = attrs; e_children = children } = +- output_spaces chan indent; +- fprintf chan "<%s" name; +- List.iter (fun (n, v) -> fprintf chan " %s='%s'" n (xml_quote_attr v)) attrs; ++ buffer_add_spaces buf indent; ++ bprintf buf "<%s" name; ++ List.iter (fun (n, v) -> bprintf buf " %s='%s'" n (xml_quote_attr v)) attrs; + if children <> [] then ( +- output_string chan ">"; ++ Buffer.add_string buf ">"; + let last_child_was_element = ref false in + List.iter ( + function + | Element _ as child -> + last_child_was_element := true; +- output_char chan '\n'; +- node_to_chan ~indent:(indent+2) chan child; ++ Buffer.add_char buf '\n'; ++ node_to_buf ~indent:(indent+2) buf child; + | PCData _ as child -> + last_child_was_element := false; +- node_to_chan ~indent:(indent+2) chan child; ++ node_to_buf ~indent:(indent+2) buf child; + | Comment _ as child -> + last_child_was_element := true; +- output_char chan '\n'; +- node_to_chan ~indent:(indent+2) chan child; ++ Buffer.add_char buf '\n'; ++ node_to_buf ~indent:(indent+2) buf child; + ) children; + if !last_child_was_element then ( +- output_char chan '\n'; +- output_spaces chan indent ++ Buffer.add_char buf '\n'; ++ buffer_add_spaces buf indent + ); +- fprintf chan "" name ++ bprintf buf "" name + ) else ( +- output_string chan "/>" ++ Buffer.add_string buf "/>" + ) + ++and buffer_add_spaces buf n = ++ Buffer.add_string buf (String.spaces n) ++ + (* Quote XML content. Note you must use single + * quotes around the attribute. + *) +@@ -99,10 +104,20 @@ and xml_quote_pcdata str = + let str = String.replace str ">" ">" in + str + +-let doc_to_chan chan (Doc doc) = +- fprintf chan "\n"; +- element_to_chan chan doc; +- fprintf chan "\n" ++let doc_to_buf buf (Doc doc) = ++ bprintf buf "\n"; ++ element_to_buf buf doc; ++ bprintf buf "\n" ++ ++let doc_to_string doc = ++ let buf = Buffer.create 4096 in ++ doc_to_buf buf doc; ++ Buffer.contents buf ++ ++let doc_to_chan chan doc = ++ let buf = Buffer.create 4096 in ++ doc_to_buf buf doc; ++ Buffer.output_buffer chan buf + + let path_to_nodes (Doc doc) path = + match path with +diff --git a/v2v/DOM.mli b/v2v/DOM.mli +index 1aa89b7e7..99223c389 100644 +--- a/v2v/DOM.mli ++++ b/v2v/DOM.mli +@@ -60,6 +60,9 @@ v} + v} + *) + ++val doc_to_string : doc -> string ++(** Convert a document to a string representation. *) ++ + val doc_to_chan : out_channel -> doc -> unit + (** Write the XML document to an output channel. *) + +-- +2.17.1 + diff --git a/SOURCES/0033-v2v-i-ova-Prefer-pigz-or-pxz-for-uncompressing-OVA-f.patch b/SOURCES/0033-v2v-i-ova-Prefer-pigz-or-pxz-for-uncompressing-OVA-f.patch deleted file mode 100644 index f0ff572..0000000 --- a/SOURCES/0033-v2v-i-ova-Prefer-pigz-or-pxz-for-uncompressing-OVA-f.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 3c4780cda6bfdd20d2a71857e326cc9cd2fd708c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 8 May 2017 09:55:42 +0100 -Subject: [PATCH] v2v: -i ova: Prefer pigz or pxz for uncompressing OVA files - (RHBZ#1448739). - -If the parallel tools pigz or pxz are available, prefer them for -uncompressing gz- and xz-compressed OVA files respectively. If not -available then gzip or xz are used as normal. ---- - v2v/input_ova.ml | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml -index c91011873..69cdf576b 100644 ---- a/v2v/input_ova.ml -+++ b/v2v/input_ova.ml -@@ -40,9 +40,19 @@ let libvirt_supports_json_raw_driver () = - else - true - -+let pigz_available = -+ let test = lazy (shell_command "pigz --help >/dev/null 2>&1" = 0) in -+ fun () -> Lazy.force test -+ -+let pxz_available = -+ let test = lazy (shell_command "pxz --help >/dev/null 2>&1" = 0) in -+ fun () -> Lazy.force test -+ - let zcat_command_of_format = function -- | `GZip -> "gzip -c -d" -- | `XZ -> "xz -c -d" -+ | `GZip -> -+ if pigz_available () then "pigz -c -d" else "gzip -c -d" -+ | `XZ -> -+ if pxz_available () then "pxz -c -d" else "xz -c -d" - - (* Untar part or all files from tar archive. If [paths] is specified it is - * a list of paths in the tar archive. --- -2.14.3 - diff --git a/SOURCES/0034-v2v-Add-op-output-password-file-option.patch b/SOURCES/0034-v2v-Add-op-output-password-file-option.patch new file mode 100644 index 0000000..4c260a6 --- /dev/null +++ b/SOURCES/0034-v2v-Add-op-output-password-file-option.patch @@ -0,0 +1,138 @@ +From 2d80f9e648fc4c7598f77dc0c15faeaacf63137d Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 22 Feb 2018 11:43:33 +0000 +Subject: [PATCH] v2v: Add -op (output password file) option. + +Currently unused, in a future commit this will allow you to pass in a +password to be used when connecting to the target hypervisor. + +(cherry picked from commit a4e181137a38f5767dd1bf05dc482959cb7283be) +--- + v2v/cmdline.ml | 18 ++++++++++++++++++ + v2v/test-v2v-docs.sh | 2 +- + v2v/virt-v2v.pod | 7 +++++++ + 3 files changed, 26 insertions(+), 1 deletion(-) + +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index e80b0689b..bfdc250fc 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -62,6 +62,7 @@ let parse_cmdline () = + let output_conn = ref None in + let output_format = ref None in + let output_name = ref None in ++ let output_password = ref None in + let output_storage = ref None in + let password_file = ref None in + let vddk_config = ref None in +@@ -218,6 +219,8 @@ let parse_cmdline () = + s_"Set output format"; + [ M"on" ], Getopt.String ("name", set_string_option_once "-on" output_name), + s_"Rename guest when converting"; ++ [ M"op" ], Getopt.String ("filename", set_string_option_once "-op" output_password), ++ s_"Use password from file to connect to output hypervisor"; + [ M"os" ], Getopt.String ("storage", set_string_option_once "-os" output_storage), + s_"Set output storage location"; + [ L"password-file" ], Getopt.String ("file", set_string_option_once "--password-file" password_file), +@@ -312,6 +315,7 @@ read the man page virt-v2v(1). + let output_format = !output_format in + let output_mode = !output_mode in + let output_name = !output_name in ++ let output_password = !output_password in + let output_storage = !output_storage in + let password_file = !password_file in + let print_source = !print_source in +@@ -462,6 +466,8 @@ read the man page virt-v2v(1). + | `Glance -> + if output_conn <> None then + error_option_cannot_be_used_in_output_mode "glance" "-oc"; ++ if output_password <> None then ++ error_option_cannot_be_used_in_output_mode "glance" "-op"; + if output_storage <> None then + error_option_cannot_be_used_in_output_mode "glance" "-os"; + if qemu_boot then +@@ -473,6 +479,8 @@ read the man page virt-v2v(1). + + | `Not_set + | `Libvirt -> ++ if output_password <> None then ++ error_option_cannot_be_used_in_output_mode "libvirt" "-op"; + let output_storage = Option.default "default" output_storage in + if qemu_boot then + error_option_cannot_be_used_in_output_mode "libvirt" "--qemu-boot"; +@@ -482,6 +490,8 @@ read the man page virt-v2v(1). + output_format, output_alloc + + | `Local -> ++ if output_password <> None then ++ error_option_cannot_be_used_in_output_mode "local" "-op"; + let os = + match output_storage with + | None -> +@@ -501,6 +511,8 @@ read the man page virt-v2v(1). + error_option_cannot_be_used_in_output_mode "null" "-oc"; + if output_format <> None then + error_option_cannot_be_used_in_output_mode "null" "-of"; ++ if output_password <> None then ++ error_option_cannot_be_used_in_output_mode "null" "-op"; + if output_storage <> None then + error_option_cannot_be_used_in_output_mode "null" "-os"; + if qemu_boot then +@@ -510,6 +522,8 @@ read the man page virt-v2v(1). + Some "raw", Sparse + + | `QEmu -> ++ if output_password <> None then ++ error_option_cannot_be_used_in_output_mode "qemu" "-op"; + let os = + match output_storage with + | None -> +@@ -523,6 +537,8 @@ read the man page virt-v2v(1). + output_format, output_alloc + + | `RHV -> ++ if output_password <> None then ++ error_option_cannot_be_used_in_output_mode "rhv" "-op"; + let os = + match output_storage with + | None -> +@@ -534,6 +550,8 @@ read the man page virt-v2v(1). + output_format, output_alloc + + | `VDSM -> ++ if output_password <> None then ++ error_option_cannot_be_used_in_output_mode "vdsm" "-op"; + let os = + match output_storage with + | None -> +diff --git a/v2v/test-v2v-docs.sh b/v2v/test-v2v-docs.sh +index c8ca193eb..bb1ddefd7 100755 +--- a/v2v/test-v2v-docs.sh ++++ b/v2v/test-v2v-docs.sh +@@ -22,4 +22,4 @@ $TEST_FUNCTIONS + skip_if_skipped + + $top_srcdir/podcheck.pl virt-v2v.pod virt-v2v \ +- --ignore=--debug-overlay,--ic,--if,--in-place,--it,--no-trim,--oa,--oc,--of,--on,--os,--vmtype ++ --ignore=--debug-overlay,--ic,--if,--in-place,--it,--no-trim,--oa,--oc,--of,--on,--op,--os,--vmtype +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index d81a2339c..4df3791a9 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -442,6 +442,13 @@ If not specified, then the input format is used. + Rename the guest when converting it. If this option is not used then + the output name is the same as the input name. + ++=item B<-op> file ++ ++Supply a file containing a password to be used when connecting to the ++target hypervisor. Note the file should contain the whole password, ++B, and for security the file should have ++mode C<0600> so that others cannot read it. ++ + =item B<-os> storage + + The location of the storage for the converted guest. +-- +2.17.1 + diff --git a/SOURCES/0034-v2v-add-crypto-support-RHBZ-1451665.patch b/SOURCES/0034-v2v-add-crypto-support-RHBZ-1451665.patch deleted file mode 100644 index e741ccd..0000000 --- a/SOURCES/0034-v2v-add-crypto-support-RHBZ-1451665.patch +++ /dev/null @@ -1,87 +0,0 @@ -From a8853952b43e15fd4aa287d235d8583782475531 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Mon, 22 May 2017 11:31:45 +0200 -Subject: [PATCH] v2v: add crypto support (RHBZ#1451665) - -Make use of the additional command line arguments, and API needed to -decrypt LUKS partitions. This extends to v2v the work done in other -OCaml tools with commit 6b26a0cce4f1d6264bee88902b8931e39288c901, -since it seems to be working fine after a basic testing. - -Related to: RHBZ#1362649 - -(cherry picked from commit 7e6c16f1e7698317991b875f2d7ab3ce9e94c8bb) ---- - v2v/cmdline.ml | 2 +- - v2v/v2v.ml | 3 +++ - v2v/virt-v2v.pod | 20 ++++++++++++++++++++ - 3 files changed, 24 insertions(+), 1 deletion(-) - -diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml -index db2346a38..6b105886c 100644 ---- a/v2v/cmdline.ml -+++ b/v2v/cmdline.ml -@@ -235,7 +235,7 @@ A short summary of the options is given below. For detailed help please - read the man page virt-v2v(1). - ") - prog in -- let opthandle = create_standard_options argspec ~anon_fun usage_msg in -+ let opthandle = create_standard_options argspec ~anon_fun ~key_opts:true usage_msg in - Getopt.parse opthandle; - - (* Dereference the arguments. *) -diff --git a/v2v/v2v.ml b/v2v/v2v.ml -index c1d412295..d03662c84 100644 ---- a/v2v/v2v.ml -+++ b/v2v/v2v.ml -@@ -90,6 +90,9 @@ let rec main () = - - g#launch (); - -+ (* Decrypt the disks. *) -+ inspect_decrypt g; -+ - (* Inspection - this also mounts up the filesystems. *) - (match conversion_mode with - | Copying _ -> message (f_"Inspecting the overlay") -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 7ed5c5d86..77b6f514f 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -191,6 +191,17 @@ Save the overlay file(s) created during conversion. This option is - only used for debugging virt-v2v and may be removed in a future - version. - -+=item B<--echo-keys> -+ -+When prompting for keys and passphrases, virt-v2v normally turns -+echoing off so you cannot see what you are typing. If you are not -+worried about Tempest attacks and there is no one else in the room you -+can specify this flag to see what you are typing. -+ -+Note this options only applies to keys and passphrases for encrypted -+devices and partitions, not for passwords used to connect to remote -+servers. -+ - =item B<-i> B - - Set the input method to I. -@@ -257,6 +268,15 @@ 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<--keys-from-stdin> -+ -+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. -+ - =item B<--machine-readable> - - This option is used to make the output more machine friendly --- -2.14.3 - diff --git a/SOURCES/0035-v2v-Implement-input-from-nbdkit-vddk-plugin-RHBZ-147.patch b/SOURCES/0035-v2v-Implement-input-from-nbdkit-vddk-plugin-RHBZ-147.patch deleted file mode 100644 index 0e2618a..0000000 --- a/SOURCES/0035-v2v-Implement-input-from-nbdkit-vddk-plugin-RHBZ-147.patch +++ /dev/null @@ -1,763 +0,0 @@ -From 9542f12a306e05b73f5c4ecd4e4e61e03797098a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 30 Aug 2017 17:14:03 +0100 -Subject: [PATCH] v2v: Implement input from nbdkit vddk plugin (RHBZ#1477912). - -(cherry picked from commit bbda5a6a68846acf971e0f4cbf83cacfa083d6e9) ---- - v2v/Makefile.am | 2 + - v2v/cmdline.ml | 53 +++++++- - v2v/input_libvirt.ml | 16 ++- - v2v/input_libvirt.mli | 8 +- - v2v/input_libvirt_vddk.ml | 314 +++++++++++++++++++++++++++++++++++++++++++++ - v2v/input_libvirt_vddk.mli | 24 ++++ - v2v/types.ml | 12 ++ - v2v/types.mli | 13 ++ - v2v/virt-v2v.pod | 155 ++++++++++++++++++++++ - 9 files changed, 588 insertions(+), 9 deletions(-) - create mode 100644 v2v/input_libvirt_vddk.ml - create mode 100644 v2v/input_libvirt_vddk.mli - -diff --git a/v2v/Makefile.am b/v2v/Makefile.am -index 0df759eca..87776a509 100644 ---- a/v2v/Makefile.am -+++ b/v2v/Makefile.am -@@ -35,6 +35,7 @@ SOURCES_MLI = \ - input_libvirt.mli \ - input_libvirt_other.mli \ - input_libvirt_vcenter_https.mli \ -+ input_libvirt_vddk.mli \ - input_libvirt_xen_ssh.mli \ - input_libvirtxml.mli \ - input_ova.mli \ -@@ -89,6 +90,7 @@ SOURCES_ML = \ - input_libvirtxml.ml \ - input_libvirt_other.ml \ - input_libvirt_vcenter_https.ml \ -+ input_libvirt_vddk.ml \ - input_libvirt_xen_ssh.ml \ - input_libvirt.ml \ - input_ova.ml \ -diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml -index 6b105886c..3050104d0 100644 ---- a/v2v/cmdline.ml -+++ b/v2v/cmdline.ml -@@ -63,6 +63,15 @@ let parse_cmdline () = - let output_name = ref None in - let output_storage = ref None in - let password_file = ref None in -+ let vddk = ref None in -+ let vddk_config = ref None in -+ let vddk_cookie = ref None in -+ let vddk_nfchostport = ref None in -+ let vddk_port = ref None in -+ let vddk_snapshot = ref None in -+ let vddk_thumbprint = ref None in -+ let vddk_transports = ref None in -+ let vddk_vimapiver = ref None in - let vdsm_vm_uuid = ref None in - let vdsm_ovf_output = ref None in (* default "." *) - -@@ -201,6 +210,24 @@ let parse_cmdline () = - s_"Use password from file"; - [ L"print-source" ], Getopt.Set print_source, s_"Print source and stop"; - [ L"root" ], Getopt.String ("ask|... ", set_root_choice), s_"How to choose root filesystem"; -+ [ L"vddk" ], Getopt.String ("libpath", set_string_option_once "--vddk" vddk), -+ s_"Use nbdkit VDDK plugin"; -+ [ L"vddk-config" ], Getopt.String ("filename", set_string_option_once "--vddk-config" vddk_config), -+ s_"Set VDDK config file"; -+ [ L"vddk-cookie" ], Getopt.String ("cookie", set_string_option_once "--vddk-cookie" vddk_cookie), -+ s_"Set VDDK cookie"; -+ [ L"vddk-nfchostport" ], Getopt.String ("nfchostport", set_string_option_once "--vddk-nfchostport" vddk_nfchostport), -+ s_"Set VDDK nfchostport"; -+ [ L"vddk-port" ], Getopt.String ("port", set_string_option_once "--vddk-port" vddk_port), -+ s_"Set VDDK port"; -+ [ L"vddk-snapshot" ], Getopt.String ("snapshot-moref", set_string_option_once "--vddk-snapshot" vddk_snapshot), -+ s_"Set VDDK snapshot"; -+ [ L"vddk-thumbprint" ], Getopt.String ("thumbprint", set_string_option_once "--vddk-thumbprint" vddk_thumbprint), -+ s_"Set VDDK thumbprint"; -+ [ L"vddk-transports" ], Getopt.String ("transports", set_string_option_once "--vddk-transports" vddk_transports), -+ s_"Set VDDK transports"; -+ [ L"vddk-vimapiver" ], Getopt.String ("apiver", set_string_option_once "--vddk-vimapiver" vddk_vimapiver), -+ s_"Set VDDK vimapiver"; - [ L"vdsm-compat" ], Getopt.Symbol ("0.10|1.1", ["0.10"; "1.1"], set_vdsm_compat), s_"Write qcow2 with compat=0.10|1.1"; - [ L"vdsm-image-uuid" ], Getopt.String ("uuid", add_vdsm_image_uuid), s_"Output image UUID(s)"; - [ L"vdsm-vol-uuid" ], Getopt.String ("uuid", add_vdsm_vol_uuid), s_"Output vol UUID(s)"; -@@ -263,6 +290,29 @@ read the man page virt-v2v(1). - let print_source = !print_source in - let qemu_boot = !qemu_boot in - let root_choice = !root_choice in -+ let vddk_options = -+ match !vddk with -+ | Some libdir -> -+ Some { vddk_libdir = libdir; -+ vddk_config = !vddk_config; -+ vddk_cookie = !vddk_cookie; -+ vddk_nfchostport = !vddk_nfchostport; -+ vddk_port = !vddk_port; -+ vddk_snapshot = !vddk_snapshot; -+ vddk_thumbprint = !vddk_thumbprint; -+ vddk_transports = !vddk_transports; -+ vddk_vimapiver = !vddk_vimapiver } -+ | None -> -+ if !vddk_config <> None || -+ !vddk_cookie <> None || -+ !vddk_nfchostport <> None || -+ !vddk_port <> None || -+ !vddk_snapshot <> None || -+ !vddk_thumbprint <> None || -+ !vddk_transports <> None || -+ !vddk_vimapiver <> None then -+ error (f_"‘--vddk-*’ options should only be used when conversion via the nbdkit VDDK plugin has been enabled, ie. using ‘--vddk’."); -+ None in - let vdsm_compat = !vdsm_compat in - let vdsm_image_uuids = List.rev !vdsm_image_uuids in - let vdsm_vol_uuids = List.rev !vdsm_vol_uuids in -@@ -278,6 +328,7 @@ read the man page virt-v2v(1). - printf "libguestfs-rewrite\n"; - printf "vcenter-https\n"; - printf "xen-ssh\n"; -+ printf "vddk\n"; - printf "colours-option\n"; - printf "vdsm-compat-option\n"; - List.iter (printf "input:%s\n") (Modules_list.input_modules ()); -@@ -316,7 +367,7 @@ read the man page virt-v2v(1). - | [guest] -> guest - | _ -> - error (f_"expecting a libvirt guest name on the command line") in -- Input_libvirt.input_libvirt dcpath password input_conn guest -+ Input_libvirt.input_libvirt dcpath vddk_options password input_conn guest - - | `LibvirtXML -> - (* -i libvirtxml: Expecting a filename (XML file). *) -diff --git a/v2v/input_libvirt.ml b/v2v/input_libvirt.ml -index 0bc386430..e8143b6ad 100644 ---- a/v2v/input_libvirt.ml -+++ b/v2v/input_libvirt.ml -@@ -27,7 +27,7 @@ open Types - open Utils - - (* Choose the right subclass based on the URI. *) --let input_libvirt dcpath password libvirt_uri guest = -+let input_libvirt dcpath vddk_options password libvirt_uri guest = - match libvirt_uri with - | None -> - Input_libvirt_other.input_libvirt_other password libvirt_uri guest -@@ -47,10 +47,18 @@ let input_libvirt dcpath password libvirt_uri guest = - | Some _, Some "" -> - Input_libvirt_other.input_libvirt_other password libvirt_uri guest - -- (* vCenter over https *) -+ (* vCenter over https, or -+ * vCenter or ESXi using nbdkit vddk plugin -+ *) - | Some server, Some ("esx"|"gsx"|"vpx" as scheme) -> -- Input_libvirt_vcenter_https.input_libvirt_vcenter_https -- dcpath password libvirt_uri parsed_uri scheme server guest -+ (match vddk_options with -+ | None -> -+ Input_libvirt_vcenter_https.input_libvirt_vcenter_https -+ dcpath password libvirt_uri parsed_uri scheme server guest -+ | Some vddk_options -> -+ Input_libvirt_vddk.input_libvirt_vddk vddk_options password -+ libvirt_uri parsed_uri guest -+ ) - - (* Xen over SSH *) - | Some server, Some ("xen+ssh" as scheme) -> -diff --git a/v2v/input_libvirt.mli b/v2v/input_libvirt.mli -index f5e6314d9..0a6aa3c54 100644 ---- a/v2v/input_libvirt.mli -+++ b/v2v/input_libvirt.mli -@@ -18,7 +18,7 @@ - - (** [-i libvirt] source. *) - --val input_libvirt : string option -> string option -> string option -> string -> Types.input --(** [input_libvirt dcpath password libvirt_uri guest] creates and returns a -- new {!Types.input} object specialized for reading input from -- libvirt sources. *) -+val input_libvirt : string option -> Types.vddk_options option -> string option -> string option -> string -> Types.input -+(** [input_libvirt dcpath vddk_options password libvirt_uri guest] creates -+ and returns a new {!Types.input} object specialized for reading input -+ from libvirt sources. *) -diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml -new file mode 100644 -index 000000000..89d2552f6 ---- /dev/null -+++ b/v2v/input_libvirt_vddk.ml -@@ -0,0 +1,314 @@ -+(* virt-v2v -+ * Copyright (C) 2009-2017 Red Hat Inc. -+ * -+ * 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. -+ *) -+ -+(** [-i libvirt] when the source is VMware via nbdkit vddk plugin *) -+ -+open Unix -+ -+open Common_gettext.Gettext -+open Common_utils -+open Unix_utils -+ -+open Types -+open Utils -+open Input_libvirt_other -+open Parse_libvirt_xml -+open Xpath_helpers -+ -+open Printf -+ -+(* Subclass specialized for handling VMware via nbdkit vddk plugin. *) -+class input_libvirt_vddk vddk_options password libvirt_uri parsed_uri guest = -+ -+ (* The VDDK path. *) -+ let libdir = vddk_options.vddk_libdir in -+ (* Compute the LD_LIBRARY_PATH that we must pass to nbdkit. *) -+ let library_path = libdir // sprintf "lib%d" Sys.word_size in -+ -+ (* Is SELinux enabled and enforcing on the host? *) -+ let have_selinux = -+ 0 = Sys.command "getenforce 2>/dev/null | grep -isq Enforcing" in -+ -+ (* Check that the VDDK path looks reasonable. *) -+ let error_unless_vddk_libdir () = -+ if not (is_directory libdir) then -+ error (f_"‘--vddk %s’ does not point to a directory. See \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") libdir; -+ -+ if not (is_directory library_path) then -+ error (f_"VDDK library path %s not found or not a directory. See \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") -+ library_path -+ in -+ -+ (* Check that nbdkit is available and new enough. *) -+ let error_unless_nbdkit_working () = -+ if 0 <> Sys.command "nbdkit --version >/dev/null" then -+ error (f_"nbdkit is not installed or not working. It is required to use ‘--vddk’. See \"INPUT FROM VDDK\" in the virt-v2v(1) manual."); -+ -+ (* Check it's a new enough version. The latest features we -+ * require are ‘--exit-with-parent’ and ‘--selinux-label’, both -+ * added in 1.1.14. -+ *) -+ let lines = external_command "nbdkit --help" in -+ let lines = String.concat " " lines in -+ if String.find lines "exit-with-parent" == -1 || -+ String.find lines "selinux-label" == -1 then -+ error (f_"nbdkit is not new enough, you need to upgrade to nbdkit ≥ 1.1.14") -+ in -+ -+ (* Check that the VDDK plugin is installed and working *) -+ let error_unless_nbdkit_vddk_working () = -+ let cmd = -+ sprintf "LD_LIBRARY_PATH=%s nbdkit vddk --dump-plugin >/dev/null" -+ (quote library_path) in -+ if Sys.command cmd <> 0 then ( -+ (* See if we can diagnose why ... *) -+ let cmd = -+ sprintf "LD_LIBRARY_PATH=%s LANG=C nbdkit vddk --dump-plugin 2>&1 | grep -sq libvixDiskLib.so" -+ (quote library_path) in -+ let needs_library = Sys.command cmd = 0 in -+ if not needs_library then -+ error (f_"nbdkit VDDK plugin is not installed or not working. It is required if you want to use VDDK. -+ -+The VDDK plugin is not enabled by default when you compile nbdkit. You have to read the instructions in the nbdkit sources under ‘plugins/vddk/README.VDDK’ to find out how to enable the VDDK plugin. -+ -+See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") -+ else -+ error (f_"nbdkit VDDK plugin is not installed or not working. It is required if you want to use VDDK. -+ -+It looks like you did not set the right path in the ‘--vddk’ option, or your copy of the VDDK directory is incomplete. There should be a library called ’%s/libvixDiskLib.so.?’. -+ -+See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") library_path -+ ) -+ in -+ -+ let error_unless_thumbprint () = -+ if vddk_options.vddk_thumbprint = None then -+ error (f_"You must pass the ‘--vddk-thumbprint’ option with the SSL thumbprint of the VMware server. To find the thumbprint, see the nbdkit-vddk-plugin(1) manual. See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") -+ in -+ -+object -+ inherit input_libvirt password libvirt_uri guest -+ -+ method source () = -+ error_unless_vddk_libdir (); -+ error_unless_nbdkit_working (); -+ error_unless_nbdkit_vddk_working (); -+ error_unless_thumbprint (); -+ -+ (* Get the libvirt XML. This also checks (as a side-effect) -+ * that the domain is not running. (RHBZ#1138586) -+ *) -+ let xml = Libvirt_utils.dumpxml ?password ?conn:libvirt_uri guest in -+ let source, disks = parse_libvirt_xml ?conn:libvirt_uri xml in -+ -+ (* Find the element from the XML. This was added -+ * in libvirt >= 3.7 and is required. -+ *) -+ let moref = -+ let doc = Xml.parse_memory xml in -+ let xpathctx = Xml.xpath_new_context doc in -+ Xml.xpath_register_ns xpathctx -+ "vmware" "http://libvirt.org/schemas/domain/vmware/1.0"; -+ let xpath_string = xpath_string xpathctx in -+ match xpath_string "/domain/vmware:moref" with -+ | Some moref -> moref -+ | None -> -+ error (f_" was not found in the output of ‘virsh dumpxml \"%s\"’. The most likely reason is that libvirt is too old, try upgrading libvirt to ≥ 3.7.") guest in -+ -+ (* Create a temporary directory where we place the sockets and -+ * password file. -+ *) -+ let tmpdir = -+ let base_dir = (open_guestfs ())#get_cachedir () in -+ let t = Mkdtemp.temp_dir ~base_dir "vddk." in -+ (* tmpdir must be readable (but not writable) by "other" so that -+ * qemu can open the sockets. If we place a password file in -+ * this directory then we'll chmod that to 0600 below. -+ *) -+ chmod t 0o755; -+ rmdir_on_exit t; -+ t in -+ -+ (* Start constructing the parts of the incredibly long nbdkit -+ * command line which don't change between disks. -+ *) -+ let args = -+ let add_arg, get_args = -+ let args = ref [] in -+ let add_arg a = push_front a args in -+ let get_args () = List.rev !args in -+ add_arg, get_args in -+ -+ (* It probably never happens that the server name can be missing -+ * from the libvirt URI, but we need a server name to pass to -+ * nbdkit, so ... -+ *) -+ let server = -+ match parsed_uri.Xml.uri_server with -+ | Some server -> server -+ | None -> -+ match libvirt_uri with -+ | Some libvirt_uri -> -+ error (f_"‘-ic %s’ URL does not contain a host name field") -+ libvirt_uri -+ | None -> -+ error (f_"you must use the ‘-ic’ parameter. See \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") in -+ -+ (* Similar to above, we also need a username to pass. *) -+ let user = -+ match parsed_uri.Xml.uri_user with -+ | Some user -> user -+ | None -> "root" (* ? *) in -+ -+ add_arg "nbdkit"; -+ if verbose () then add_arg "--verbose"; -+ add_arg "--readonly"; (* important! readonly mode *) -+ add_arg "--foreground"; (* run in foreground *) -+ add_arg "--exit-with-parent"; (* exit when virt-v2v exits *) -+ add_arg "--newstyle"; (* use newstyle NBD protocol *) -+ add_arg "--exportname"; add_arg "/"; -+ if have_selinux then ( (* label the socket so qemu can open it *) -+ add_arg "--selinux-label"; add_arg "system_u:object_r:svirt_t:s0" -+ ); -+ -+ (* Name of the plugin. Everything following is a plugin parameter. *) -+ add_arg "vddk"; -+ -+ let password_param = -+ match password with -+ | None -> -+ (* nbdkit asks for the password interactively *) -+ "password=-" -+ | Some password -> -+ let password_file = tmpdir // "password" in -+ let chan = open_out password_file in -+ chmod password_file 0o600; -+ output_string chan password; -+ close_out chan; -+ (* nbdkit reads the password from the file *) -+ "password=+" ^ password_file in -+ add_arg (sprintf "server=%s" server); -+ add_arg (sprintf "user=%s" user); -+ add_arg password_param; -+ add_arg (sprintf "vm=moref=%s" moref); -+ add_arg (sprintf "libdir=%s" libdir); -+ -+ (* The passthrough parameters. *) -+ let pt name = may (fun field -> add_arg (sprintf "%s=%s" name field)) in -+ pt "config" vddk_options.vddk_config; -+ pt "cookie" vddk_options.vddk_cookie; -+ pt "nfchostport" vddk_options.vddk_nfchostport; -+ pt "port" vddk_options.vddk_port; -+ pt "snapshot" vddk_options.vddk_snapshot; -+ pt "thumbprint" vddk_options.vddk_thumbprint; -+ pt "transports" vddk_options.vddk_transports; -+ pt "vimapiver" vddk_options.vddk_vimapiver; -+ -+ get_args () in -+ -+ (* Create an nbdkit instance for each disk and rewrite the source -+ * paths to point to the NBD socket. -+ *) -+ let disks = List.map ( -+ function -+ | { p_source_disk = disk; p_source = P_dont_rewrite } -> -+ disk -+ -+ | { p_source = P_source_dev _ } -> (* Should never happen. *) -+ error (f_"source disk has attribute in XML") -+ -+ | { p_source_disk = disk; p_source = P_source_file path } -> -+ (* The attribute returned by the libvirt -+ * VMX driver looks like "[datastore] path". We can use it -+ * directly as the nbdkit file= parameter, and it is passed -+ * directly in this form to VDDK. -+ *) -+ -+ let sock = tmpdir // sprintf "nbdkit%d.sock" disk.s_disk_id in -+ let qemu_uri = sprintf "nbd:unix:%s:exportname=/" sock in -+ -+ let pidfile = tmpdir // sprintf "nbdkit%d.pid" disk.s_disk_id in -+ -+ (* Construct the final command line with the "static" args -+ * above plus the args which vary for each disk. -+ *) -+ let args = -+ args @ [ "--pidfile"; pidfile; -+ "--unix"; sock; -+ sprintf "file=%s" path ] in -+ let args = Array.of_list args in -+ -+ (* Start an nbdkit instance in the background. By using -+ * --exit-with-parent we don't have to worry about cleaning -+ * it up, hopefully. -+ *) -+ let pid = fork () in -+ if pid = 0 then ( -+ (* Child process (nbdkit). *) -+ putenv "LD_LIBRARY_PATH" library_path; -+ execvp "nbdkit" args -+ ); -+ -+ (* Wait for the pidfile to appear so we know that nbdkit -+ * is listening for requests. -+ *) -+ let rec loop i = -+ if i = 0 then false -+ else if Sys.file_exists pidfile then true -+ else ( -+ sleep 1; -+ loop (i-1) -+ ) -+ in -+ if not (loop 30) then ( -+ if verbose () then -+ error (f_"nbdkit did not start up. See previous debugging messages for problems.") -+ else -+ error (f_"nbdkit did not start up. There may be errors printed by nbdkit above. -+ -+If the messages above are not sufficient to diagnose the problem then add the ‘virt-v2v -v -x’ options and examine the debugging output carefully.") -+ ); -+ -+ if have_selinux then ( -+ (* Note that Unix domain sockets have both a file label and -+ * a socket/process label. Using --selinux-label above -+ * only set the socket label, but we must also set the file -+ * label. -+ *) -+ ignore ( -+ run_command ["chcon"; "system_u:object_r:svirt_image_t:s0"; -+ sock] -+ ); -+ ); -+ (* ... and the regular Unix permissions, in case qemu is -+ * running as another user. -+ *) -+ chmod sock 0o777; -+ -+ { disk with s_qemu_uri = qemu_uri } -+ ) disks in -+ -+ if verbose () then ( -+ eprintf "vddk: tmpdir %s:\n%!" tmpdir; -+ ignore (Sys.command (sprintf "ls -laZ %s" (quote tmpdir))) -+ ); -+ -+ { source with s_disks = disks } -+end -+ -+let input_libvirt_vddk = new input_libvirt_vddk -diff --git a/v2v/input_libvirt_vddk.mli b/v2v/input_libvirt_vddk.mli -new file mode 100644 -index 000000000..19a34c202 ---- /dev/null -+++ b/v2v/input_libvirt_vddk.mli -@@ -0,0 +1,24 @@ -+(* virt-v2v -+ * Copyright (C) 2017 Red Hat Inc. -+ * -+ * 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. -+ *) -+ -+(** [-i libvirt] when the source is VMware via nbdkit vddk plugin *) -+ -+val input_libvirt_vddk : Types.vddk_options -> string option -> string option -> Xml.uri -> string -> Types.input -+(** [input_libvirt_vddk vddk_options password libvirt_uri 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/types.ml b/v2v/types.ml -index 3efb9ff46..4f9205aa0 100644 ---- a/v2v/types.ml -+++ b/v2v/types.ml -@@ -472,6 +472,18 @@ type root_choice = AskRoot | SingleRoot | FirstRoot | RootDev of string - - type output_allocation = Sparse | Preallocated - -+type vddk_options = { -+ vddk_libdir : string; -+ vddk_config : string option; -+ vddk_cookie : string option; -+ vddk_nfchostport : string option; -+ vddk_port : string option; -+ vddk_snapshot : string option; -+ vddk_thumbprint : string option; -+ vddk_transports : string option; -+ vddk_vimapiver : string option; -+} -+ - class virtual input = object - method precheck () = () - method virtual as_options : string -diff --git a/v2v/types.mli b/v2v/types.mli -index 2880546ae..087a03702 100644 ---- a/v2v/types.mli -+++ b/v2v/types.mli -@@ -328,6 +328,19 @@ type root_choice = AskRoot | SingleRoot | FirstRoot | RootDev of string - type output_allocation = Sparse | Preallocated - (** Type of [-oa] (output allocation) option. *) - -+type vddk_options = { -+ vddk_libdir : string; -+ vddk_config : string option; -+ vddk_cookie : string option; -+ vddk_nfchostport : string option; -+ vddk_port : string option; -+ vddk_snapshot : string option; -+ vddk_thumbprint : string option; -+ vddk_transports : string option; -+ vddk_vimapiver : string option; -+} -+(** Various options passed through to the nbdkit vddk plugin unmodified. *) -+ - (** {2 Input object} - - There is one of these used for the [-i] option. *) -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 77b6f514f..d713d0b1f 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -514,6 +514,35 @@ boot an operating system from the first VirtIO disk. Specifically, - F must be on the first VirtIO disk, and it cannot chainload an - OS which is not in the first VirtIO disk. - -+=item B<--vddk> LIBDIR -+ -+Enable VDDK input from VMware vCenter or ESXi. C is the top -+directory of the VDDK library. This directory should I -+subdirectories called F, F etc., but do not include -+F actually in the parameter. -+ -+See L below for details. -+ -+=item B<--vddk-config> FILENAME -+ -+=item B<--vddk-cookie> COOKIE -+ -+=item B<--vddk-nfchostport> PORT -+ -+=item B<--vddk-port> PORT -+ -+=item B<--vddk-snapshot> SNAPSHOT-MOREF -+ -+=item B<--vddk-thumbprint> xx:xx:xx:... -+ -+=item B<--vddk-transports> MODE:MODE:... -+ -+=item B<--vddk-vimapiver> APIVER -+ -+When using VDDK mode, these options are passed unmodified to the -+L VDDK plugin. Please refer to L. -+Only I<--vddk-thumbprint> is required, the others are optional. -+ - =item B<--vdsm-compat=0.10> - - =item B<--vdsm-compat=1.1> -@@ -1270,6 +1299,130 @@ Perform the conversion of the guest using virt-v2v: - - Remove the F and F files. - -+=head1 INPUT FROM VDDK -+ -+Virt-v2v is able to import guests using VMware’s proprietary VDDK -+library (a.k.a. VixDiskLib). -+ -+=head2 VDDK: PREREQUISITES -+ -+=over 4 -+ -+=item 1. -+ -+As the VDDK library is not open source, and the license of this -+library does not permit redistribution or commercial use, you must -+obtain VDDK yourself and satisfy yourself that your usage of the -+library is permitted by the license. -+ -+=item 2. -+ -+You must also compile nbdkit, enabling the VDDK plugin. At least -+nbdkit E 1.1.14 is required, but it is usually best to compile -+from the git tree. -+ -+=over 4 -+ -+=item * -+ -+L -+ -+=item * -+ -+L -+ -+=back -+ -+=item 3. -+ -+You can run nbdkit from its source directory without needing to -+install it. Set C<$PATH> to include the nbdkit top build directory -+(the directory containing a shell script called F): -+ -+ export PATH=/path/to/nbdkit:$PATH -+ -+=item 4. -+ -+You must find the SSL "thumbprint" of your VMware server. How to do -+this is explained in L, also available at the -+link given in item 2 above. -+ -+=item 5. -+ -+VDDK imports require a feature added in libvirt E 3.7. -+ -+=back -+ -+=head2 VDDK: URI -+ -+Construct the correct C (for vCenter) or C (for ESXi) -+URL. It will look something like these: -+ -+ vpx://root@vcenter.example.com/Datacenter/esxi -+ -+ esx://root@esxi.example.com -+ -+To verify that you have the correct URL, use the L command -+to list the guests on the server: -+ -+ $ virsh -c 'vpx://root@vcenter.example.com/Datacenter/esxi' list --all -+ Enter root's password for vcenter.example.com: *** -+ -+ Id Name State -+ ---------------------------------------------------- -+ - Fedora 20 shut off -+ - Windows 2003 shut off -+ -+If you get an error "Peer certificate cannot be authenticated with -+given CA certificates" or similar, then you can either import the -+vCenter host’s certificate, or bypass signature verification by adding -+the C flag: -+ -+ $ virsh -c 'vpx://root@vcenter.example.com/Datacenter/esxi?no_verify=1' list --all -+ -+You should also try dumping the metadata from any guest on your -+server, like this: -+ -+ $ virsh -c 'vpx://root@vcenter.example.com/Datacenter/esxi' dumpxml "Windows 2003" -+ -+ Windows 2003 -+ [...] -+ vm-123 -+ -+ -+If Cvmware:morefE> does not appear in the metadata, then you -+need to upgrade libvirt. -+ -+B. Fix your URI and/or your VMware server before -+continuing. -+ -+=head2 VDDK: IMPORTING A GUEST -+ -+To import a particular guest from vCenter server or ESXi hypervisor, -+use a command like the following, substituting the URI, guest name and -+SSL thumbprint: -+ -+ $ export PATH=/path/to/nbdkit:$PATH -+ $ virt-v2v \ -+ -ic 'vpx://root@vcenter.example.com/Datacenter/esxi?no_verify=1' \ -+ --vddk /path/to/vmware-vix-disklib-distrib \ -+ --vddk-thumbprint xx:xx:xx:... \ -+ "Windows 2003" \ -+ -o local -os /var/tmp -+ -+Other options that you might need to add in rare circumstances include -+I<--vddk-config>, I<--vddk-cookie>, I<--vddk-nfchostport>, -+I<--vddk-port>, I<--vddk-snapshot>, I<--vddk-transports> and -+I<--vddk-vimapiver>, which are all explained in the -+L documentation. -+ -+=head2 VDDK: DEBUGGING VDDK FAILURES -+ -+The VDDK library can be operated in a verbose mode where it gives -+(very) verbose messages. Use ‘virt-v2v -v -x’ as usual to enable -+verbose messages. -+ - =head1 INPUT FROM XEN - - Virt-v2v is able to import Xen guests from RHEL 5 Xen hosts. -@@ -2032,6 +2185,8 @@ L, - L, - L, - L, -+L, -+L, - L. - - =head1 AUTHORS --- -2.14.3 - diff --git a/SOURCES/0035-v2v-cmdline-Move-definition-to-before-its-only-use.patch b/SOURCES/0035-v2v-cmdline-Move-definition-to-before-its-only-use.patch new file mode 100644 index 0000000..5ccda9a --- /dev/null +++ b/SOURCES/0035-v2v-cmdline-Move-definition-to-before-its-only-use.patch @@ -0,0 +1,35 @@ +From 128f7736445649001261195b5dfeb0e7d34bbedc Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 22 Mar 2018 10:28:36 +0000 +Subject: [PATCH] v2v: cmdline: Move definition to before its only use. + +(cherry picked from commit 3167ce1f91667de4c4fe1885bb33c06ee6fa38c5) +--- + v2v/cmdline.ml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index bfdc250fc..9bd0e8afc 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -81,7 +81,6 @@ let parse_cmdline () = + let set_vdsm_compat s = vdsm_compat := s in + + let vdsm_ovf_flavour = ref Create_ovf.RHVExportStorageDomain in +- let ovf_flavours_str = String.concat "|" Create_ovf.ovf_flavours in + let set_vdsm_ovf_flavour arg = + vdsm_ovf_flavour := Create_ovf.ovf_flavour_of_string arg in + +@@ -183,7 +182,8 @@ let parse_cmdline () = + let i_options = + String.concat "|" (Modules_list.input_modules ()) + and o_options = +- String.concat "|" (Modules_list.output_modules ()) in ++ String.concat "|" (Modules_list.output_modules ()) ++ and ovf_flavours_str = String.concat "|" Create_ovf.ovf_flavours in + + let argspec = [ + [ S 'b'; L"bridge" ], Getopt.String ("in:out", add_bridge), +-- +2.17.1 + diff --git a/SOURCES/0036-s390x-launch-libvirt-Use-console-device-sclp-for-app.patch b/SOURCES/0036-s390x-launch-libvirt-Use-console-device-sclp-for-app.patch deleted file mode 100644 index e149135..0000000 --- a/SOURCES/0036-s390x-launch-libvirt-Use-console-device-sclp-for-app.patch +++ /dev/null @@ -1,50 +0,0 @@ -From c73e6d1e2dcbcf2c7b17096953e48bc5a84ee7d2 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 16 May 2017 20:12:54 +0200 -Subject: [PATCH] s390x: launch: libvirt: Use device sclp for - appliance debug messages (RHBZ#1376547). - -Thanks: Cole Robinson, Dan Horak, Thomas Huth. -(cherry picked from commit 6328f332361675abb0233db890d2bfe0d9a5092a) ---- - lib/launch-libvirt.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c -index 681281b9b..49bd40583 100644 ---- a/lib/launch-libvirt.c -+++ b/lib/launch-libvirt.c -@@ -1347,6 +1347,7 @@ construct_libvirt_xml_devices (guestfs_h *g, - return -1; - } - -+#ifndef __s390x__ - /* Console. */ - start_element ("serial") { - attribute ("type", "unix"); -@@ -1358,6 +1359,22 @@ construct_libvirt_xml_devices (guestfs_h *g, - attribute ("port", "0"); - } end_element (); - } end_element (); -+#else -+ /* https://bugzilla.redhat.com/show_bug.cgi?id=1376547#c14 -+ * and https://libvirt.org/formatdomain.html#elementCharConsole -+ */ -+ start_element ("console") { -+ attribute ("type", "unix"); -+ start_element ("source") { -+ attribute ("mode", "connect"); -+ attribute ("path", params->data->console_path); -+ } end_element (); -+ start_element ("target") { -+ attribute ("type", "sclp"); -+ attribute ("port", "0"); -+ } end_element (); -+ } end_element (); -+#endif - - /* Virtio-serial for guestfsd communication. */ - start_element ("channel") { --- -2.14.3 - diff --git a/SOURCES/0036-v2v-Add-general-mechanism-for-input-and-output-optio.patch b/SOURCES/0036-v2v-Add-general-mechanism-for-input-and-output-optio.patch new file mode 100644 index 0000000..0c69429 --- /dev/null +++ b/SOURCES/0036-v2v-Add-general-mechanism-for-input-and-output-optio.patch @@ -0,0 +1,1269 @@ +From 390f01ad72c9846a71d721d68ddab4535c77bb4d Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 22 Mar 2018 10:29:23 +0000 +Subject: [PATCH] v2v: Add general mechanism for input and output options + (-io/-oo). + +Currently we have a bunch of ad hoc options like --vddk* and --vdsm* +(and proposed to add --rhv*) to handle extra parameters for input and +output modes/transports. This complicates the command line parsing +and also the clarity of the command line (becauseit's not very obvious +which options apply to which side of the conversion). + +Replace these with a general mechanism for handling input and output +options. + +Thus (for example): + + --vddk-thumbprint=... becomes -io vddk-thumbprint=... + --vdsm-compat=0.10 -oo vdsm-compat=0.10 + +The responsibility for parsing input and output options moves into the +input and output drivers. + +This improves error checking so it's harder now for wrong flags to be +included on the command line when they don't apply to the current mode. + +The old option names are preserved for compatibility. + +(cherry picked from commit 6327e716cdd2f161bc639733f216a3a29d26ad3c) +--- + v2v/Makefile.am | 4 + + v2v/cmdline.ml | 229 ++++++++++++++------------- + v2v/input_libvirt.ml | 4 +- + v2v/input_libvirt.mli | 4 +- + v2v/input_libvirt_vddk.ml | 112 +++++++++----- + v2v/input_libvirt_vddk.mli | 16 +- + v2v/output_vdsm.ml | 79 +++++++++- + v2v/output_vdsm.mli | 13 +- + v2v/test-v2v-docs.sh | 32 +++- + v2v/test-v2v-it-vddk-io-query.sh | 38 +++++ + v2v/test-v2v-o-vdsm-oo-query.sh | 38 +++++ + v2v/test-v2v-o-vdsm-options.sh | 16 +- + v2v/virt-v2v.pod | 258 ++++++++++++++++--------------- + 13 files changed, 531 insertions(+), 312 deletions(-) + create mode 100755 v2v/test-v2v-it-vddk-io-query.sh + create mode 100755 v2v/test-v2v-o-vdsm-oo-query.sh + +diff --git a/v2v/Makefile.am b/v2v/Makefile.am +index 424530b1d..5fcfeadba 100644 +--- a/v2v/Makefile.am ++++ b/v2v/Makefile.am +@@ -307,6 +307,8 @@ TESTS = \ + test-v2v-i-ova-tar.sh \ + test-v2v-i-ova-two-disks.sh \ + test-v2v-i-vmx.sh \ ++ test-v2v-it-vddk-io-query.sh \ ++ test-v2v-o-vdsm-oo-query.sh \ + test-v2v-bad-networks-and-bridges.sh + + if HAVE_LIBVIRT +@@ -468,6 +470,7 @@ EXTRA_DIST += \ + test-v2v-i-vmx-3.vmx \ + test-v2v-i-vmx-4.vmx \ + test-v2v-i-vmx-5.vmx \ ++ test-v2v-it-vddk-io-query.sh \ + test-v2v-machine-readable.sh \ + test-v2v-networks-and-bridges-expected.xml \ + test-v2v-networks-and-bridges.sh \ +@@ -478,6 +481,7 @@ EXTRA_DIST += \ + test-v2v-o-null.sh \ + test-v2v-o-qemu.sh \ + test-v2v-o-rhv.sh \ ++ test-v2v-o-vdsm-oo-query.sh \ + test-v2v-o-vdsm-options.sh \ + test-v2v-oa-option.sh \ + test-v2v-of-option.sh \ +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index 9bd0e8afc..c9b859dd6 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -65,24 +65,6 @@ let parse_cmdline () = + let output_password = ref None in + let output_storage = ref None in + let password_file = ref None in +- let vddk_config = ref None in +- let vddk_cookie = ref None in +- let vddk_libdir = ref None in +- let vddk_nfchostport = ref None in +- let vddk_port = ref None in +- let vddk_snapshot = ref None in +- let vddk_thumbprint = ref None in +- let vddk_transports = ref None in +- let vddk_vimapiver = ref None in +- let vdsm_vm_uuid = ref None in +- let vdsm_ovf_output = ref None in (* default "." *) +- +- let vdsm_compat = ref "0.10" in +- let set_vdsm_compat s = vdsm_compat := s in +- +- let vdsm_ovf_flavour = ref Create_ovf.RHVExportStorageDomain in +- let set_vdsm_ovf_flavour arg = +- vdsm_ovf_flavour := Create_ovf.ovf_flavour_of_string arg in + + let set_string_option_once optname optref arg = + match !optref with +@@ -106,6 +88,15 @@ let parse_cmdline () = + error (f_"unknown -i option: %s") s + in + ++ let input_options = ref [] in ++ let set_input_option_compat k v = ++ input_options := (k, v) :: !input_options ++ in ++ let set_input_option option = ++ let k, v = String.split "=" option in ++ set_input_option_compat k v ++ in ++ + let network_map = ref NetworkMap.empty in + let add_network, add_bridge = + let add flag name t str = +@@ -159,6 +150,15 @@ let parse_cmdline () = + error (f_"unknown -oa option: %s") s + in + ++ let output_options = ref [] in ++ let set_output_option_compat k v = ++ output_options := (k, v) :: !output_options ++ in ++ let set_output_option option = ++ let k, v = String.split "=" option in ++ set_output_option_compat k v ++ in ++ + let root_choice = ref AskRoot in + let set_root_choice = function + | "ask" -> root_choice := AskRoot +@@ -169,12 +169,6 @@ let parse_cmdline () = + error (f_"unknown --root option: %s") s + in + +- let vdsm_image_uuids = ref [] in +- let add_vdsm_image_uuid s = List.push_front s vdsm_image_uuids in +- +- let vdsm_vol_uuids = ref [] in +- let add_vdsm_vol_uuid s = List.push_front s vdsm_vol_uuids in +- + let vmtype_warning _ = + warning (f_"the --vmtype option has been removed and now does nothing") + in +@@ -198,6 +192,8 @@ let parse_cmdline () = + s_"Libvirt URI"; + [ M"if" ], Getopt.String ("format", set_string_option_once "-if" input_format), + s_"Input format (for -i disk)"; ++ [ M"io" ], Getopt.String ("option[=value]", set_input_option), ++ s_"Set option for input mode"; + [ M"it" ], Getopt.String ("transport", set_string_option_once "-it" input_transport), + s_"Input transport"; + [ L"in-place" ], Getopt.Set in_place, Getopt.hidden_option_description; +@@ -219,6 +215,8 @@ let parse_cmdline () = + s_"Set output format"; + [ M"on" ], Getopt.String ("name", set_string_option_once "-on" output_name), + s_"Rename guest when converting"; ++ [ M"oo" ], Getopt.String ("option[=value]", set_output_option), ++ s_"Set option for output mode"; + [ M"op" ], Getopt.String ("filename", set_string_option_once "-op" output_password), + s_"Use password from file to connect to output hypervisor"; + [ M"os" ], Getopt.String ("storage", set_string_option_once "-os" output_storage), +@@ -229,36 +227,36 @@ let parse_cmdline () = + s_"Print source and stop"; + [ L"root" ], Getopt.String ("ask|... ", set_root_choice), + s_"How to choose root filesystem"; +- [ L"vddk-config" ], Getopt.String ("filename", set_string_option_once "--vddk-config" vddk_config), +- s_"Set VDDK config file"; +- [ L"vddk-cookie" ], Getopt.String ("cookie", set_string_option_once "--vddk-cookie" vddk_cookie), +- s_"Set VDDK cookie"; +- [ L"vddk-libdir" ], Getopt.String ("libdir", set_string_option_once "--vddk-libdir" vddk_libdir), +- s_"Set VDDK library parent directory"; +- [ L"vddk-nfchostport" ], Getopt.String ("nfchostport", set_string_option_once "--vddk-nfchostport" vddk_nfchostport), +- s_"Set VDDK nfchostport"; +- [ L"vddk-port" ], Getopt.String ("port", set_string_option_once "--vddk-port" vddk_port), +- s_"Set VDDK port"; +- [ L"vddk-snapshot" ], Getopt.String ("snapshot-moref", set_string_option_once "--vddk-snapshot" vddk_snapshot), +- s_"Set VDDK snapshot"; +- [ L"vddk-thumbprint" ], Getopt.String ("thumbprint", set_string_option_once "--vddk-thumbprint" vddk_thumbprint), +- s_"Set VDDK thumbprint"; +- [ L"vddk-transports" ], Getopt.String ("transports", set_string_option_once "--vddk-transports" vddk_transports), +- s_"Set VDDK transports"; +- [ L"vddk-vimapiver" ], Getopt.String ("apiver", set_string_option_once "--vddk-vimapiver" vddk_vimapiver), +- s_"Set VDDK vimapiver"; +- [ L"vdsm-compat" ], Getopt.Symbol ("0.10|1.1", ["0.10"; "1.1"], set_vdsm_compat), +- s_"Write qcow2 with compat=0.10|1.1"; +- [ L"vdsm-image-uuid" ], Getopt.String ("uuid", add_vdsm_image_uuid), +- s_"Output image UUID(s)"; +- [ L"vdsm-vol-uuid" ], Getopt.String ("uuid", add_vdsm_vol_uuid), +- s_"Output vol UUID(s)"; +- [ L"vdsm-vm-uuid" ], Getopt.String ("uuid", set_string_option_once "--vdsm-vm-uuid" vdsm_vm_uuid), +- s_"Output VM UUID"; +- [ L"vdsm-ovf-output" ], Getopt.String ("-", set_string_option_once "--vdsm-ovf-output" vdsm_ovf_output), +- s_"Output OVF file"; +- [ L"vdsm-ovf-flavour" ], Getopt.Symbol (ovf_flavours_str, Create_ovf.ovf_flavours, set_vdsm_ovf_flavour), +- s_"Set the type of generated OVF (default rhvexp)"; ++ [ L"vddk-config" ], Getopt.String ("filename", set_input_option_compat "vddk-config"), ++ s_"Same as ‘-io vddk-config=filename’"; ++ [ L"vddk-cookie" ], Getopt.String ("cookie", set_input_option_compat "vddk-cookie"), ++ s_"Same as ‘-io vddk-cookie=filename’"; ++ [ L"vddk-libdir" ], Getopt.String ("libdir", set_input_option_compat "vddk-libdir"), ++ s_"Same as ‘-io vddk-libdir=libdir’"; ++ [ L"vddk-nfchostport" ], Getopt.String ("nfchostport", set_input_option_compat "vddk-nfchostport"), ++ s_"Same as ‘-io vddk-nfchostport=nfchostport’"; ++ [ L"vddk-port" ], Getopt.String ("port", set_input_option_compat "vddk-port"), ++ s_"Same as ‘-io vddk-port=port’"; ++ [ L"vddk-snapshot" ], Getopt.String ("snapshot-moref", set_input_option_compat "vddk-snapshot"), ++ s_"Same as ‘-io vddk-snapshot=snapshot-moref’"; ++ [ L"vddk-thumbprint" ], Getopt.String ("thumbprint", set_input_option_compat "vddk-thumbprint"), ++ s_"Same as ‘-io vddk-thumbprint=thumbprint’"; ++ [ L"vddk-transports" ], Getopt.String ("transports", set_input_option_compat "vddk-transports"), ++ s_"Same as ‘-io vddk-transports=transports’"; ++ [ L"vddk-vimapiver" ], Getopt.String ("apiver", set_input_option_compat "vddk-vimapiver"), ++ s_"Same as ‘-io vddk-vimapiver=apiver’"; ++ [ L"vdsm-compat" ], Getopt.String ("0.10|1.1", set_output_option_compat "vdsm-compat"), ++ s_"Same as ‘-oo vdsm-compat=0.10|1.1’"; ++ [ L"vdsm-image-uuid" ], Getopt.String ("uuid", set_output_option_compat "vdsm-image-uuid"), ++ s_"Same as ‘-oo vdsm-image-uuid=uuid’"; ++ [ L"vdsm-vol-uuid" ], Getopt.String ("uuid", set_output_option_compat "vdsm-vol-uuid"), ++ s_"Same as ‘-oo vdsm-vol-uuid=uuid’"; ++ [ L"vdsm-vm-uuid" ], Getopt.String ("uuid", set_output_option_compat "vdsm-vm-uuid"), ++ s_"Same as ‘-oo vdsm-vm-uuid=uuid’"; ++ [ L"vdsm-ovf-output" ], Getopt.String ("dir", set_output_option_compat "vdsm-ovf-output"), ++ s_"Same as ‘-oo vdsm-ovf-output=dir’"; ++ [ L"vdsm-ovf-flavour" ], Getopt.String (ovf_flavours_str, set_output_option_compat "vdsm-ovf-flavour"), ++ s_"Same as ‘-oo vdsm-ovf-flavour=flavour’"; + [ L"vmtype" ], Getopt.String ("-", vmtype_warning), + s_"Ignored for backwards compatibility"; + ] in +@@ -297,6 +295,7 @@ read the man page virt-v2v(1). + let input_conn = !input_conn in + let input_format = !input_format in + let input_mode = !input_mode in ++ let input_options = List.rev !input_options in + let input_transport = + match !input_transport with + | None -> None +@@ -315,28 +314,13 @@ read the man page virt-v2v(1). + let output_format = !output_format in + let output_mode = !output_mode in + let output_name = !output_name in ++ let output_options = List.rev !output_options in + let output_password = !output_password in + let output_storage = !output_storage in + let password_file = !password_file in + let print_source = !print_source in + let qemu_boot = !qemu_boot in + let root_choice = !root_choice in +- let vddk_options = +- { Input_libvirt_vddk.vddk_config = !vddk_config; +- vddk_cookie = !vddk_cookie; +- vddk_libdir = !vddk_libdir; +- vddk_nfchostport = !vddk_nfchostport; +- vddk_port = !vddk_port; +- vddk_snapshot = !vddk_snapshot; +- vddk_thumbprint = !vddk_thumbprint; +- vddk_transports = !vddk_transports; +- vddk_vimapiver = !vddk_vimapiver } in +- let vdsm_compat = !vdsm_compat in +- let vdsm_image_uuids = List.rev !vdsm_image_uuids in +- let vdsm_vol_uuids = List.rev !vdsm_vol_uuids in +- let vdsm_vm_uuid = !vdsm_vm_uuid in +- let vdsm_ovf_output = Option.default "." !vdsm_ovf_output in +- let vdsm_ovf_flavour = !vdsm_ovf_flavour in + + (* No arguments and machine-readable mode? Print out some facts + * about what this binary supports. +@@ -349,6 +333,7 @@ read the man page virt-v2v(1). + printf "vddk\n"; + printf "colours-option\n"; + printf "vdsm-compat-option\n"; ++ printf "io/oo\n"; + List.iter (printf "input:%s\n") (Modules_list.input_modules ()); + List.iter (printf "output:%s\n") (Modules_list.output_modules ()); + List.iter (printf "convert:%s\n") (Modules_list.convert_modules ()); +@@ -356,6 +341,65 @@ read the man page virt-v2v(1). + exit 0 + ); + ++ (* Input transport affects whether some input options should or ++ * should not be used. ++ *) ++ let input_transport = ++ let is_query = input_options = ["?", ""] in ++ let no_options () = ++ if is_query then ( ++ printf (f_"No -io (input options) are supported with this input transport.\n"); ++ exit 0 ++ ) ++ else if input_options <> [] then ++ error (f_"no -io (input options) are allowed here"); ++ in ++ match input_transport with ++ | None -> no_options (); None ++ | Some `SSH -> no_options (); Some `SSH ++ | Some `VDDK -> ++ if is_query then ( ++ Input_libvirt_vddk.print_input_options (); ++ exit 0 ++ ) ++ else ( ++ let vddk_options = ++ Input_libvirt_vddk.parse_input_options input_options in ++ Some (`VDDK vddk_options) ++ ) in ++ ++ (* Output mode affects whether some output options should or ++ * should not be used. ++ *) ++ let output_mode = ++ let is_query = output_options = ["?", ""] in ++ let no_options () = ++ if is_query then ( ++ printf (f_"No -oo (output options) are supported in this output mode.\n"); ++ exit 0 ++ ) ++ else if output_options <> [] then ++ error (f_"no -oo (output options) are allowed here"); ++ in ++ match output_mode with ++ | `Not_set -> no_options (); `Not_set ++ | `Glance -> no_options (); `Glance ++ | `Libvirt -> no_options (); `Libvirt ++ | `Local -> no_options (); `Local ++ | `Null -> no_options (); `Null ++ | `RHV -> no_options (); `RHV ++ | `QEmu -> no_options (); `QEmu ++ | `VDSM -> ++ if is_query then ( ++ Output_vdsm.print_output_options (); ++ exit 0 ++ ) ++ else ( ++ let vdsm_options = ++ Output_vdsm.parse_output_options output_options in ++ `VDSM vdsm_options ++ ) in ++ + (* Parse out the password from the password file. *) + let password = + match password_file with +@@ -364,27 +408,6 @@ read the man page virt-v2v(1). + let password = read_first_line_from_file filename in + Some password in + +- (* Input transport affects whether some parameters should or +- * should not be used. +- *) +- (match input_transport with +- | None +- | Some `SSH -> +- if !vddk_config <> None || +- !vddk_cookie <> None || +- !vddk_libdir <> None || +- !vddk_nfchostport <> None || +- !vddk_port <> None || +- !vddk_snapshot <> None || +- !vddk_thumbprint <> None || +- !vddk_transports <> None || +- !vddk_vimapiver <> None then +- error (f_"‘--vddk-*’ options should only be used when conversion via the nbdkit VDDK plugin has been enabled, ie. using ‘-it vddk’.") +- | Some `VDDK -> +- if !vddk_thumbprint = None then +- error (f_"‘--vddk-thumbprint’ is required when using ‘-it vddk’.") +- ); +- + (* Parsing of the argument(s) depends on the input mode. *) + let input = + match input_mode with +@@ -410,11 +433,10 @@ read the man page virt-v2v(1). + let input_transport = + match input_transport with + | None -> None +- | Some `VDDK -> Some `VDDK ++ | (Some (`VDDK _) as vddk) -> vddk + | Some `SSH -> + error (f_"only ‘-it vddk’ can be used here") in +- Input_libvirt.input_libvirt vddk_options password +- input_conn input_transport guest ++ Input_libvirt.input_libvirt password input_conn input_transport guest + + | `LibvirtXML -> + (* -i libvirtxml: Expecting a filename (XML file). *) +@@ -445,7 +467,7 @@ read the man page virt-v2v(1). + match input_transport with + | None -> None + | Some `SSH -> Some `SSH +- | Some `VDDK -> ++ | Some (`VDDK _) -> + error (f_"only ‘-it ssh’ can be used here") in + Input_vmx.input_vmx input_transport arg in + +@@ -549,7 +571,7 @@ read the man page virt-v2v(1). + Output_rhv.output_rhv os output_alloc, + output_format, output_alloc + +- | `VDSM -> ++ | `VDSM vdsm_options -> + if output_password <> None then + error_option_cannot_be_used_in_output_mode "vdsm" "-op"; + let os = +@@ -559,21 +581,6 @@ read the man page virt-v2v(1). + | Some d -> d in + if qemu_boot then + error_option_cannot_be_used_in_output_mode "vdsm" "--qemu-boot"; +- let vdsm_vm_uuid = +- match vdsm_vm_uuid with +- | None -> +- error (f_"-o vdsm: --vdsm-image-uuid was not specified") +- | Some s -> s in +- if vdsm_image_uuids = [] || vdsm_vol_uuids = [] then +- error (f_"-o vdsm: either --vdsm-vol-uuid or --vdsm-vm-uuid was not specified"); +- let vdsm_options = { +- Output_vdsm.image_uuids = vdsm_image_uuids; +- vol_uuids = vdsm_vol_uuids; +- vm_uuid = vdsm_vm_uuid; +- ovf_output = vdsm_ovf_output; +- compat = vdsm_compat; +- ovf_flavour = vdsm_ovf_flavour; +- } in + Output_vdsm.output_vdsm os vdsm_options output_alloc, + output_format, output_alloc in + +diff --git a/v2v/input_libvirt.ml b/v2v/input_libvirt.ml +index 25c81b924..377257dc2 100644 +--- a/v2v/input_libvirt.ml ++++ b/v2v/input_libvirt.ml +@@ -27,7 +27,7 @@ open Types + open Utils + + (* Choose the right subclass based on the URI. *) +-let input_libvirt vddk_options password libvirt_uri input_transport guest = ++let input_libvirt password libvirt_uri input_transport guest = + match libvirt_uri with + | None -> + Input_libvirt_other.input_libvirt_other password libvirt_uri guest +@@ -53,7 +53,7 @@ let input_libvirt vddk_options password libvirt_uri input_transport guest = + password libvirt_uri parsed_uri server guest + + (* vCenter or ESXi using nbdkit vddk plugin *) +- | Some server, Some ("esx"|"gsx"|"vpx"), Some `VDDK -> ++ | Some server, Some ("esx"|"gsx"|"vpx"), Some (`VDDK vddk_options) -> + Input_libvirt_vddk.input_libvirt_vddk vddk_options password + libvirt_uri parsed_uri guest + +diff --git a/v2v/input_libvirt.mli b/v2v/input_libvirt.mli +index 6f9162482..08824bb67 100644 +--- a/v2v/input_libvirt.mli ++++ b/v2v/input_libvirt.mli +@@ -18,7 +18,7 @@ + + (** [-i libvirt] source. *) + +-val input_libvirt : Input_libvirt_vddk.vddk_options -> string option -> string option -> [`VDDK] option -> string -> Types.input +-(** [input_libvirt vddk_options password libvirt_uri input_transport guest] ++val input_libvirt : string option -> string option -> [`VDDK of Input_libvirt_vddk.vddk_options] option -> string -> Types.input ++(** [input_libvirt password libvirt_uri input_transport guest] + creates and returns a new {!Types.input} object specialized for reading + input from libvirt sources. *) +diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml +index a53f3e71d..0b3ed7af9 100644 +--- a/v2v/input_libvirt_vddk.ml ++++ b/v2v/input_libvirt_vddk.ml +@@ -33,22 +33,73 @@ open Xpath_helpers + + open Printf + +-type vddk_options = { +- vddk_config : string option; +- vddk_cookie : string option; +- vddk_libdir : string option; +- vddk_nfchostport : string option; +- vddk_port : string option; +- vddk_snapshot : string option; +- vddk_thumbprint : string option; +- vddk_transports : string option; +- vddk_vimapiver : string option; +-} ++type vddk_options = (string * string) list ++ ++(* List of vddk-* input options. *) ++let vddk_option_keys = ++ [ "config"; ++ "cookie"; ++ "libdir"; ++ "nfchostport"; ++ "port"; ++ "snapshot"; ++ "thumbprint"; ++ "transports"; ++ "vimapiver" ] ++ ++let print_input_options () = ++ printf (f_"Input options (-io) which can be used with -it vddk: ++ ++ -io vddk-thumbprint=xx:xx:xx:... ++ VDDK server thumbprint (required) ++ ++All other settings are optional: ++ ++ -io vddk-config=FILE VDDK configuration file ++ -io vddk-cookie=COOKIE VDDK cookie ++ -io vddk-libdir=LIBDIR VDDK library parent directory ++ -io vddk-nfchostport=PORT VDDK nfchostport ++ -io vddk-port=PORT VDDK port ++ -io vddk-snapshot=SNAPSHOT-MOREF ++ VDDK snapshot moref ++ -io vddk-transports=MODE:MODE:.. ++ VDDK transports ++ -io vddk-vimapiver=APIVER VDDK vimapiver ++ ++Refer to nbdkit-vddk-plugin(1) and the VDDK documentation for further ++information on these settings. ++") ++ ++let parse_input_options options = ++ (* Check there are no options we don't understand. Also removes ++ * the "vddk-" prefix from the internal list. ++ *) ++ let options = ++ List.map ( ++ fun (key, value) -> ++ let error_invalid_key () = ++ error (f_"-it vddk: ‘-io %s’ is not a valid input option") key ++ in ++ if not (String.is_prefix key "vddk-") then error_invalid_key (); ++ let key = String.sub key 5 (String.length key-5) in ++ if not (List.mem key vddk_option_keys) then error_invalid_key (); ++ ++ (key, value) ++ ) options in ++ ++ (* Check no option appears twice. *) ++ let keys = List.map fst options in ++ if List.length keys <> List.length (List.sort_uniq keys) then ++ error (f_"-it vddk: duplicate -io options on the command line"); ++ ++ options + + (* Subclass specialized for handling VMware via nbdkit vddk plugin. *) + class input_libvirt_vddk vddk_options password libvirt_uri parsed_uri guest = + (* The VDDK path. *) +- let libdir = vddk_options.vddk_libdir in ++ let libdir = ++ try Some (List.assoc "libdir" vddk_options) ++ with Not_found -> None in + + (* VDDK libraries are located under lib32/ or lib64/ relative to the + * libdir. Note this is unrelated to Linux multilib or multiarch. +@@ -68,7 +119,7 @@ class input_libvirt_vddk vddk_options password libvirt_uri parsed_uri guest = + | None -> () + | Some libdir -> + if not (is_directory libdir) then +- error (f_"‘--vddk-libdir %s’ does not point to a directory. See \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") libdir ++ error (f_"‘-io vddk-libdir=%s’ does not point to a directory. See \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") libdir + ); + + (match library_path with +@@ -122,15 +173,15 @@ See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") + else + error (f_"nbdkit VDDK plugin is not installed or not working. It is required if you want to use VDDK. + +-It looks like you did not set the right path in the ‘--vddk-libdir’ option, or your copy of the VDDK directory is incomplete. There should be a library called ’/%s/libvixDiskLib.so.?’. ++It looks like you did not set the right path in the ‘-io vddk-libdir’ option, or your copy of the VDDK directory is incomplete. There should be a library called ’/%s/libvixDiskLib.so.?’. + + See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") libNN + ) + in + + let error_unless_thumbprint () = +- if vddk_options.vddk_thumbprint = None then +- error (f_"You must pass the ‘--vddk-thumbprint’ option with the SSL thumbprint of the VMware server. To find the thumbprint, see the nbdkit-vddk-plugin(1) manual. See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") ++ if not (List.mem_assoc "thumbprint" vddk_options) then ++ error (f_"You must pass the ‘-io vddk-thumbprint’ option with the SSL thumbprint of the VMware server. To find the thumbprint, see the nbdkit-vddk-plugin(1) manual. See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") + in + + (* Check that nbdkit was compiled with SELinux support (for the +@@ -147,18 +198,6 @@ See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") libNN + 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.") + in + +- (* List of passthrough parameters. *) +- let vddk_passthrus = +- [ "config", (fun { vddk_config } -> vddk_config); +- "cookie", (fun { vddk_cookie } -> vddk_cookie); +- "libdir", (fun { vddk_libdir } -> vddk_libdir); +- "nfchostport", (fun { vddk_nfchostport } -> vddk_nfchostport); +- "port", (fun { vddk_port } -> vddk_port); +- "snapshot", (fun { vddk_snapshot } -> vddk_snapshot); +- "thumbprint", (fun { vddk_thumbprint } -> vddk_thumbprint); +- "transports", (fun { vddk_transports } -> vddk_transports); +- "vimapiver", (fun { vddk_vimapiver } -> vddk_vimapiver) ] in +- + object + inherit input_libvirt password libvirt_uri guest as super + +@@ -172,14 +211,9 @@ object + + method as_options = + let pt_options = +- String.concat "" ( +- List.map ( +- fun (name, get_field) -> +- match get_field vddk_options with +- | None -> "" +- | Some field -> sprintf " --vddk-%s %s" name field +- ) vddk_passthrus +- ) in ++ String.concat "" ++ (List.map (fun (k, v) -> ++ sprintf " -io vddk-%s=%s" k v) vddk_options) in + sprintf "%s -it vddk %s" + super#as_options (* superclass prints "-i libvirt etc" *) + pt_options +@@ -284,11 +318,7 @@ object + add_arg (sprintf "vm=moref=%s" moref); + + (* The passthrough parameters. *) +- List.iter ( +- fun (name, get_field) -> +- Option.may (fun field -> add_arg (sprintf "%s=%s" name field)) +- (get_field vddk_options) +- ) vddk_passthrus; ++ List.iter (fun (k, v) -> add_arg (sprintf "%s=%s" k v)) vddk_options; + + get_args () in + +diff --git a/v2v/input_libvirt_vddk.mli b/v2v/input_libvirt_vddk.mli +index c8606c72a..1cebba506 100644 +--- a/v2v/input_libvirt_vddk.mli ++++ b/v2v/input_libvirt_vddk.mli +@@ -18,19 +18,13 @@ + + (** [-i libvirt] when the source is VMware via nbdkit vddk plugin *) + +-type vddk_options = { +- vddk_config : string option; +- vddk_cookie : string option; +- vddk_libdir : string option; +- vddk_nfchostport : string option; +- vddk_port : string option; +- vddk_snapshot : string option; +- vddk_thumbprint : string option; +- vddk_transports : string option; +- vddk_vimapiver : string option; +-} ++type vddk_options + (** Various options passed through to the nbdkit vddk plugin unmodified. *) + ++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 : vddk_options -> string option -> string option -> Xml.uri -> string -> Types.input + (** [input_libvirt_vddk vddk_options password libvirt_uri parsed_uri guest] + creates and returns a {!Types.input} object specialized for reading +diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml +index b76a2e930..92b3fd122 100644 +--- a/v2v/output_vdsm.ml ++++ b/v2v/output_vdsm.ml +@@ -35,23 +35,90 @@ type vdsm_options = { + ovf_flavour : Create_ovf.ovf_flavour; + } + ++let ovf_flavours_str = String.concat "|" Create_ovf.ovf_flavours ++ ++let print_output_options () = ++ printf (f_"Output options (-oo) which can be used with -o vdsm: ++ ++ -oo vdsm-compat=0.10|1.1 Write qcow2 with compat=0.10|1.1 ++ (default: 0.10) ++ -oo vdsm-vm-uuid=UUID VM UUID (required) ++ -oo vdsm-ovf-output=DIR OVF metadata directory (required) ++ -oo vdsm-ovf-flavour=%s ++ Set the type of generated OVF (default: rhvexp) ++ ++For each disk you must supply one of each of these options: ++ ++ -oo vdsm-image-uuid=UUID Image directory UUID ++ -oo vdsm-vol-uuid=UUID Disk volume UUID ++") ovf_flavours_str ++ ++let parse_output_options options = ++ let vm_uuid = ref None in ++ let ovf_output = ref None in (* default "." *) ++ let compat = ref "0.10" in ++ let ovf_flavour = ref Create_ovf.RHVExportStorageDomain in ++ let image_uuids = ref [] in ++ let vol_uuids = ref [] in ++ ++ List.iter ( ++ function ++ | "vdsm-compat", "0.10" -> compat := "0.10" ++ | "vdsm-compat", "1.1" -> compat := "1.1" ++ | "vdsm-compat", v -> ++ error (f_"-o vdsm: unknown vdsm-compat level ‘%s’") v ++ | "vdsm-vm-uuid", v -> ++ if !vm_uuid <> None then ++ error (f_"-o vdsm: -oo vdsm-vm-uuid set twice"); ++ vm_uuid := Some v; ++ | "vdsm-ovf-output", v -> ++ if !ovf_output <> None then ++ error (f_"-o vdsm: -oo vdsm-ovf-output set twice"); ++ ovf_output := Some v; ++ | "vdsm-ovf-flavour", v -> ++ ovf_flavour := Create_ovf.ovf_flavour_of_string v ++ | "vdsm-image-uuid", v -> ++ List.push_front v image_uuids ++ | "vdsm-vol-uuid", v -> ++ List.push_front v vol_uuids ++ | k, _ -> ++ error (f_"-o vdsm: unknown output option ‘-oo %s’") k ++ ) options; ++ ++ let compat = !compat in ++ let image_uuids = List.rev !image_uuids in ++ let vol_uuids = List.rev !vol_uuids in ++ if image_uuids = [] || vol_uuids = [] then ++ error (f_"-o vdsm: either -oo vdsm-vol-uuid or -oo vdsm-vm-uuid was not specified"); ++ let vm_uuid = ++ match !vm_uuid with ++ | None -> ++ error (f_"-o vdsm: -oo vdsm-image-uuid was not specified") ++ | Some uuid -> uuid in ++ let ovf_output = Option.default "." !ovf_output in ++ let ovf_flavour = !ovf_flavour in ++ ++ { image_uuids; vol_uuids; vm_uuid; ovf_output; compat; ovf_flavour } ++ + class output_vdsm os vdsm_options output_alloc = + object + inherit output + + method as_options = +- sprintf "-o vdsm -os %s%s%s --vdsm-vm-uuid %s --vdsm-ovf-output %s%s%s" os ++ sprintf "-o vdsm -os %s%s%s -oo vdsm-vm-uuid=%s -oo vdsm-ovf-output=%s%s%s" os + (String.concat "" +- (List.map (sprintf " --vdsm-image-uuid %s") vdsm_options.image_uuids)) ++ (List.map (sprintf " -oo vdsm-image-uuid=%s") ++ vdsm_options.image_uuids)) + (String.concat "" +- (List.map (sprintf " --vdsm-vol-uuid %s") vdsm_options.vol_uuids)) ++ (List.map (sprintf " -oo vdsm-vol-uuid=%s") ++ vdsm_options.vol_uuids)) + vdsm_options.vm_uuid + vdsm_options.ovf_output + (match vdsm_options.compat with + | "0.10" -> "" (* currently this is the default, so don't print it *) +- | s -> sprintf " --vdsm-compat=%s" s) ++ | s -> sprintf " -oo vdsm-compat=%s" s) + (match vdsm_options.ovf_flavour with +- | Create_ovf.OVirt -> "--vdsm-ovf-flavour=ovf" ++ | Create_ovf.OVirt -> "-oo vdsm-ovf-flavour=ovf" + (* currently this is the default, so don't print it *) + | Create_ovf.RHVExportStorageDomain -> "") + +@@ -84,7 +151,7 @@ object + method prepare_targets _ targets = + if List.length vdsm_options.image_uuids <> List.length targets || + List.length vdsm_options.vol_uuids <> List.length targets then +- error (f_"the number of ‘--vdsm-image-uuid’ and ‘--vdsm-vol-uuid’ parameters passed on the command line has to match the number of guest disk images (for this guest: %d)") ++ error (f_"the number of ‘-oo vdsm-image-uuid’ and ‘-oo vdsm-vol-uuid’ parameters passed on the command line has to match the number of guest disk images (for this guest: %d)") + (List.length targets); + + let mp, uuid = +diff --git a/v2v/output_vdsm.mli b/v2v/output_vdsm.mli +index 6ed684638..36f327900 100644 +--- a/v2v/output_vdsm.mli ++++ b/v2v/output_vdsm.mli +@@ -18,16 +18,13 @@ + + (** [-o vdsm] target. *) + +-type vdsm_options = { +- image_uuids : string list; (* --vdsm-image-uuid (multiple) *) +- vol_uuids : string list; (* --vdsm-vol-uuid (multiple) *) +- vm_uuid : string; (* --vdsm-vm-uuid *) +- ovf_output : string; (* --vdsm-ovf-output *) +- compat : string; (* --vdsm-compat=0.10|1.1 *) +- ovf_flavour : Create_ovf.ovf_flavour; +-} ++type vdsm_options + (** Miscellaneous extra command line parameters used by VDSM. *) + ++val print_output_options : unit -> unit ++val parse_output_options : (string * string) list -> vdsm_options ++(** Print and parse vdsm -oo options. *) ++ + val output_vdsm : string -> vdsm_options -> Types.output_allocation -> Types.output + (** [output_vdsm os vdsm_options output_alloc] creates and + returns a new {!Types.output} object specialized for writing +diff --git a/v2v/test-v2v-docs.sh b/v2v/test-v2v-docs.sh +index bb1ddefd7..da98050ee 100755 +--- a/v2v/test-v2v-docs.sh ++++ b/v2v/test-v2v-docs.sh +@@ -22,4 +22,34 @@ $TEST_FUNCTIONS + skip_if_skipped + + $top_srcdir/podcheck.pl virt-v2v.pod virt-v2v \ +- --ignore=--debug-overlay,--ic,--if,--in-place,--it,--no-trim,--oa,--oc,--of,--on,--op,--os,--vmtype ++ --ignore=\ ++--debug-overlay,\ ++--ic,\ ++--if,\ ++--in-place,\ ++--io,\ ++--it,\ ++--no-trim,\ ++--oa,\ ++--oc,\ ++--of,\ ++--on,\ ++--oo,\ ++--op,\ ++--os,\ ++--vddk-config,\ ++--vddk-cookie,\ ++--vddk-libdir,\ ++--vddk-nfchostport,\ ++--vddk-port,\ ++--vddk-snapshot,\ ++--vddk-thumbprint,\ ++--vddk-transports,\ ++--vddk-vimapiver,\ ++--vdsm-compat,\ ++--vdsm-image-uuid,\ ++--vdsm-ovf-flavour,\ ++--vdsm-ovf-output,\ ++--vdsm-vm-uuid,\ ++--vdsm-vol-uuid,\ ++--vmtype +diff --git a/v2v/test-v2v-it-vddk-io-query.sh b/v2v/test-v2v-it-vddk-io-query.sh +new file mode 100755 +index 000000000..014e30207 +--- /dev/null ++++ b/v2v/test-v2v-it-vddk-io-query.sh +@@ -0,0 +1,38 @@ ++#!/bin/bash - ++# libguestfs virt-v2v test script ++# Copyright (C) 2018 Red Hat Inc. ++# ++# 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 -io "?" option. ++ ++set -e ++ ++$TEST_FUNCTIONS ++skip_if_skipped ++ ++export VIRT_TOOLS_DATA_DIR="$top_srcdir/test-data/fake-virt-tools" ++export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win" ++ ++f=test-v2v-it-vddk-io-query.actual ++rm -f $f ++ ++$VG virt-v2v --debug-gc \ ++ -it vddk -io "?" > $f ++ ++grep -- "-io vddk-config" $f ++grep -- "-io vddk-thumbprint" $f ++ ++rm $f +diff --git a/v2v/test-v2v-o-vdsm-oo-query.sh b/v2v/test-v2v-o-vdsm-oo-query.sh +new file mode 100755 +index 000000000..5691446ea +--- /dev/null ++++ b/v2v/test-v2v-o-vdsm-oo-query.sh +@@ -0,0 +1,38 @@ ++#!/bin/bash - ++# libguestfs virt-v2v test script ++# Copyright (C) 2018 Red Hat Inc. ++# ++# 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 -oo "?" option. ++ ++set -e ++ ++$TEST_FUNCTIONS ++skip_if_skipped ++ ++export VIRT_TOOLS_DATA_DIR="$top_srcdir/test-data/fake-virt-tools" ++export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win" ++ ++f=test-v2v-o-vdsm-oo-query.actual ++rm -f $f ++ ++$VG virt-v2v --debug-gc \ ++ -o vdsm -oo "?" > $f ++ ++grep -- "-oo vdsm-compat" $f ++grep -- "-oo vdsm-image-uuid" $f ++ ++rm $f +diff --git a/v2v/test-v2v-o-vdsm-options.sh b/v2v/test-v2v-o-vdsm-options.sh +index 4ad5d4aad..65ce1234e 100755 +--- a/v2v/test-v2v-o-vdsm-options.sh ++++ b/v2v/test-v2v-o-vdsm-options.sh +@@ -16,7 +16,7 @@ + # along with this program; if not, write to the Free Software + # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +-# Test -o vdsm options --vdsm-*-uuid ++# Test -o vdsm options -oo vdsm-*-uuid + + set -e + set -x +@@ -44,19 +44,19 @@ mkdir $d/12345678-1234-1234-1234-123456789abc/master + mkdir $d/12345678-1234-1234-1234-123456789abc/master/vms + mkdir $d/12345678-1234-1234-1234-123456789abc/master/vms/VM + +-# The --vdsm-*-uuid options don't actually check that the ++# The -oo vdsm-*-uuid options don't actually check that the + # parameter is a UUID, which is useful here. + + $VG virt-v2v --debug-gc \ + -i libvirt -ic "$libvirt_uri" windows \ + -o vdsm -os $d/12345678-1234-1234-1234-123456789abc \ + -of qcow2 \ +- --vdsm-image-uuid IMAGE \ +- --vdsm-vol-uuid VOL \ +- --vdsm-vm-uuid VM \ +- --vdsm-ovf-output $d/12345678-1234-1234-1234-123456789abc/master/vms/VM \ +- --vdsm-compat=1.1 \ +- --vdsm-ovf-flavour=ovirt ++ -oo vdsm-image-uuid=IMAGE \ ++ -oo vdsm-vol-uuid=VOL \ ++ -oo vdsm-vm-uuid=VM \ ++ -oo vdsm-ovf-output=$d/12345678-1234-1234-1234-123456789abc/master/vms/VM \ ++ -oo vdsm-compat=1.1 \ ++ -oo vdsm-ovf-flavour=ovirt + + # Test the OVF metadata was created. + test -f $d/12345678-1234-1234-1234-123456789abc/master/vms/VM/VM.ovf +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 4df3791a9..5dd888e77 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -273,6 +273,47 @@ 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<-io> OPTION=VALUE ++ ++Set input option(s) related to the current input mode or transport. ++To display short help on what options are available you can use: ++ ++ virt-v2v -it vddk -io "?" ++ ++=item B<-io vddk-libdir=>LIBDIR ++ ++Set the VDDK library directory. This directory should I ++subdirectories called F, F etc., but do not include ++F actually in the parameter. ++ ++In most cases this parameter is required when using the I<-it vddk> ++(VDDK) transport. See L below for details. ++ ++=item B<-io vddk-thumbprint=>xx:xx:xx:... ++ ++Set the thumbprint of the remote VMware server. ++ ++This parameter is required when using the I<-it vddk> (VDDK) transport. ++See L below for details. ++ ++=item B<-io vddk-config=>FILENAME ++ ++=item B<-io vddk-cookie=>COOKIE ++ ++=item B<-io vddk-nfchostport=>PORT ++ ++=item B<-io vddk-port=>PORT ++ ++=item B<-io vddk-snapshot=>SNAPSHOT-MOREF ++ ++=item B<-io vddk-transports=>MODE:MODE:... ++ ++=item B<-io vddk-vimapiver=>APIVER ++ ++When using VDDK mode, these options are passed unmodified to the ++L VDDK plugin. Please refer to L. ++These are all optional. ++ + =item B<-it> B + + When using I<-i vmx>, this enables the ssh transport. +@@ -282,7 +323,7 @@ See L below. + + Use VMware VDDK as a transport to copy the input disks. See + L below. If you use this parameter then you may +-need to use other I<--vddk*> options to specify how to connect through ++need to use other I<-io vddk*> options to specify how to connect through + VDDK. + + =item B<--keys-from-stdin> +@@ -442,6 +483,95 @@ If not specified, then the input format is used. + Rename the guest when converting it. If this option is not used then + the output name is the same as the input name. + ++=item B<-oo> OPTION=VALUE ++ ++Set output option(s) related to the current output mode. ++To display short help on what options are available you can use: ++ ++ virt-v2v -o vdsm -oo "?" ++ ++=item B<-oo vdsm-compat=0.10> ++ ++=item B<-oo vdsm-compat=1.1> ++ ++If I<-o vdsm> and the output format is qcow2, then we add the qcow2 ++I option to the output file for compatibility with RHEL 6 ++(see L). ++ ++If I<-oo vdsm-compat=1.1> is used then modern qcow2 (I) ++files are generated instead. ++ ++Currently I<-oo vdsm-compat=0.10> is the default, but this will change ++to I<-oo vdsm-compat=1.1> in a future version of virt-v2v (when we can ++assume that everyone is using a modern version of qemu). ++ ++B output>. All other output ++modes (including I<-o rhv>) generate modern qcow2 I ++files, always. ++ ++If this option is available, then C will appear in ++the I<--machine-readable> output. ++ ++=item B<-oo vdsm-image-uuid=>UUID ++ ++=item B<-oo vdsm-vol-uuid=>UUID ++ ++=item B<-oo vdsm-vm-uuid=>UUID ++ ++=item B<-oo vdsm-ovf-output=>DIR ++ ++Normally the RHV output mode chooses random UUIDs for the target ++guest. However VDSM needs to control the UUIDs and passes these ++parameters when virt-v2v runs under VDSM control. The parameters ++control: ++ ++=over 4 ++ ++=item * ++ ++the image directory of each guest disk (I<-oo vdsm-image-uuid>) (this ++option is passed once for each guest disk) ++ ++=item * ++ ++UUIDs for each guest disk (I<-oo vdsm-vol-uuid>) (this option ++is passed once for each guest disk) ++ ++=item * ++ ++the OVF file name (I<-oo vdsm-vm-uuid>). ++ ++=item * ++ ++the OVF output directory (default current directory) (I<-oo vdsm-ovf-output>). ++ ++=back ++ ++The format of UUIDs is: C<12345678-1234-1234-1234-123456789abc> (each ++hex digit can be C<0-9> or C), conforming to S. ++ ++These options can only be used with I<-o vdsm>. ++ ++=item B<-oo vdsm-ovf-flavour=>flavour ++ ++This option controls the format of the OVF generated at the end of conversion. ++Currently there are two possible flavours: ++ ++=over 4 ++ ++=item rhevexp ++ ++The OVF format used in RHV export storage domain. ++ ++=item ovirt ++ ++The OVF format understood by oVirt REST API. ++ ++=back ++ ++For backward compatibility the default is I, but this may change in ++the future. ++ + =item B<-op> file + + Supply a file containing a password to be used when connecting to the +@@ -538,122 +668,6 @@ boot an operating system from the first virtio disk. Specifically, + F must be on the first virtio disk, and it cannot chainload an + OS which is not in the first virtio disk. + +-=item B<--vddk-libdir> LIBDIR +- +-Set the VDDK library directory. This directory should I +-subdirectories called F, F etc., but do not include +-F actually in the parameter. +- +-In most cases this parameter is required when using the I<-it vddk> +-(VDDK) transport. See L below for details. +- +-=item B<--vddk-thumbprint> xx:xx:xx:... +- +-Set the thumbprint of the remote VMware server. +- +-This parameter is required when using the I<-it vddk> (VDDK) transport. +-See L below for details. +- +-=item B<--vddk-config> FILENAME +- +-=item B<--vddk-cookie> COOKIE +- +-=item B<--vddk-nfchostport> PORT +- +-=item B<--vddk-port> PORT +- +-=item B<--vddk-snapshot> SNAPSHOT-MOREF +- +-=item B<--vddk-transports> MODE:MODE:... +- +-=item B<--vddk-vimapiver> APIVER +- +-When using VDDK mode, these options are passed unmodified to the +-L VDDK plugin. Please refer to L. +-These are all optional. +- +-=item B<--vdsm-compat=0.10> +- +-=item B<--vdsm-compat=1.1> +- +-If I<-o vdsm> and the output format is qcow2, then we add the qcow2 +-I option to the output file for compatibility with RHEL 6 +-(see L). +- +-If I<--vdsm-compat=1.1> is used then modern qcow2 (I) +-files are generated instead. +- +-Currently I<--vdsm-compat=0.10> is the default, but this will change +-to I<--vdsm-compat=1.1> in a future version of virt-v2v (when we can +-assume that everyone is using a modern version of qemu). +- +-B output>. All other output +-modes (including I<-o rhv>) generate modern qcow2 I +-files, always. +- +-If this option is available, then C will appear in +-the I<--machine-readable> output. +- +-=item B<--vdsm-image-uuid> UUID +- +-=item B<--vdsm-vol-uuid> UUID +- +-=item B<--vdsm-vm-uuid> UUID +- +-=item B<--vdsm-ovf-output> +- +-Normally the RHV output mode chooses random UUIDs for the target +-guest. However VDSM needs to control the UUIDs and passes these +-parameters when virt-v2v runs under VDSM control. The parameters +-control: +- +-=over 4 +- +-=item * +- +-the image directory of each guest disk (I<--vdsm-image-uuid>) (this +-option is passed once for each guest disk) +- +-=item * +- +-UUIDs for each guest disk (I<--vdsm-vol-uuid>) (this option +-is passed once for each guest disk) +- +-=item * +- +-the OVF file name (I<--vdsm-vm-uuid>). +- +-=item * +- +-the OVF output directory (default current directory) (I<--vdsm-ovf-output>). +- +-=back +- +-The format of UUIDs is: C<12345678-1234-1234-1234-123456789abc> (each +-hex digit can be C<0-9> or C), conforming to S. +- +-These options can only be used with I<-o vdsm>. +- +-=item B<--vdsm-ovf-flavour> flavour +- +-This option controls the format of the OVF generated at the end of conversion. +-Currently there are two possible flavours: +- +-=over 4 +- +-=item rhevexp +- +-The OVF format used in RHV export storage domain. +- +-=item ovirt +- +-The OVF format understood by oVirt REST API. +- +-=back +- +-For backward compatibility the default is I, but this may change in +-the future. +- + =item B<-v> + + =item B<--verbose> +@@ -1528,15 +1542,15 @@ SSL thumbprint: + $ virt-v2v \ + -ic 'vpx://root@vcenter.example.com/Datacenter/esxi?no_verify=1' \ + -it vddk \ +- --vddk-libdir /path/to/vmware-vix-disklib-distrib \ +- --vddk-thumbprint xx:xx:xx:... \ ++ -io vddk-libdir=/path/to/vmware-vix-disklib-distrib \ ++ -io vddk-thumbprint=xx:xx:xx:... \ + "Windows 2003" \ + -o local -os /var/tmp + + Other options that you might need to add in rare circumstances include +-I<--vddk-config>, I<--vddk-cookie>, I<--vddk-nfchostport>, +-I<--vddk-port>, I<--vddk-snapshot>, I<--vddk-transports> and +-I<--vddk-vimapiver>, which are all explained in the ++I<-io vddk-config>, I<-io vddk-cookie>, I<-io vddk-nfchostport>, ++I<-io vddk-port>, I<-io vddk-snapshot>, I<-io vddk-transports> and ++I<-io vddk-vimapiver>, which are all explained in the + L documentation. + + =head2 VDDK: DEBUGGING VDDK FAILURES +-- +2.17.1 + diff --git a/SOURCES/0037-s390x-launch-direct-Use-sclp-as-serial-console-on-th.patch b/SOURCES/0037-s390x-launch-direct-Use-sclp-as-serial-console-on-th.patch deleted file mode 100644 index a4346dd..0000000 --- a/SOURCES/0037-s390x-launch-direct-Use-sclp-as-serial-console-on-th.patch +++ /dev/null @@ -1,37 +0,0 @@ -From f774a2efed860774ba3a8e47e8ac81eeed2508fa Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 17 May 2017 12:16:07 +0200 -Subject: [PATCH] s390x: launch: direct: Use sclp as serial console on this - architecture. - -The same change to the direct backend as made to the libvirt backend -in the previous commit. - -(cherry picked from commit ade2652bdac16656ba4ed821d74528a6de188fa0) ---- - lib/launch-direct.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/lib/launch-direct.c b/lib/launch-direct.c -index 9cc153b21..147e158de 100644 ---- a/lib/launch-direct.c -+++ b/lib/launch-direct.c -@@ -592,8 +592,15 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - ADD_CMDLINE (VIRTIO_SERIAL); - - /* Create the serial console. */ -+#ifndef __s390x__ - ADD_CMDLINE ("-serial"); - ADD_CMDLINE ("stdio"); -+#else -+ ADD_CMDLINE ("-chardev"); -+ ADD_CMDLINE ("stdio,id=charconsole0"); -+ ADD_CMDLINE ("-device"); -+ ADD_CMDLINE ("sclpconsole,chardev=charconsole0"); -+#endif - - if (g->verbose && - guestfs_int_qemu_supports_device (g, data->qemu_data, --- -2.14.3 - diff --git a/SOURCES/0037-v2v-OVF-write-ovirt-id-attribute-for-the-OS-in-OVirt.patch b/SOURCES/0037-v2v-OVF-write-ovirt-id-attribute-for-the-OS-in-OVirt.patch new file mode 100644 index 0000000..fb45111 --- /dev/null +++ b/SOURCES/0037-v2v-OVF-write-ovirt-id-attribute-for-the-OS-in-OVirt.patch @@ -0,0 +1,247 @@ +From b9b146315156b0debe6902cdcd93f0dbe49370f0 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Wed, 4 Apr 2018 18:18:32 +0200 +Subject: [PATCH] v2v: OVF: write ovirt:id attribute for the OS in OVirt + flavour + +When writing the OVF in OVirt flavour, add a ovirt:id attribute to the +OperatingSystemSection tag: this attribute represents the numeric value +of the ostype ID, which is ignored by oVirt when parsing OVFs in API +mode. + +(cherry picked from commit 593a19cc86cfa8f24c66518c8ba21222550b066a) +--- + v2v/create_ovf.ml | 202 +++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 201 insertions(+), 1 deletion(-) + +diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml +index bf3741e0f..ccde960df 100644 +--- a/v2v/create_ovf.ml ++++ b/v2v/create_ovf.ml +@@ -242,6 +242,203 @@ and get_ostype = function + typ distro major minor arch product; + "Unassigned" + ++(* Determine the ovirt:id attribute from libguestfs inspection. ++ * See ovirt-engine sources, file: ++ * packaging/conf/osinfo-defaults.properties ++ * and also: ++ * https://bugzilla.redhat.com/show_bug.cgi?id=1219857#c9 ++ *) ++and get_ovirt_osid = function ++ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 3; ++ i_arch = "i386" } -> ++ 9 ++ ++ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 3; ++ i_arch = "x86_64" } -> ++ 15 ++ ++ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 4; ++ i_arch = "i386" } -> ++ 8 ++ ++ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 4; ++ i_arch = "x86_64" } -> ++ 14 ++ ++ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 5; ++ i_arch = "i386" } -> ++ 7 ++ ++ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 5; ++ i_arch = "x86_64" } -> ++ 13 ++ ++ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 6; ++ i_arch = "i386" } -> ++ 18 ++ ++ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 6; ++ i_arch = "x86_64" } -> ++ 19 ++ ++ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 6; ++ i_minor_version = min; i_arch = ("ppc64"|"ppc64le") } when min >= 9 -> ++ 1007 ++ ++ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 6; ++ i_arch = ("ppc64"|"ppc64le") } -> ++ 1003 ++ ++ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 7; ++ i_arch = "x86_64" } -> ++ 24 ++ ++ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 7; ++ i_arch = ("ppc64"|"ppc64le") } -> ++ 1006 ++ ++ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 7; ++ i_arch = "s390x" } -> ++ 2003 ++ ++ | { i_type = "linux"; i_distro = "sles"; i_major_version = maj; ++ i_arch = "x86_64" } when maj >= 11 -> ++ 1193 ++ ++ | { i_type = "linux"; i_distro = "sles"; i_major_version = maj; ++ i_arch = ("ppc64"|"ppc64le") } when maj >= 11 -> ++ 1004 ++ ++ | { i_type = "linux"; i_distro = "sles"; i_major_version = maj; ++ i_arch = "s390x" } when maj >= 12 -> ++ 2004 ++ ++ (* Only Debian 7 is available, so use it for any 7+ version. *) ++ | { i_type = "linux"; i_distro = "debian"; i_major_version = v } ++ when v >= 7 -> ++ 1300 ++ ++ (* Only Ubuntu 12.04 to 14.04 are available, so use them starting ++ * from 12.04, and 14.04 for anything after it. ++ *) ++ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = v; ++ i_arch = ("ppc64"|"ppc64le") } when v >= 14 -> ++ 1005 ++ ++ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = v; ++ i_arch = "s390x" } when v >= 16 -> ++ 2005 ++ ++ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = v } ++ when v >= 14 -> ++ 1256 ++ ++ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = 12; ++ i_minor_version = 4 } -> ++ 1252 ++ ++ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = 12; ++ i_minor_version = 10 } -> ++ 1253 ++ ++ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = 13; ++ i_minor_version = 4 } -> ++ 1254 ++ ++ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = 13; ++ i_minor_version = 10 } -> ++ 1255 ++ ++ | { i_type = "linux"; i_arch = ("ppc64"|"ppc64le") } -> ++ 1002 ++ ++ | { i_type = "linux"; i_arch = "s390x" } -> ++ 2002 ++ ++ | { i_type = "linux" } -> ++ 5 ++ ++ | { i_type = "windows"; i_major_version = 5; i_minor_version = 1 } -> ++ 1 (* no architecture differentiation of XP on RHV *) ++ ++ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2; ++ i_product_name = product } when String.find product "XP" >= 0 -> ++ 1 (* no architecture differentiation of XP on RHV *) ++ ++ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2; ++ i_arch = "i386" } -> ++ 3 ++ ++ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2; ++ i_arch = "x86_64" } -> ++ 10 ++ ++ | { i_type = "windows"; i_major_version = 6; i_minor_version = 0; ++ i_arch = "i386" } -> ++ 4 ++ ++ | { i_type = "windows"; i_major_version = 6; i_minor_version = 0; ++ i_arch = "x86_64" } -> ++ 16 ++ ++ | { i_type = "windows"; i_major_version = 6; i_minor_version = 1; ++ i_arch = "i386" } -> ++ 11 ++ ++ | { i_type = "windows"; i_major_version = 6; i_minor_version = 1; ++ i_arch = "x86_64"; i_product_variant = "Client" } -> ++ 12 ++ ++ | { i_type = "windows"; i_major_version = 6; i_minor_version = 1; ++ i_arch = "x86_64" } -> ++ 17 ++ ++ | { i_type = "windows"; i_major_version = 6; i_minor_version = 2; ++ i_arch = "i386" } -> ++ 20 ++ ++ | { i_type = "windows"; i_major_version = 6; i_minor_version = 2; ++ i_arch = "x86_64"; i_product_variant = "Client" } -> ++ 21 ++ ++ | { i_type = "windows"; i_major_version = 6; i_minor_version = 2; ++ i_arch = "x86_64" } -> ++ 23 ++ ++ (* Treat Windows 8.1 client like Windows 8. See: ++ * https://bugzilla.redhat.com/show_bug.cgi?id=1309580#c4 ++ *) ++ | { i_type = "windows"; i_major_version = 6; i_minor_version = 3; ++ i_arch = "i386"; i_product_variant = "Client" } -> ++ 20 ++ ++ | { i_type = "windows"; i_major_version = 6; i_minor_version = 3; ++ i_arch = "x86_64"; i_product_variant = "Client" } -> ++ 21 ++ ++ | { i_type = "windows"; i_major_version = 6; i_minor_version = 3; ++ i_arch = "x86_64" } -> ++ 23 ++ ++ | { i_type = "windows"; i_major_version = 10; i_minor_version = 0; ++ i_arch = "i386" } -> ++ 26 ++ ++ | { i_type = "windows"; i_major_version = 10; i_minor_version = 0; ++ i_arch = "x86_64"; i_product_variant = "Client" } -> ++ 27 ++ ++ | { i_type = "windows"; i_major_version = 10; i_minor_version = 0; ++ i_arch = "x86_64" } -> ++ 29 ++ ++ | { i_type = typ; i_distro = distro; ++ i_major_version = major; i_minor_version = minor; i_arch = arch; ++ i_product_name = product } -> ++ warning (f_"unknown guest operating system: %s %s %d.%d %s (%s)") ++ typ distro major minor arch product; ++ 0 ++ + (* Set the element based on the source hypervisor. + * https://bugzilla.redhat.com/show_bug.cgi?id=1342398#c6 + * https://gerrit.ovirt.org/#/c/59147/ +@@ -321,6 +518,7 @@ let rec create_ovf source targets guestcaps inspect + "xmlns:vssd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData"; + "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"; + "xmlns:ovf", "http://schemas.dmtf.org/ovf/envelope/1/"; ++ "xmlns:ovirt", "http://www.ovirt.org/ovf"; + "ovf:version", "0.9" + ] [ + Comment generated_by; +@@ -383,8 +581,10 @@ let rec create_ovf source targets guestcaps inspect + ] in + (match ovf_flavour with + | OVirt -> ++ let ovirt_osid = get_ovirt_osid inspect in + e "OperatingSystemSection" ["ovf:id", vm_uuid; +- "ovf:required", "false"] ++ "ovf:required", "false"; ++ "ovirt:id", string_of_int ovirt_osid] + osinfo_subnodes + | RHVExportStorageDomain -> + e "Section" ["ovf:id", vm_uuid; "ovf:required", "false"; +-- +2.17.1 + diff --git a/SOURCES/0038-s390x-appliance-Use-dev-ttysclp0-for-serial-console.patch b/SOURCES/0038-s390x-appliance-Use-dev-ttysclp0-for-serial-console.patch deleted file mode 100644 index 6592e9d..0000000 --- a/SOURCES/0038-s390x-appliance-Use-dev-ttysclp0-for-serial-console.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 1dc3311d91d3d0caa2796ea5b52e07d84b2d3a90 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 17 May 2017 11:24:39 +0200 -Subject: [PATCH] s390x: appliance: Use /dev/ttysclp0 for serial console. - -(cherry picked from commit 5fc76d6d10a1095c9301edbf4716114e4e94882c) ---- - lib/appliance-kcmdline.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/lib/appliance-kcmdline.c b/lib/appliance-kcmdline.c -index 4dde7a865..ff7bda494 100644 ---- a/lib/appliance-kcmdline.c -+++ b/lib/appliance-kcmdline.c -@@ -44,6 +44,8 @@ - #define SERIAL_CONSOLE "console=hvc0 console=ttyS0" - #elif defined(__arm__) || defined(__aarch64__) - #define SERIAL_CONSOLE "console=ttyAMA0" -+#elif defined(__s390x__) -+#define SERIAL_CONSOLE "console=ttysclp0" - #else - #define SERIAL_CONSOLE "console=ttyS0" - #endif --- -2.14.3 - diff --git a/SOURCES/0038-v2v-OVF-fix-ovf-id-for-VirtualSystem-in-OVirt-flavou.patch b/SOURCES/0038-v2v-OVF-fix-ovf-id-for-VirtualSystem-in-OVirt-flavou.patch new file mode 100644 index 0000000..d6159e6 --- /dev/null +++ b/SOURCES/0038-v2v-OVF-fix-ovf-id-for-VirtualSystem-in-OVirt-flavou.patch @@ -0,0 +1,32 @@ +From ffd2b553fd9e1037d25122c6b749e6f4d1632df0 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Thu, 5 Apr 2018 10:28:17 +0200 +Subject: [PATCH] v2v: OVF: fix ovf:id for VirtualSystem in OVirt flavour + +When writing the OVF in OVirt flavour, write the actual UUID of the +VM as ovf:id attribute for , instead of a dummy value. + +Suggested by Arik Hadas in +https://www.redhat.com/archives/libguestfs/2018-April/msg00005.html + +(cherry picked from commit 9dce43931a19510be1b6d21ce67d14a4136ce241) +--- + v2v/create_ovf.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml +index ccde960df..c29b8421c 100644 +--- a/v2v/create_ovf.ml ++++ b/v2v/create_ovf.ml +@@ -688,7 +688,7 @@ let rec create_ovf source targets guestcaps inspect + + (match ovf_flavour with + | OVirt -> +- e "VirtualSystem" ["ovf:id", "out"] !content_subnodes ++ e "VirtualSystem" ["ovf:id", vm_uuid] !content_subnodes + | RHVExportStorageDomain -> + e "Content" ["ovf:id", "out"; "xsi:type", "ovf:VirtualSystem_Type"] + !content_subnodes +-- +2.17.1 + diff --git a/SOURCES/0039-init-Add-comment-that-we-should-consider-using-proc-.patch b/SOURCES/0039-init-Add-comment-that-we-should-consider-using-proc-.patch deleted file mode 100644 index 98cdce5..0000000 --- a/SOURCES/0039-init-Add-comment-that-we-should-consider-using-proc-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 630c80558888131c094c15d8854a527d3c41261f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 17 May 2017 11:38:05 +0200 -Subject: [PATCH] init: Add comment that we should consider using - /proc/consoles. - -Although we can't use it at the moment because it is incorrect -on at least s390x (RHBZ#1351968). - -(cherry picked from commit fa6bc0fd83317d43df38c50bf94966b31024ca35) ---- - appliance/init | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/appliance/init b/appliance/init -index 2c9aecd5f..735ba8946 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -179,6 +179,7 @@ else - # Run virt-rescue shell. - - # Get name of the serial port, from console= passed by libguestfs. -+ # XXX Consider using /proc/consoles - guestfs_serial=$(grep -Eo 'console=[^[:space:]]+' /proc/cmdline | - sed s/console=//) - --- -2.14.3 - diff --git a/SOURCES/0039-v2v-Add-o-rhv-upload-output-mode-RHBZ-1557273.patch b/SOURCES/0039-v2v-Add-o-rhv-upload-output-mode-RHBZ-1557273.patch new file mode 100644 index 0000000..53aebf8 --- /dev/null +++ b/SOURCES/0039-v2v-Add-o-rhv-upload-output-mode-RHBZ-1557273.patch @@ -0,0 +1,1764 @@ +From d7a1c9c0bb074d0e5c1878a38a6b6315d33be89c Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 12 Feb 2018 16:45:02 +0000 +Subject: [PATCH] v2v: Add -o rhv-upload output mode (RHBZ#1557273). +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This adds a new output mode to virt-v2v. virt-v2v -o rhv-upload +streams images directly to an oVirt or RHV >= 4 Data Domain using the +oVirt SDK v4. It is more efficient than -o rhv because it does not +need to go via the Export Storage Domain, and is possible for humans +to use unlike -o vdsm. + +The implementation uses the Python SDK (‘ovirtsdk4’ module). An +nbdkit Python 3 plugin translates NBD calls from qemu into HTTPS +requests to oVirt via the SDK. + +(cherry picked from commit cc04573927cca97de60d544d37467e67c25867a7) +--- + .gitignore | 3 + + TODO | 27 ++ + v2v/Makefile.am | 30 +- + v2v/cmdline.ml | 41 ++ + v2v/embed.sh | 48 +++ + v2v/output_rhv_upload.ml | 401 +++++++++++++++++++ + v2v/output_rhv_upload.mli | 33 ++ + v2v/output_rhv_upload_createvm_source.mli | 19 + + v2v/output_rhv_upload_plugin_source.mli | 19 + + v2v/output_rhv_upload_precheck_source.mli | 19 + + v2v/rhv-upload-createvm.py | 86 +++++ + v2v/rhv-upload-plugin.py | 445 ++++++++++++++++++++++ + v2v/rhv-upload-precheck.py | 73 ++++ + v2v/test-v2v-o-rhv-upload-oo-query.sh | 38 ++ + v2v/test-v2v-python-syntax.sh | 45 +++ + v2v/virt-v2v.pod | 138 ++++++- + 16 files changed, 1447 insertions(+), 18 deletions(-) + create mode 100755 v2v/embed.sh + create mode 100644 v2v/output_rhv_upload.ml + create mode 100644 v2v/output_rhv_upload.mli + create mode 100644 v2v/output_rhv_upload_createvm_source.mli + create mode 100644 v2v/output_rhv_upload_plugin_source.mli + create mode 100644 v2v/output_rhv_upload_precheck_source.mli + create mode 100644 v2v/rhv-upload-createvm.py + create mode 100644 v2v/rhv-upload-plugin.py + create mode 100644 v2v/rhv-upload-precheck.py + create mode 100755 v2v/test-v2v-o-rhv-upload-oo-query.sh + create mode 100755 v2v/test-v2v-python-syntax.sh + +diff --git a/.gitignore b/.gitignore +index e67013478..ecdac6df3 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -671,6 +671,9 @@ Makefile.in + /utils/qemu-speed-test/qemu-speed-test + /v2v/.depend + /v2v/oUnit-* ++/v2v/output_rhv_upload_createvm_source.ml ++/v2v/output_rhv_upload_plugin_source.ml ++/v2v/output_rhv_upload_precheck_source.ml + /v2v/real-*.d/ + /v2v/real-*.img + /v2v/real-*.xml +diff --git a/TODO b/TODO +index 2e37ce67c..d196a3f6b 100644 +--- a/TODO ++++ b/TODO +@@ -570,3 +570,30 @@ Subsecond handling in virt-diff, virt-ls + + Handle nanoseconds properly. You should be able to specify them on + the command line and display them. ++ ++virt-v2v -o rhv-upload ++---------------------- ++ ++* Set or disable the ticket timeout. The default is going to be ++ increased (from current 60 seconds), so maybe we won't have to ++ set it. See also: ++ https://bugzilla.redhat.com/show_bug.cgi?id=1563278 ++ ++* qcow2 cannot be supported yet because there is not yet any ++ concept in imageio of read+write handles. ++ https://bugzilla.redhat.com/show_bug.cgi?id=1563299 ++ ++* preallocated cannot be supported yet because imageio doesn't ++ know how to zero the image efficiently, instead it runs an ++ fallocate process which writes to every block and that takes ++ many minutes. ++ ++* Really check what insecure/rhv_cafile do and implement it correctly. ++ ++* Measure and resolve performance problems. ++ ++* Allocated image size is unknown for v2v uploads, but imageio needs ++ to know it. We pass initial_size == provisioned_size == virtual size. ++ That can't be fixed from the v2v side. ++ ++* There are unresolved issues about how to clean up disks on failure. +diff --git a/v2v/Makefile.am b/v2v/Makefile.am +index 5fcfeadba..affc00a8b 100644 +--- a/v2v/Makefile.am ++++ b/v2v/Makefile.am +@@ -22,12 +22,19 @@ generator_built = \ + uefi.mli + + BUILT_SOURCES = \ +- $(generator_built) ++ $(generator_built) \ ++ output_rhv_upload_createvm_source.ml \ ++ output_rhv_upload_plugin_source.ml \ ++ output_rhv_upload_precheck_source.ml + + EXTRA_DIST = \ + $(SOURCES_MLI) $(SOURCES_ML) $(SOURCES_C) \ + copy_to_local.ml \ + copy_to_local.mli \ ++ embed-code.sh \ ++ rhv-upload-createvm.py \ ++ rhv-upload-plugin.py \ ++ rhv-upload-precheck.py \ + v2v_unit_tests.ml \ + virt-v2v.pod \ + virt-v2v-copy-to-local.pod +@@ -62,6 +69,10 @@ SOURCES_MLI = \ + output_null.mli \ + output_qemu.mli \ + output_rhv.mli \ ++ output_rhv_upload.mli \ ++ output_rhv_upload_createvm_source.mli \ ++ output_rhv_upload_plugin_source.mli \ ++ output_rhv_upload_precheck_source.mli \ + output_vdsm.mli \ + parse_ova.mli \ + parse_ovf_from_ova.mli \ +@@ -116,6 +127,10 @@ SOURCES_ML = \ + output_local.ml \ + output_qemu.ml \ + output_rhv.ml \ ++ output_rhv_upload_createvm_source.ml \ ++ output_rhv_upload_plugin_source.ml \ ++ output_rhv_upload_precheck_source.ml \ ++ output_rhv_upload.ml \ + output_vdsm.ml \ + inspect_source.ml \ + target_bus_assignment.ml \ +@@ -126,6 +141,15 @@ SOURCES_C = \ + libvirt_utils-c.c \ + qemuopts-c.c + ++# These files are generated and contain rhv-upload-*.py embedded as an ++# OCaml string. ++output_rhv_upload_createvm_source.ml: rhv-upload-createvm.py ++ ./embed.sh code $^ $@ ++output_rhv_upload_plugin_source.ml: rhv-upload-plugin.py ++ ./embed.sh code $^ $@ ++output_rhv_upload_precheck_source.ml: rhv-upload-precheck.py ++ ./embed.sh code $^ $@ ++ + if HAVE_OCAML + + bin_PROGRAMS = virt-v2v virt-v2v-copy-to-local +@@ -295,6 +319,7 @@ TESTS_ENVIRONMENT = $(top_builddir)/run --test + + TESTS = \ + test-v2v-docs.sh \ ++ test-v2v-python-syntax.sh \ + test-v2v-i-ova-bad-sha1.sh \ + test-v2v-i-ova-bad-sha256.sh \ + test-v2v-i-ova-formats.sh \ +@@ -308,6 +333,7 @@ TESTS = \ + test-v2v-i-ova-two-disks.sh \ + test-v2v-i-vmx.sh \ + test-v2v-it-vddk-io-query.sh \ ++ test-v2v-o-rhv-upload-oo-query.sh \ + test-v2v-o-vdsm-oo-query.sh \ + test-v2v-bad-networks-and-bridges.sh + +@@ -481,6 +507,7 @@ EXTRA_DIST += \ + test-v2v-o-null.sh \ + test-v2v-o-qemu.sh \ + test-v2v-o-rhv.sh \ ++ test-v2v-o-rhv-upload-oo-query.sh \ + test-v2v-o-vdsm-oo-query.sh \ + test-v2v-o-vdsm-options.sh \ + test-v2v-oa-option.sh \ +@@ -489,6 +516,7 @@ EXTRA_DIST += \ + test-v2v-print-source.expected \ + test-v2v-print-source.sh \ + test-v2v-print-source.xml \ ++ test-v2v-python-syntax.sh \ + test-v2v-conversion-of.sh \ + test-v2v-sound.sh \ + test-v2v-sound.xml \ +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index c9b859dd6..6321eb656 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -133,6 +133,8 @@ let parse_cmdline () = + | "disk" | "local" -> output_mode := `Local + | "null" -> output_mode := `Null + | "ovirt" | "rhv" | "rhev" -> output_mode := `RHV ++ | "ovirt-upload" | "ovirt_upload" | "rhv-upload" | "rhv_upload" -> ++ output_mode := `RHV_Upload + | "qemu" -> output_mode := `QEmu + | "vdsm" -> output_mode := `VDSM + | s -> +@@ -389,6 +391,16 @@ read the man page virt-v2v(1). + | `Null -> no_options (); `Null + | `RHV -> no_options (); `RHV + | `QEmu -> no_options (); `QEmu ++ | `RHV_Upload -> ++ if is_query then ( ++ Output_rhv_upload.print_output_options (); ++ exit 0 ++ ) ++ else ( ++ let rhv_options = ++ Output_rhv_upload.parse_output_options output_options in ++ `RHV_Upload rhv_options ++ ) + | `VDSM -> + if is_query then ( + Output_vdsm.print_output_options (); +@@ -571,6 +583,35 @@ read the man page virt-v2v(1). + Output_rhv.output_rhv os output_alloc, + output_format, output_alloc + ++ | `RHV_Upload rhv_options -> ++ let output_conn = ++ match output_conn with ++ | None -> ++ error (f_"-o rhv-upload: use ‘-oc’ to point to the oVirt or RHV server REST API URL, which is usually https://servername/ovirt-engine/api") ++ | Some oc -> oc in ++ (* Output format / sparse must currently be raw+sparse. We can ++ * change this in future. See TODO file for details. XXX ++ *) ++ if output_alloc <> Sparse || output_format <> Some "raw" then ++ error (f_"-o rhv-upload: currently you must use ‘-of raw’ and you cannot use ‘-oa preallocated’ with this output mode. These restrictions will be loosened in a future version."); ++ (* In theory we could make the password optional in future. *) ++ let output_password = ++ match output_password with ++ | None -> ++ error (f_"-o rhv-upload: output password file was not specified, use ‘-op’ to point to a file which contains the password used to connect to the oVirt or RHV server") ++ | Some op -> op in ++ let os = ++ match output_storage with ++ | None -> ++ error (f_"-o rhv-upload: output storage was not specified, use ‘-os’"); ++ | Some os -> os in ++ if qemu_boot then ++ error_option_cannot_be_used_in_output_mode "rhv-upload" "--qemu-boot"; ++ Output_rhv_upload.output_rhv_upload output_alloc output_conn ++ output_password os ++ rhv_options, ++ output_format, output_alloc ++ + | `VDSM vdsm_options -> + if output_password <> None then + error_option_cannot_be_used_in_output_mode "vdsm" "-op"; +diff --git a/v2v/embed.sh b/v2v/embed.sh +new file mode 100755 +index 000000000..363d7e2b0 +--- /dev/null ++++ b/v2v/embed.sh +@@ -0,0 +1,48 @@ ++#!/bin/bash - ++# Embed code or other content into an OCaml file. ++# Copyright (C) 2018 Red Hat Inc. ++# ++# 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. ++ ++# Embed code or other content into an OCaml file. ++# ++# It is embedded into a string. As OCaml string literals have virtually ++# no restrictions on length or content we only have to escape double ++# quotes for backslash characters. ++ ++if [ $# -ne 3 ]; then ++ echo "embed.sh identifier input output" ++ exit 1 ++fi ++ ++set -e ++set -u ++ ++ident="$1" ++input="$2" ++output="$3" ++ ++rm -f "$output" "$output"-t ++ ++exec >"$output"-t ++ ++echo "(* Generated by embed.sh from $input *)" ++echo ++echo let "$ident" = '"' ++sed -e 's/\(["\]\)/\\\1/g' < "$input" ++echo '"' ++ ++chmod -w "$output"-t ++mv "$output"-t "$output" +diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml +new file mode 100644 +index 000000000..129461242 +--- /dev/null ++++ b/v2v/output_rhv_upload.ml +@@ -0,0 +1,401 @@ ++(* virt-v2v ++ * Copyright (C) 2009-2018 Red Hat Inc. ++ * ++ * 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. ++ *) ++ ++open Printf ++open Unix ++ ++open Std_utils ++open Tools_utils ++open Unix_utils ++open Common_gettext.Gettext ++ ++open Types ++open Utils ++ ++type rhv_options = { ++ rhv_cafile : string; ++ rhv_cluster : string option; ++ rhv_direct : bool; ++ rhv_verifypeer : bool; ++} ++ ++let print_output_options () = ++ printf (f_"Output options (-oo) which can be used with -o rhv-upload: ++ ++ -oo rhv-cafile=CA.PEM Set ‘ca.pem’ certificate bundle filename. ++ -oo rhv-cluster=CLUSTERNAME Set RHV cluster name. ++ -oo rhv-direct[=true|false] Use direct transfer mode (default: false). ++ -oo rhv-verifypeer[=true|false] Verify server identity (default: false). ++") ++ ++let parse_output_options options = ++ let rhv_cafile = ref None in ++ let rhv_cluster = ref None in ++ let rhv_direct = ref false in ++ let rhv_verifypeer = ref false in ++ ++ List.iter ( ++ function ++ | "rhv-cafile", v -> ++ if !rhv_cafile <> None then ++ error (f_"-o rhv-upload: -oo rhv-cafile set twice"); ++ rhv_cafile := Some v ++ | "rhv-cluster", v -> ++ if !rhv_cluster <> None then ++ error (f_"-o rhv-upload: -oo rhv-cluster set twice"); ++ rhv_cluster := Some v ++ | "rhv-direct", "" -> rhv_direct := true ++ | "rhv-direct", v -> rhv_direct := bool_of_string v ++ | "rhv-verifypeer", "" -> rhv_verifypeer := true ++ | "rhv-verifypeer", v -> rhv_verifypeer := bool_of_string v ++ | k, _ -> ++ error (f_"-o rhv-upload: unknown output option ‘-oo %s’") k ++ ) options; ++ ++ let rhv_cafile = ++ match !rhv_cafile with ++ | Some s -> s ++ | None -> ++ error (f_"-o rhv-upload: must use ‘-oo rhv-cafile’ to supply the path to the oVirt or RHV user’s ‘ca.pem’ file") in ++ let rhv_cluster = !rhv_cluster in ++ let rhv_direct = !rhv_direct in ++ let rhv_verifypeer = !rhv_verifypeer in ++ ++ { rhv_cafile; rhv_cluster; rhv_direct; rhv_verifypeer } ++ ++let python3 = "python3" (* Defined by PEP 394 *) ++let pidfile_timeout = 30 ++let finalization_timeout = 5*60 ++ ++class output_rhv_upload output_alloc output_conn ++ output_password output_storage ++ 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 ++ rmdir_on_exit t; ++ t in ++ ++ let diskid_file_of_id id = tmpdir // sprintf "diskid.%d" id in ++ ++ (* Write the Python precheck, plugin and create VM to a temporary file. *) ++ let precheck = ++ let precheck = tmpdir // "rhv-upload-precheck.py" in ++ with_open_out ++ precheck ++ (fun chan -> output_string chan Output_rhv_upload_precheck_source.code); ++ precheck in ++ let plugin = ++ let plugin = tmpdir // "rhv-upload-plugin.py" in ++ with_open_out ++ plugin ++ (fun chan -> output_string chan Output_rhv_upload_plugin_source.code); ++ plugin in ++ let createvm = ++ let createvm = tmpdir // "rhv-upload-createvm.py" in ++ with_open_out ++ createvm ++ (fun chan -> output_string chan Output_rhv_upload_createvm_source.code); ++ createvm in ++ ++ (* Is SELinux enabled and enforcing on the host? *) ++ let have_selinux = ++ 0 = Sys.command "getenforce 2>/dev/null | grep -isq Enforcing" in ++ ++ (* Check that the Python binary is available. *) ++ let error_unless_python_binary_on_path () = ++ try ignore (which python3) ++ with Executable_not_found _ -> ++ error (f_"no python binary called ‘%s’ can be found on the $PATH") ++ python3 ++ in ++ ++ (* Check that nbdkit is available and new enough. *) ++ let error_unless_nbdkit_working () = ++ if 0 <> Sys.command "nbdkit --version >/dev/null" then ++ error (f_"nbdkit is not installed or not working. It is required to use ‘-o rhv-upload’. See \"OUTPUT TO RHV\" in the virt-v2v(1) manual."); ++ ++ (* Check it's a new enough version. The latest features we ++ * require are ‘--exit-with-parent’ and ‘--selinux-label’, both ++ * added in 1.1.14. (We use 1.1.16 as the minimum here because ++ * it also adds the selinux=yes|no flag in --dump-config). ++ *) ++ let lines = external_command "nbdkit --help" in ++ let lines = String.concat " " lines in ++ if String.find lines "exit-with-parent" == -1 || ++ String.find lines "selinux-label" == -1 then ++ error (f_"nbdkit is not new enough, you need to upgrade to nbdkit ≥ 1.1.16") ++ in ++ ++ (* Check that the python3 plugin is installed and working ++ * and can load the plugin script. ++ *) ++ let error_unless_nbdkit_python3_working () = ++ let cmd = sprintf "nbdkit %s %s --dump-plugin >/dev/null" ++ python3 (quote plugin) in ++ if Sys.command cmd <> 0 then ++ error (f_"nbdkit Python 3 plugin is not installed or not working. It is required if you want to use ‘-o rhv-upload’. ++ ++See also \"OUTPUT TO RHV\" in the virt-v2v(1) manual.") ++ in ++ ++ (* Check that nbdkit was compiled with SELinux support (for the ++ * --selinux-label option). ++ *) ++ let error_unless_nbdkit_compiled_with_selinux () = ++ let lines = external_command "nbdkit --dump-config" in ++ (* In nbdkit <= 1.1.15 the selinux attribute was not present ++ * at all in --dump-config output so there was no way to tell. ++ * Ignore this case because there will be an error later when ++ * we try to use the --selinux-label parameter. ++ *) ++ if List.mem "selinux=no" (List.map String.trim lines) then ++ 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.") ++ in ++ ++ (* JSON parameters which are invariant between disks. *) ++ let json_params = [ ++ "verbose", JSON.Bool (verbose ()); ++ ++ "output_conn", JSON.String output_conn; ++ "output_password", JSON.String output_password; ++ "output_storage", JSON.String output_storage; ++ "output_sparse", JSON.Bool (match output_alloc with ++ | Sparse -> true ++ | Preallocated -> false); ++ "rhv_cafile", JSON.String rhv_options.rhv_cafile; ++ "rhv_cluster", ++ JSON.String (Option.default "Default" rhv_options.rhv_cluster); ++ "rhv_direct", JSON.Bool rhv_options.rhv_direct; ++ ++ (* The 'Insecure' flag seems to be a number with various possible ++ * meanings, however we just set it to True/False. ++ * ++ * https://github.com/oVirt/ovirt-engine-sdk/blob/19aa7070b80e60a4cfd910448287aecf9083acbe/sdk/lib/ovirtsdk4/__init__.py#L395 ++ *) ++ "insecure", JSON.Bool (not rhv_options.rhv_verifypeer); ++ ] in ++ ++ (* nbdkit command line args which are invariant between disks. *) ++ let nbdkit_args = ++ let args = [ ++ "nbdkit"; ++ ++ "--foreground"; (* run in foreground *) ++ "--exit-with-parent"; (* exit when virt-v2v exits *) ++ "--newstyle"; (* use newstyle NBD protocol *) ++ "--exportname"; "/"; ++ ++ "python3"; (* use the nbdkit Python 3 plugin *) ++ plugin; (* Python plugin script *) ++ ] in ++ let args = if verbose () then args @ ["--verbose"] else args in ++ let args = ++ (* label the socket so qemu can open it *) ++ if have_selinux then ++ args @ ["--selinux-label"; "system_u:object_r:svirt_t:s0"] ++ else args in ++ args in ++ ++object ++ inherit output ++ ++ method precheck () = ++ error_unless_python_binary_on_path (); ++ error_unless_nbdkit_working (); ++ error_unless_nbdkit_python3_working (); ++ if have_selinux then ++ error_unless_nbdkit_compiled_with_selinux () ++ ++ method as_options = ++ "-o rhv-upload" ^ ++ (match output_alloc with ++ | Sparse -> "" (* default, don't need to print it *) ++ | Preallocated -> " -oa preallocated") ^ ++ sprintf " -oc %s -op %s -os %s" ++ output_conn output_password output_storage ++ ++ method supported_firmware = [ TargetBIOS ] ++ ++ method prepare_targets source targets = ++ let output_name = source.s_name in ++ let json_params = ++ ("output_name", JSON.String output_name) :: json_params in ++ ++ (* Python code prechecks. These can't run in #precheck because ++ * we need to know the name of the virtual machine. ++ *) ++ let json_param_file = tmpdir // "params.json" in ++ with_open_out ++ json_param_file ++ (fun chan -> output_string chan (JSON.string_of_doc json_params)); ++ if run_command [ python3; precheck; json_param_file ] <> 0 then ++ error (f_"failed server prechecks, see earlier errors"); ++ ++ (* Create an nbdkit instance for each disk and set the ++ * target URI to point to the NBD socket. ++ *) ++ List.map ( ++ fun t -> ++ let id = t.target_overlay.ov_source.s_disk_id in ++ let disk_name = sprintf "%s-%03d" output_name id in ++ let json_params = ++ ("disk_name", JSON.String disk_name) :: json_params in ++ ++ let disk_format = ++ match t.target_format with ++ | ("raw" | "qcow2") as fmt -> fmt ++ | _ -> ++ error (f_"rhv-upload: -of %s: Only output format ‘raw’ or ‘qcow2’ is supported. If the input is in a different format then force one of these output formats by adding either ‘-of raw’ or ‘-of qcow2’ on the command line.") ++ t.target_format in ++ let json_params = ++ ("disk_format", JSON.String disk_format) :: json_params in ++ ++ let disk_size = t.target_overlay.ov_virtual_size in ++ let json_params = ++ ("disk_size", JSON.Int64 disk_size) :: json_params in ++ ++ (* Ask the plugin to write the disk ID to a special file. *) ++ let diskid_file = diskid_file_of_id id in ++ let json_params = ++ ("diskid_file", JSON.String diskid_file) :: json_params in ++ ++ (* Write the JSON parameters to a file. *) ++ let json_param_file = tmpdir // sprintf "params%d.json" id in ++ with_open_out ++ json_param_file ++ (fun chan -> output_string chan (JSON.string_of_doc json_params)); ++ ++ let sock = tmpdir // sprintf "nbdkit%d.sock" id in ++ let pidfile = tmpdir // sprintf "nbdkit%d.pid" id in ++ ++ (* Add common arguments to per-target arguments. *) ++ let args = ++ nbdkit_args @ [ "--pidfile"; pidfile; ++ "--unix"; sock; ++ sprintf "params=%s" json_param_file ] in ++ ++ (* Print the full command we are about to run when debugging. *) ++ if verbose () then ( ++ eprintf "running nbdkit:\n"; ++ List.iter (fun arg -> eprintf " %s" (quote arg)) args; ++ prerr_newline () ++ ); ++ ++ (* Start an nbdkit instance in the background. By using ++ * --exit-with-parent we don't have to worry about clean-up. ++ *) ++ let args = Array.of_list args in ++ let pid = fork () in ++ if pid = 0 then ( ++ (* Child process (nbdkit). *) ++ execvp "nbdkit" args ++ ); ++ ++ (* Wait for the pidfile to appear so we know that nbdkit ++ * is listening for requests. ++ *) ++ if not (wait_for_file pidfile pidfile_timeout) then ( ++ if verbose () then ++ error (f_"nbdkit did not start up. See previous debugging messages for problems.") ++ else ++ error (f_"nbdkit did not start up. There may be errors printed by nbdkit above. ++ ++If the messages above are not sufficient to diagnose the problem then add the ‘virt-v2v -v -x’ options and examine the debugging output carefully.") ++ ); ++ ++ if have_selinux then ( ++ (* Note that Unix domain sockets have both a file label and ++ * a socket/process label. Using --selinux-label above ++ * only set the socket label, but we must also set the file ++ * label. ++ *) ++ ignore ( ++ run_command ["chcon"; "system_u:object_r:svirt_image_t:s0"; ++ sock] ++ ); ++ ); ++ (* ... and the regular Unix permissions, in case qemu is ++ * running as another user. ++ *) ++ chmod sock 0o777; ++ ++ (* Tell ‘qemu-img convert’ to write to the nbd socket which is ++ * connected to nbdkit. ++ *) ++ let json_params = [ ++ "file.driver", JSON.String "nbd"; ++ "file.path", JSON.String sock; ++ "file.export", JSON.String "/"; ++ ] in ++ let target_file = ++ TargetURI ("json:" ^ JSON.string_of_doc json_params) in ++ { t with target_file } ++ ) targets ++ ++ method create_metadata source targets _ guestcaps inspect target_firmware = ++ (* Get the UUIDs of each disk image. These files are written ++ * out by the nbdkit plugins on successful finalization of the ++ * transfer. ++ *) ++ let nr_disks = List.length targets in ++ let image_uuids = ++ List.map ( ++ fun t -> ++ let id = t.target_overlay.ov_source.s_disk_id in ++ let diskid_file = diskid_file_of_id id in ++ if not (wait_for_file diskid_file finalization_timeout) then ++ error (f_"transfer of disk %d/%d failed, see earlier error messages") ++ (id+1) nr_disks; ++ let diskid = read_whole_file diskid_file in ++ diskid ++ ) targets in ++ ++ (* We don't have the storage domain UUID, but instead we write ++ * in a magic value which the Python code (which can get it) ++ * will substitute. ++ *) ++ let sd_uuid = "@SD_UUID@" in ++ ++ (* The volume and VM UUIDs are made up. *) ++ let vol_uuids = List.map (fun _ -> uuidgen ()) targets ++ and vm_uuid = uuidgen () in ++ ++ (* Create the metadata. *) ++ let ovf = ++ Create_ovf.create_ovf source targets guestcaps inspect ++ output_alloc ++ sd_uuid image_uuids vol_uuids vm_uuid ++ OVirt in ++ let ovf = DOM.doc_to_string ovf in ++ ++ let json_param_file = tmpdir // "params.json" in ++ with_open_out ++ json_param_file ++ (fun chan -> output_string chan (JSON.string_of_doc json_params)); ++ ++ let ovf_file = tmpdir // "vm.ovf" in ++ with_open_out ovf_file (fun chan -> output_string chan ovf); ++ if run_command [ python3; createvm; json_param_file; ovf_file ] <> 0 then ++ error (f_"failed to create virtual machine, see earlier errors") ++ ++end ++ ++let output_rhv_upload = new output_rhv_upload ++let () = Modules_list.register_output_module "rhv-upload" +diff --git a/v2v/output_rhv_upload.mli b/v2v/output_rhv_upload.mli +new file mode 100644 +index 000000000..f6cd69a61 +--- /dev/null ++++ b/v2v/output_rhv_upload.mli +@@ -0,0 +1,33 @@ ++(* virt-v2v ++ * Copyright (C) 2009-2018 Red Hat Inc. ++ * ++ * 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. ++ *) ++ ++(** [-o rhv-upload] target. *) ++ ++type rhv_options ++(** Miscellaneous extra command line parameters used by rhv-upload. *) ++ ++val print_output_options : unit -> unit ++val parse_output_options : (string * string) list -> rhv_options ++(** Print and parse rhv-upload -oo options. *) ++ ++val output_rhv_upload : Types.output_allocation -> string -> string -> ++ string -> rhv_options -> Types.output ++(** [output_rhv_upload output_alloc output_conn output_password output_storage ++ rhv_options] ++ creates and returns a new {!Types.output} object specialized for writing ++ output to oVirt or RHV directly via RHV APIs. *) +diff --git a/v2v/output_rhv_upload_createvm_source.mli b/v2v/output_rhv_upload_createvm_source.mli +new file mode 100644 +index 000000000..c1bafa15b +--- /dev/null ++++ b/v2v/output_rhv_upload_createvm_source.mli +@@ -0,0 +1,19 @@ ++(* virt-v2v ++ * Copyright (C) 2018 Red Hat Inc. ++ * ++ * 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. ++ *) ++ ++val code : string +diff --git a/v2v/output_rhv_upload_plugin_source.mli b/v2v/output_rhv_upload_plugin_source.mli +new file mode 100644 +index 000000000..c1bafa15b +--- /dev/null ++++ b/v2v/output_rhv_upload_plugin_source.mli +@@ -0,0 +1,19 @@ ++(* virt-v2v ++ * Copyright (C) 2018 Red Hat Inc. ++ * ++ * 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. ++ *) ++ ++val code : string +diff --git a/v2v/output_rhv_upload_precheck_source.mli b/v2v/output_rhv_upload_precheck_source.mli +new file mode 100644 +index 000000000..c1bafa15b +--- /dev/null ++++ b/v2v/output_rhv_upload_precheck_source.mli +@@ -0,0 +1,19 @@ ++(* virt-v2v ++ * Copyright (C) 2018 Red Hat Inc. ++ * ++ * 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. ++ *) ++ ++val code : string +diff --git a/v2v/rhv-upload-createvm.py b/v2v/rhv-upload-createvm.py +new file mode 100644 +index 000000000..a34627ec8 +--- /dev/null ++++ b/v2v/rhv-upload-createvm.py +@@ -0,0 +1,86 @@ ++# -*- python -*- ++# oVirt or RHV upload create VM used by ‘virt-v2v -o rhv-upload’ ++# Copyright (C) 2018 Red Hat Inc. ++# ++# 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. ++ ++import json ++import logging ++import sys ++import time ++ ++from http.client import HTTPSConnection ++from urllib.parse import urlparse ++ ++import ovirtsdk4 as sdk ++import ovirtsdk4.types as types ++ ++# Parameters are passed in via a JSON doc from the OCaml code. ++# Because this Python code ships embedded inside virt-v2v there ++# is no formal API here. ++params = None ++ovf = None # OVF file ++ ++if len(sys.argv) != 3: ++ raise RuntimeError("incorrect number of parameters") ++ ++# Parameters are passed in via a JSON document. ++with open(sys.argv[1], 'r') as fp: ++ params = json.load(fp) ++ ++# What is passed in is a password file, read the actual password. ++with open(params['output_password'], 'r') as fp: ++ output_password = fp.read() ++output_password = output_password.rstrip() ++ ++# Read the OVF document. ++with open(sys.argv[2], 'r') as fp: ++ ovf = fp.read() ++ ++# Parse out the username from the output_conn URL. ++parsed = urlparse(params['output_conn']) ++username = parsed.username or "admin@internal" ++ ++# Connect to the server. ++connection = sdk.Connection( ++ url = params['output_conn'], ++ username = username, ++ password = output_password, ++ ca_file = params['rhv_cafile'], ++ log = logging.getLogger(), ++ insecure = params['insecure'], ++) ++ ++system_service = connection.system_service() ++ ++# Get the storage domain UUID and substitute it into the OVF doc. ++sds_service = system_service.storage_domains_service() ++sd = sds_service.list(search=("name=%s" % params['output_storage']))[0] ++sd_uuid = sd.id ++ ++ovf.replace("@SD_UUID@", sd_uuid) ++ ++vms_service = system_service.vms_service() ++vm = vms_service.add( ++ types.Vm( ++ cluster=types.Cluster(name = params['rhv_cluster']), ++ initialization=types.Initialization( ++ configuration = types.Configuration( ++ type = types.ConfigurationType.OVA, ++ data = ovf, ++ ) ++ ) ++ ) ++) +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +new file mode 100644 +index 000000000..791c9e7d2 +--- /dev/null ++++ b/v2v/rhv-upload-plugin.py +@@ -0,0 +1,445 @@ ++# -*- python -*- ++# oVirt or RHV upload nbdkit plugin used by ‘virt-v2v -o rhv-upload’ ++# Copyright (C) 2018 Red Hat Inc. ++# ++# 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. ++ ++import builtins ++import json ++import logging ++import ssl ++import sys ++import time ++ ++from http.client import HTTPSConnection ++from urllib.parse import urlparse ++ ++import ovirtsdk4 as sdk ++import ovirtsdk4.types as types ++ ++# Timeout to wait for oVirt disks to change status, or the transfer ++# object to finish initializing [seconds]. ++timeout = 5*60 ++ ++# Parameters are passed in via a JSON doc from the OCaml code. ++# Because this Python code ships embedded inside virt-v2v there ++# is no formal API here. ++params = None ++ ++def config(key, value): ++ global params ++ ++ if key == "params": ++ with builtins.open(value, 'r') as fp: ++ params = json.load(fp) ++ else: ++ raise RuntimeError("unknown configuration key '%s'" % key) ++ ++def config_complete(): ++ if params is None: ++ raise RuntimeError("missing configuration parameters") ++ ++def debug(s): ++ if params['verbose']: ++ print(s, file=sys.stderr) ++ sys.stderr.flush() ++ ++def open(readonly): ++ # Parse out the username from the output_conn URL. ++ parsed = urlparse(params['output_conn']) ++ username = parsed.username or "admin@internal" ++ ++ # Read the password from file. ++ with builtins.open(params['output_password'], 'r') as fp: ++ password = fp.read() ++ password = password.rstrip() ++ ++ # Connect to the server. ++ connection = sdk.Connection( ++ url = params['output_conn'], ++ username = username, ++ password = password, ++ ca_file = params['rhv_cafile'], ++ log = logging.getLogger(), ++ insecure = params['insecure'], ++ ) ++ ++ system_service = connection.system_service() ++ ++ # Create the disk. ++ disks_service = system_service.disks_service() ++ if params['disk_format'] == "raw": ++ disk_format = types.DiskFormat.RAW ++ else: ++ disk_format = types.DiskFormat.COW ++ disk = disks_service.add( ++ disk = types.Disk( ++ name = params['disk_name'], ++ description = "Uploaded by virt-v2v", ++ format = disk_format, ++ 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, ++ storage_domains = [ ++ types.StorageDomain( ++ name = params['output_storage'], ++ ) ++ ], ++ ) ++ ) ++ ++ # Wait till the disk is up, as the transfer can't start if the ++ # disk is locked: ++ disk_service = disks_service.disk_service(disk.id) ++ debug("disk.id = %r" % disk.id) ++ ++ endt = time.time() + timeout ++ while True: ++ time.sleep(5) ++ disk = disk_service.get() ++ if disk.status == types.DiskStatus.OK: ++ break ++ if time.time() > endt: ++ raise RuntimeError("timed out waiting for disk to become unlocked") ++ ++ # Get a reference to the transfer service. ++ transfers_service = system_service.image_transfers_service() ++ ++ # Create a new image transfer. ++ transfer = transfers_service.add( ++ types.ImageTransfer( ++ image = types.Image( ++ id = disk.id ++ ) ++ ) ++ ) ++ debug("transfer.id = %r" % transfer.id) ++ ++ # Get a reference to the created transfer service. ++ transfer_service = transfers_service.image_transfer_service(transfer.id) ++ ++ # After adding a new transfer for the disk, the transfer's status ++ # will be INITIALIZING. Wait until the init phase is over. The ++ # actual transfer can start when its status is "Transferring". ++ endt = time.time() + timeout ++ while True: ++ time.sleep(5) ++ transfer = transfer_service.get() ++ if transfer.phase != types.ImageTransferPhase.INITIALIZING: ++ break ++ if time.time() > endt: ++ raise RuntimeError("timed out waiting for transfer status " + ++ "!= INITIALIZING") ++ ++ # Now we have permission to start the transfer. ++ if params['rhv_direct']: ++ if transfer.transfer_url is None: ++ raise RuntimeError("direct upload to host not supported, " + ++ "requires ovirt-engine >= 4.2 and only works " + ++ "when virt-v2v is run within the oVirt/RHV " + ++ "environment, eg. on an oVirt node.") ++ destination_url = urlparse(transfer.transfer_url) ++ else: ++ destination_url = urlparse(transfer.proxy_url) ++ ++ context = ssl.create_default_context() ++ context.load_verify_locations(cafile = params['rhv_cafile']) ++ ++ http = HTTPSConnection( ++ destination_url.hostname, ++ destination_url.port, ++ context = context ++ ) ++ ++ # Save everything we need to make requests in the handle. ++ return { ++ 'can_flush': False, ++ 'can_trim': False, ++ 'can_zero': False, ++ 'connection': connection, ++ 'disk': disk, ++ 'disk_service': disk_service, ++ 'failed': False, ++ 'got_options': False, ++ 'highestwrite': 0, ++ 'http': http, ++ 'needs_auth': not params['rhv_direct'], ++ 'path': destination_url.path, ++ 'transfer': transfer, ++ 'transfer_service': transfer_service, ++ } ++ ++# Can we issue zero, trim or flush requests? ++def get_options(h): ++ if h['got_options']: ++ return ++ h['got_options'] = True ++ ++ http = h['http'] ++ transfer = h['transfer'] ++ ++ http.putrequest("OPTIONS", h['path']) ++ http.putheader("Authorization", transfer.signed_ticket) ++ http.endheaders() ++ ++ r = http.getresponse() ++ if r.status == 200: ++ # New imageio never needs authentication. ++ h['needs_auth'] = False ++ ++ j = json.loads(r.read()) ++ h['can_zero'] = "zero" in j['features'] ++ h['can_trim'] = "trim" in j['features'] ++ h['can_flush'] = "flush" in j['features'] ++ ++ # Old imageio servers returned either 405 Method Not Allowed or ++ # 204 No Content (with an empty body). If we see that we leave ++ # all the features as False and they will be emulated. ++ elif r.status == 405 or r.status == 204: ++ pass ++ ++ else: ++ raise RuntimeError("could not use OPTIONS request: %d: %s" % ++ (r.status, r.reason)) ++ ++def can_trim(h): ++ get_options(h) ++ return h['can_trim'] ++ ++def can_flush(h): ++ get_options(h) ++ return h['can_flush'] ++ ++def get_size(h): ++ return params['disk_size'] ++ ++# For documentation see: ++# https://github.com/oVirt/ovirt-imageio/blob/master/docs/random-io.md ++# For examples of working code to read/write from the server, see: ++# https://github.com/oVirt/ovirt-imageio/blob/master/daemon/test/server_test.py ++ ++def pread(h, count, offset): ++ http = h['http'] ++ transfer = h['transfer'] ++ transfer_service = h['transfer_service'] ++ ++ http.putrequest("GET", h['path']) ++ # Authorization is only needed for old imageio. ++ if h['needs_auth']: ++ http.putheader("Authorization", transfer.signed_ticket) ++ http.putheader("Range", "bytes=%d-%d" % (offset, offset+count-1)) ++ http.endheaders() ++ ++ r = http.getresponse() ++ # 206 = HTTP Partial Content. ++ if r.status != 206: ++ h['transfer_service'].pause() ++ h['failed'] = True ++ raise RuntimeError("could not read sector (%d, %d): %d: %s" % ++ (offset, count, r.status, r.reason)) ++ return r.read() ++ ++def pwrite(h, buf, offset): ++ http = h['http'] ++ transfer = h['transfer'] ++ transfer_service = h['transfer_service'] ++ ++ count = len(buf) ++ h['highestwrite'] = max(h['highestwrite'], offset+count) ++ ++ http.putrequest("PUT", h['path'] + "?flush=n") ++ # Authorization is only needed for old imageio. ++ if h['needs_auth']: ++ http.putheader("Authorization", transfer.signed_ticket) ++ # The oVirt server only uses the first part of the range, and the ++ # content-length. ++ http.putheader("Content-Range", "bytes %d-%d/*" % (offset, offset+count-1)) ++ http.putheader("Content-Length", str(count)) ++ http.endheaders() ++ http.send(buf) ++ ++ r = http.getresponse() ++ if r.status != 200: ++ transfer_service.pause() ++ h['failed'] = True ++ raise RuntimeError("could not write sector (%d, %d): %d: %s" % ++ (offset, count, r.status, r.reason)) ++ ++def zero(h, count, offset, may_trim): ++ http = h['http'] ++ transfer = h['transfer'] ++ transfer_service = h['transfer_service'] ++ ++ # Unlike the trim and flush calls, there is no 'can_zero' method ++ # so nbdkit could call this even if the server doesn't support ++ # zeroing. If this is the case we must emulate. ++ if not h['can_zero']: ++ emulate_zero(h, count, offset) ++ return ++ ++ # Construct the JSON request for zeroing. ++ buf = json.dumps({'op': "zero", ++ 'offset': offset, ++ 'size': count, ++ 'flush': False}).encode() ++ ++ http.putrequest("PATCH", h['path']) ++ http.putheader("Content-Type", "application/json") ++ http.putheader("Content-Length", len(buf)) ++ http.endheaders() ++ http.send(buf) ++ ++ r = http.getresponse() ++ if r.status != 200: ++ transfer_service.pause() ++ h['failed'] = True ++ raise RuntimeError("could not zero sector (%d, %d): %d: %s" % ++ (offset, count, r.status, r.reason)) ++ ++def emulate_zero(h, count, offset): ++ # qemu-img convert starts by trying to zero/trim the whole device. ++ # Since we've just created a new disk it's safe to ignore these ++ # requests as long as they are smaller than the highest write seen. ++ # After that we must emulate them with writes. ++ if offset+count < h['highestwrite']: ++ http.putrequest("PUT", h['path']) ++ # Authorization is only needed for old imageio. ++ if h['needs_auth']: ++ http.putheader("Authorization", transfer.signed_ticket) ++ http.putheader("Content-Range", ++ "bytes %d-%d/*" % (offset, offset+count-1)) ++ http.putheader("Content-Length", str(count)) ++ http.endheaders() ++ ++ buf = bytearray(128*1024) ++ while count > len(buf): ++ http.send(buf) ++ count -= len(buf) ++ http.send(buffer(buf, 0, count)) ++ ++ r = http.getresponse() ++ if r.status != 200: ++ transfer_service.pause() ++ h['failed'] = True ++ raise RuntimeError("could not write zeroes (%d, %d): %d: %s" % ++ (offset, count, r.status, r.reason)) ++ ++def trim(h, count, offset): ++ http = h['http'] ++ transfer = h['transfer'] ++ transfer_service = h['transfer_service'] ++ ++ # Construct the JSON request for trimming. ++ buf = json.dumps({'op': "trim", ++ 'offset': offset, ++ 'size': count, ++ 'flush': False}).encode() ++ ++ http.putrequest("PATCH", h['path']) ++ http.putheader("Content-Type", "application/json") ++ http.putheader("Content-Length", len(buf)) ++ http.endheaders() ++ http.send(buf) ++ ++ r = http.getresponse() ++ if r.status != 200: ++ transfer_service.pause() ++ h['failed'] = True ++ raise RuntimeError("could not trim sector (%d, %d): %d: %s" % ++ (offset, count, r.status, r.reason)) ++ ++def flush(h): ++ http = h['http'] ++ transfer = h['transfer'] ++ transfer_service = h['transfer_service'] ++ ++ # Construct the JSON request for flushing. ++ buf = json.dumps({'op': "flush"}).encode() ++ ++ http.putrequest("PATCH", h['path']) ++ http.putheader("Content-Type", "application/json") ++ http.putheader("Content-Length", len(buf)) ++ http.endheaders() ++ http.send(buf) ++ ++ r = http.getresponse() ++ if r.status != 200: ++ transfer_service.pause() ++ h['failed'] = True ++ raise RuntimeError("could not flush: %d: %s" % (r.status, r.reason)) ++ ++def delete_disk_on_failure(h): ++ disk_service = h['disk_service'] ++ disk_service.remove() ++ ++def close(h): ++ http = h['http'] ++ connection = h['connection'] ++ ++ # This is sometimes necessary because python doesn't set up ++ # sys.stderr to be line buffered and so debug, errors or ++ # exceptions printed previously might not be emitted before the ++ # plugin exits. ++ sys.stderr.flush() ++ ++ # If the connection failed earlier ensure we clean up the disk. ++ if h['failed']: ++ delete_disk_on_failure(h) ++ connection.close() ++ return ++ ++ try: ++ # Issue a flush request on close so that the data is written to ++ # persistent store before we create the VM. ++ if h['can_flush']: ++ flush(h) ++ ++ http.close() ++ ++ disk = h['disk'] ++ transfer_service = h['transfer_service'] ++ ++ transfer_service.finalize() ++ ++ # Wait until the transfer disk job is completed since ++ # only then we can be sure the disk is unlocked. As this ++ # code is not very clear, what's happening is that we are ++ # waiting for the transfer object to cease to exist, which ++ # falls through to the exception case and then we can ++ # continue. ++ endt = time.time() + timeout ++ try: ++ while True: ++ time.sleep(1) ++ tmp = transfer_service.get() ++ if time.time() > endt: ++ raise RuntimeError("timed out waiting for transfer " + ++ "to finalize") ++ except sdk.NotFoundError: ++ pass ++ ++ # Write the disk ID file. Only do this on successful completion. ++ with builtins.open(params['diskid_file'], 'w') as fp: ++ fp.write(disk.id) ++ ++ except: ++ # Otherwise on any failure we must clean up the disk. ++ delete_disk_on_failure(h) ++ raise ++ ++ connection.close() +diff --git a/v2v/rhv-upload-precheck.py b/v2v/rhv-upload-precheck.py +new file mode 100644 +index 000000000..2798a29dd +--- /dev/null ++++ b/v2v/rhv-upload-precheck.py +@@ -0,0 +1,73 @@ ++# -*- python -*- ++# oVirt or RHV pre-upload checks used by ‘virt-v2v -o rhv-upload’ ++# Copyright (C) 2018 Red Hat Inc. ++# ++# 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. ++ ++import json ++import logging ++import sys ++import time ++ ++from http.client import HTTPSConnection ++from urllib.parse import urlparse ++ ++import ovirtsdk4 as sdk ++import ovirtsdk4.types as types ++ ++# Parameters are passed in via a JSON doc from the OCaml code. ++# Because this Python code ships embedded inside virt-v2v there ++# is no formal API here. ++params = None ++ ++if len(sys.argv) != 2: ++ raise RuntimeError("incorrect number of parameters") ++ ++# Parameters are passed in via a JSON document. ++with open(sys.argv[1], 'r') as fp: ++ params = json.load(fp) ++ ++# What is passed in is a password file, read the actual password. ++with open(params['output_password'], 'r') as fp: ++ output_password = fp.read() ++output_password = output_password.rstrip() ++ ++# Parse out the username from the output_conn URL. ++parsed = urlparse(params['output_conn']) ++username = parsed.username or "admin@internal" ++ ++# Connect to the server. ++connection = sdk.Connection( ++ url = params['output_conn'], ++ username = username, ++ password = output_password, ++ ca_file = params['rhv_cafile'], ++ log = logging.getLogger(), ++ insecure = params['insecure'], ++) ++ ++system_service = connection.system_service() ++ ++# Find if a virtual machine already exists with that name. ++vms_service = system_service.vms_service() ++vms = vms_service.list( ++ search = ("name=%s" % params['output_name']), ++) ++if len(vms) > 0: ++ vm = vms[0] ++ raise RuntimeError("VM already exists with name ‘%s’, id ‘%s’" % ++ (params['output_name'], vm.id)) ++ ++# Otherwise everything is OK, exit with no error. +diff --git a/v2v/test-v2v-o-rhv-upload-oo-query.sh b/v2v/test-v2v-o-rhv-upload-oo-query.sh +new file mode 100755 +index 000000000..29d69e1c1 +--- /dev/null ++++ b/v2v/test-v2v-o-rhv-upload-oo-query.sh +@@ -0,0 +1,38 @@ ++#!/bin/bash - ++# libguestfs virt-v2v test script ++# Copyright (C) 2018 Red Hat Inc. ++# ++# 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 -oo "?" option. ++ ++set -e ++ ++$TEST_FUNCTIONS ++skip_if_skipped ++ ++export VIRT_TOOLS_DATA_DIR="$top_srcdir/test-data/fake-virt-tools" ++export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win" ++ ++f=test-v2v-o-rhv-upload-oo-query.actual ++rm -f $f ++ ++$VG virt-v2v --debug-gc \ ++ -o rhv-upload -oo "?" > $f ++ ++grep -- "-oo rhv-cafile" $f ++grep -- "-oo rhv-verifypeer" $f ++ ++rm $f +diff --git a/v2v/test-v2v-python-syntax.sh b/v2v/test-v2v-python-syntax.sh +new file mode 100755 +index 000000000..b167f4610 +--- /dev/null ++++ b/v2v/test-v2v-python-syntax.sh +@@ -0,0 +1,45 @@ ++#!/bin/bash - ++# libguestfs ++# Copyright (C) 2018 Red Hat Inc. ++# ++# 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. ++ ++set -e ++ ++$TEST_FUNCTIONS ++skip_if_skipped ++ ++# Files to check. ++files="rhv-upload-createvm.py rhv-upload-plugin.py rhv-upload-precheck.py" ++ ++# Base version of Python. ++python=python3 ++ ++# Checks the files are syntactically correct, but not very much else. ++for f in $files; do ++ $python -m py_compile $f ++done ++ ++# Checks the files correspond to PEP8 coding style. ++# https://www.python.org/dev/peps/pep-0008/ ++if $python-pep8 --version >/dev/null 2>&1; then ++ for f in $files; do ++ # Ignore: ++ # E226 missing whitespace around arithmetic operator ++ # E251 unexpected spaces around keyword / parameter equals ++ # E302 expected 2 blank lines, found 1 ++ $python-pep8 --ignore=E226,E251,E302 $f ++ done ++fi +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 5dd888e77..62b726b8f 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -6,15 +6,18 @@ virt-v2v - Convert a guest to use KVM + + virt-v2v -ic vpx://vcenter.example.com/Datacenter/esxi vmware_guest + +- virt-v2v -ic vpx://vcenter.example.com/Datacenter/esxi vmware_guest \ +- -o rhv -os rhv.nfs:/export_domain --bridge ovirtmgmt +- + virt-v2v -i libvirtxml guest-domain.xml -o local -os /var/tmp + + virt-v2v -i disk disk.img -o local -os /var/tmp + + virt-v2v -i disk disk.img -o glance + ++ virt-v2v -ic vpx://vcenter.example.com/Datacenter/esxi vmware_guest \ ++ -o rhv-upload -oc https://ovirt-engine.example.com/ovirt-engine/api \ ++ -os ovirt-data -op /tmp/ovirt-admin-password -of raw \ ++ -oo rhv-cafile=/tmp/ca.pem -oo rhv-direct \ ++ --bridge ovirtmgmt ++ + =head1 DESCRIPTION + + Virt-v2v converts guests from a foreign hypervisor to run on KVM. It +@@ -50,20 +53,18 @@ For more information see L below. + =head2 Convert from VMware to RHV/oVirt + + This is the same as the previous example, except you want to send the +-guest to a RHV-M Export Storage Domain which is located remotely +-(over NFS) at C. If you are unclear about +-the location of the Export Storage Domain you should check the +-settings on your RHV-M management console. Guest network ++guest to a RHV Data Domain using the RHV REST API. Guest network + interface(s) are connected to the target network called C. + + virt-v2v -ic vpx://vcenter.example.com/Datacenter/esxi vmware_guest \ +- -o rhv -os rhv.nfs:/export_domain --bridge ovirtmgmt ++ -o rhv-upload -oc https://ovirt-engine.example.com/ovirt-engine/api \ ++ -os ovirt-data -op /tmp/ovirt-admin-password -of raw \ ++ -oo rhv-cafile=/tmp/ca.pem -oo rhv-direct \ ++ --bridge ovirtmgmt + + In this case the host running virt-v2v acts as a B. + +-Note that after conversion, the guest will appear in the RHV-M Export +-Storage Domain, from where you will need to import it using the RHV-M +-user interface. (See L). ++For more information see L below. + + =head2 Convert from ESXi hypervisor over SSH to local libvirt + +@@ -122,9 +123,9 @@ command line. + Xen ───▶│ -i libvirt ──▶ │ │ │ (default) │ + ... ───▶│ (default) │ │ │ ──┐ └────────────┘ + └────────────┘ │ │ ─┐└──────▶ -o glance +- -i libvirtxml ─────────▶ │ │ ┐└─────────▶ -o rhv +- -i vmx ────────────────▶ │ │ └──────────▶ -o vdsm +- └────────────┘ ++ -i libvirtxml ─────────▶ │ │ ┐├─────────▶ -o rhv ++ -i vmx ────────────────▶ │ │ │└─────────▶ -o vdsm ++ └────────────┘ └──────────▶ -o rhv-upload + + Virt-v2v has a number of possible input and output modes, selected + using the I<-i> and I<-o> options. Only one input and output mode can +@@ -157,8 +158,9 @@ libvirt configuration file (mainly for testing). + I<-o qemu> writes to a local disk image with a shell script for + booting the guest directly in qemu (mainly for testing). + +-I<-o rhv> is used to write to a RHV / oVirt target. I<-o vdsm> +-is only used when virt-v2v runs under VDSM control. ++I<-o rhv-upload> is used to write to a RHV / oVirt target. I<-o rhv> ++is a legacy method to write to RHV / oVirt E 4.2. I<-o vdsm> is ++only used when virt-v2v runs under VDSM control. + + =head1 OPTIONS + +@@ -426,6 +428,10 @@ written. + + This is the same as I<-o rhv>. + ++=item B<-o> B ++ ++This is the same as I<-o rhv-upload>. ++ + =item B<-o> B + + Set the output method to I. +@@ -447,6 +453,16 @@ I<-os> parameter must also be used to specify the location of the + Export Storage Domain. Note this does not actually import the guest + into RHV. You have to do that manually later using the UI. + ++See L below. ++ ++=item B<-o> B ++ ++Set the output method to I. ++ ++The converted guest is written directly to a RHV Data Domain. ++This is a faster method than I<-o rhv>, but requires oVirt ++or RHV E 4.2. ++ + See L below. + + =item B<-o> B +@@ -488,7 +504,33 @@ the output name is the same as the input name. + Set output option(s) related to the current output mode. + To display short help on what options are available you can use: + +- virt-v2v -o vdsm -oo "?" ++ virt-v2v -o rhv-upload -oo "?" ++ ++=item B<-oo rhv-cafile=>F ++ ++For I<-o rhv-upload> (L) only, the F file ++(Certificate Authority), copied from F ++on the oVirt engine. ++ ++=item B<-oo rhv-cluster=>C ++ ++For I<-o rhv-upload> (L) only, set the RHV Cluster ++Name. If not given it uses C. ++ ++=item B<-oo rhv-direct> ++ ++For I<-o rhv-upload> (L) only, if this option is given ++then virt-v2v will attempt to directly upload the disk to the oVirt ++node, otherwise it will proxy the upload through the oVirt engine. ++Direct upload requires that you have network access to the oVirt ++nodes. Non-direct upload is slightly slower but should work in all ++situations. ++ ++=item B<-oo rhv-verifypeer> ++ ++For I<-o rhv-upload> (L) only, verify the oVirt/RHV ++server’s identity by checking the server‘s certificate against the ++Certificate Authority. + + =item B<-oo vdsm-compat=0.10> + +@@ -1749,6 +1791,68 @@ Define the final guest in libvirt: + + =head1 OUTPUT TO RHV + ++This new method to upload guests to oVirt or RHV directly via the REST ++API requires oVirt/RHV E 4.2. ++ ++You need to specify I<-o rhv-upload> as well as the following extra ++parameters: ++ ++=over 4 ++ ++=item I<-oc> C ++ ++The URL of the REST API which is usually the server name with ++C appended, but might be different if you installed ++oVirt Engine on a different path. ++ ++You can optionally add a username and port number to the URL. If the ++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 ++engine. Note the file should contain the whole password, B, and for security the file should have mode ++C<0600> so that others cannot read it. ++ ++=item I<-os> C ++ ++The storage domain. ++ ++=item I<-oo rhv-cafile=>F ++ ++The F file (Certificate Authority), copied from ++F on the oVirt engine. ++ ++=item I<-oo rhv-cluster=>C ++ ++Set the RHV Cluster Name. If not given it uses C. ++ ++=item I<-oo rhv-direct> ++ ++If this option is given then virt-v2v will attempt to directly upload ++the disk to the oVirt node, otherwise it will proxy the upload through ++the oVirt engine. Direct upload requires that you have network access ++to the oVirt nodes. Non-direct upload is slightly slower but should ++work in all situations. ++ ++=item I<-oo rhv-verifypeer> ++ ++Verify the oVirt/RHV server’s identity by checking the server‘s ++certificate against the Certificate Authority. ++ ++=back ++ ++=head1 OUTPUT TO RHV (OLD METHOD) ++ + This section only applies to the I<-o rhv> output mode. If you use + virt-v2v from the RHV-M user interface, then behind the scenes the + import is managed by VDSM using the I<-o vdsm> output mode (which end +-- +2.17.1 + diff --git a/SOURCES/0040-s390x-launch-direct-Use-virtio-ccw-on-this-architect.patch b/SOURCES/0040-s390x-launch-direct-Use-virtio-ccw-on-this-architect.patch deleted file mode 100644 index 478530a..0000000 --- a/SOURCES/0040-s390x-launch-direct-Use-virtio-ccw-on-this-architect.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 516f008f29e77d676907208e51e2f57bb73888aa Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 16 May 2017 19:58:59 +0200 -Subject: [PATCH] s390x: launch: direct: Use virtio-*-ccw on this architecture. - -PCI devices don't exist/work. You would see errors such as: - -qemu-system-s390x: -device virtio-rng-pci,rng=rng0: MSI-X support is mandatory in the S390 architecture -(cherry picked from commit ddde6f9e2f14ccf8d91a8587052d0abcfb6496f1) ---- - lib/guestfs-internal.h | 26 +++++++++++++++++--------- - lib/launch-direct.c | 4 ++-- - 2 files changed, 19 insertions(+), 11 deletions(-) - -diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h -index 949cacfef..f035e0931 100644 ---- a/lib/guestfs-internal.h -+++ b/lib/guestfs-internal.h -@@ -142,20 +142,28 @@ - /* Maximum size of Windows explorer.exe. 2.6MB on Windows 7. */ - #define MAX_WINDOWS_EXPLORER_SIZE (4 * 1000 * 1000) - --/* Differences in device names on ARM (virtio-mmio) vs normal -- * hardware with PCI. -+/* Differences in device names on ARMv7 (virtio-mmio), s/390x (CCW) vs -+ * normal hardware with PCI. - */ --#if !defined(__arm__) --#define VIRTIO_BLK "virtio-blk-pci" --#define VIRTIO_SCSI "virtio-scsi-pci" --#define VIRTIO_SERIAL "virtio-serial-pci" --#define VIRTIO_NET "virtio-net-pci" --#else /* ARMv7 */ -+#if defined(__arm__) - #define VIRTIO_BLK "virtio-blk-device" - #define VIRTIO_SCSI "virtio-scsi-device" - #define VIRTIO_SERIAL "virtio-serial-device" - #define VIRTIO_NET "virtio-net-device" --#endif /* ARMv7 */ -+#define VIRTIO_RNG "virtio-rng-device" -+#elif defined(__s390x__) -+#define VIRTIO_BLK "virtio-blk-ccw" -+#define VIRTIO_SCSI "virtio-scsi-ccw" -+#define VIRTIO_SERIAL "virtio-serial-ccw" -+#define VIRTIO_NET "virtio-net-ccw" -+#define VIRTIO_RNG "virtio-rng-ccw" -+#else -+#define VIRTIO_BLK "virtio-blk-pci" -+#define VIRTIO_SCSI "virtio-scsi-pci" -+#define VIRTIO_SERIAL "virtio-serial-pci" -+#define VIRTIO_NET "virtio-net-pci" -+#define VIRTIO_RNG "virtio-rng-pci" -+#endif - - /* Machine types. */ - #ifdef __arm__ -diff --git a/lib/launch-direct.c b/lib/launch-direct.c -index 147e158de..c8841bfe4 100644 ---- a/lib/launch-direct.c -+++ b/lib/launch-direct.c -@@ -463,11 +463,11 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - * when needing entropy. - */ - if (guestfs_int_qemu_supports_device (g, data->qemu_data, -- "virtio-rng-pci")) { -+ VIRTIO_RNG)) { - ADD_CMDLINE ("-object"); - ADD_CMDLINE ("rng-random,filename=/dev/urandom,id=rng0"); - ADD_CMDLINE ("-device"); -- ADD_CMDLINE ("virtio-rng-pci,rng=rng0"); -+ ADD_CMDLINE (VIRTIO_RNG ",rng=rng0"); - } - - /* Add drives */ --- -2.14.3 - diff --git a/SOURCES/0040-v2v-refer-to-the-right-embed-script-in-EXTRA_DIST.patch b/SOURCES/0040-v2v-refer-to-the-right-embed-script-in-EXTRA_DIST.patch new file mode 100644 index 0000000..2752c3b --- /dev/null +++ b/SOURCES/0040-v2v-refer-to-the-right-embed-script-in-EXTRA_DIST.patch @@ -0,0 +1,28 @@ +From 2b18ec6b5680bd557a78f958c8eb75698d0737cc Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 20 Apr 2018 13:00:56 +0200 +Subject: [PATCH] v2v: refer to the right embed script in EXTRA_DIST + +Fixes commit cc04573927cca97de60d544d37467e67c25867a7. + +(cherry picked from commit cf49fe100338aeac281c7cbcdfe743177ceb0606) +--- + v2v/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/Makefile.am b/v2v/Makefile.am +index affc00a8b..0f8c5120b 100644 +--- a/v2v/Makefile.am ++++ b/v2v/Makefile.am +@@ -31,7 +31,7 @@ EXTRA_DIST = \ + $(SOURCES_MLI) $(SOURCES_ML) $(SOURCES_C) \ + copy_to_local.ml \ + copy_to_local.mli \ +- embed-code.sh \ ++ embed.sh \ + rhv-upload-createvm.py \ + rhv-upload-plugin.py \ + rhv-upload-precheck.py \ +-- +2.17.1 + diff --git a/SOURCES/0041-s390x-tests-regressions-Skip-IDE-tests-on-S-390.patch b/SOURCES/0041-s390x-tests-regressions-Skip-IDE-tests-on-S-390.patch deleted file mode 100644 index a9ecc13..0000000 --- a/SOURCES/0041-s390x-tests-regressions-Skip-IDE-tests-on-S-390.patch +++ /dev/null @@ -1,40 +0,0 @@ -From a5a3600b8341278ee8c18dca89b9a9ba75ec2eca Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 17 May 2017 13:38:43 +0200 -Subject: [PATCH] s390x: tests: regressions: Skip IDE tests on S/390. - -IDE interface is not supported. - -(cherry picked from commit 93af83de853b87c555624227741bdf8af1918703) ---- - tests/regressions/rhbz690819.sh | 1 + - tests/regressions/rhbz975797.sh | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/tests/regressions/rhbz690819.sh b/tests/regressions/rhbz690819.sh -index d18b4d81a..0b790862d 100755 ---- a/tests/regressions/rhbz690819.sh -+++ b/tests/regressions/rhbz690819.sh -@@ -29,6 +29,7 @@ skip_if_arch arm - skip_if_arch aarch64 - skip_if_arch ppc64 - skip_if_arch ppc64le -+skip_if_arch s390x - skip_if_backend libvirt - # UML doesn't support the 'iface' parameter. - skip_if_backend uml -diff --git a/tests/regressions/rhbz975797.sh b/tests/regressions/rhbz975797.sh -index bc6a1c63f..04e8d23de 100755 ---- a/tests/regressions/rhbz975797.sh -+++ b/tests/regressions/rhbz975797.sh -@@ -29,6 +29,7 @@ skip_if_arch arm - skip_if_arch aarch64 - skip_if_arch ppc64 - skip_if_arch ppc64le -+skip_if_arch s390x - skip_if_backend libvirt - # UML doesn't support the 'iface' parameter. - skip_if_backend uml --- -2.14.3 - diff --git a/SOURCES/0041-v2v-o-rhv-upload-Don-t-require-of-raw-parameter.patch b/SOURCES/0041-v2v-o-rhv-upload-Don-t-require-of-raw-parameter.patch new file mode 100644 index 0000000..96e30f2 --- /dev/null +++ b/SOURCES/0041-v2v-o-rhv-upload-Don-t-require-of-raw-parameter.patch @@ -0,0 +1,84 @@ +From 1b7f750e9244c6d0cd184ffa8a64461db70be263 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 20 Apr 2018 11:48:47 +0100 +Subject: [PATCH] =?UTF-8?q?v2v:=20-o=20rhv-upload:=20Don't=20require=20?= + =?UTF-8?q?=E2=80=98-of=20raw=E2=80=99=20parameter.?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Because we checked the limitation of raw+sparse during command line +processing, it had the effect of forcing you to use ‘-of raw’ even if +the input was already in raw format. Move the checking to the output +mode to avoid this. + +Fixes commit cc04573927cca97de60d544d37467e67c25867a7. + +(cherry picked from commit b3769afaece360b8a2095e3d8a7a934d351c3ade) +--- + v2v/cmdline.ml | 5 ----- + v2v/output_rhv_upload.ml | 18 +++++++++++++++++- + 2 files changed, 17 insertions(+), 6 deletions(-) + +diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml +index 6321eb656..d0be1deb6 100644 +--- a/v2v/cmdline.ml ++++ b/v2v/cmdline.ml +@@ -589,11 +589,6 @@ read the man page virt-v2v(1). + | None -> + error (f_"-o rhv-upload: use ‘-oc’ to point to the oVirt or RHV server REST API URL, which is usually https://servername/ovirt-engine/api") + | Some oc -> oc in +- (* Output format / sparse must currently be raw+sparse. We can +- * change this in future. See TODO file for details. XXX +- *) +- if output_alloc <> Sparse || output_format <> Some "raw" then +- error (f_"-o rhv-upload: currently you must use ‘-of raw’ and you cannot use ‘-oa preallocated’ with this output mode. These restrictions will be loosened in a future version."); + (* In theory we could make the password optional in future. *) + let output_password = + match output_password with +diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml +index 129461242..dc0d96d53 100644 +--- a/v2v/output_rhv_upload.ml ++++ b/v2v/output_rhv_upload.ml +@@ -169,6 +169,19 @@ See also \"OUTPUT TO RHV\" in the virt-v2v(1) manual.") + 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.") + in + ++ (* Output format/sparse must be raw/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 ++ *) ++ 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 ++ in ++ ++ let error_unless_output_alloc_sparse () = ++ if output_alloc <> Sparse then ++ error_current_limitation "-oa sparse" ++ in ++ + (* JSON parameters which are invariant between disks. *) + let json_params = [ + "verbose", JSON.Bool (verbose ()); +@@ -220,6 +233,7 @@ object + error_unless_python_binary_on_path (); + error_unless_nbdkit_working (); + error_unless_nbdkit_python3_working (); ++ error_unless_output_alloc_sparse (); + if have_selinux then + error_unless_nbdkit_compiled_with_selinux () + +@@ -260,7 +274,9 @@ object + + let disk_format = + match t.target_format with +- | ("raw" | "qcow2") as fmt -> fmt ++ | "raw" as fmt -> fmt ++ | "qcow2" -> ++ error_current_limitation "-of raw" + | _ -> + error (f_"rhv-upload: -of %s: Only output format ‘raw’ or ‘qcow2’ is supported. If the input is in a different format then force one of these output formats by adding either ‘-of raw’ or ‘-of qcow2’ on the command line.") + t.target_format in +-- +2.17.1 + diff --git a/SOURCES/0042-lib-Add-VIRTIO_DEVICE_NAME-macro-to-handle-virtio-mm.patch b/SOURCES/0042-lib-Add-VIRTIO_DEVICE_NAME-macro-to-handle-virtio-mm.patch deleted file mode 100644 index bf204d6..0000000 --- a/SOURCES/0042-lib-Add-VIRTIO_DEVICE_NAME-macro-to-handle-virtio-mm.patch +++ /dev/null @@ -1,155 +0,0 @@ -From eddfb0a765e0246d0fb397414f32403f055488a3 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 18 May 2017 15:59:38 +0100 -Subject: [PATCH] lib: Add VIRTIO_DEVICE_NAME macro to handle virtio-mmio vs - CCW vs virtio-PCI. - -(cherry picked from commit a5bd493e3f90945cb8e913f9c680bedbdf26aaaa) - -PT: the VIRTIO_DEVICE_NAME macros are left in guestfs-internal.h, since -the VIRTIO_* macros were used in other places than launch-direct.c. ---- - lib/guestfs-internal.h | 22 +++++----------------- - lib/launch-direct.c | 16 ++++++++-------- - lib/launch-libvirt.c | 2 +- - lib/qemu.c | 2 +- - 4 files changed, 15 insertions(+), 27 deletions(-) - -diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h -index f035e0931..d962aacd4 100644 ---- a/lib/guestfs-internal.h -+++ b/lib/guestfs-internal.h -@@ -142,27 +142,15 @@ - /* Maximum size of Windows explorer.exe. 2.6MB on Windows 7. */ - #define MAX_WINDOWS_EXPLORER_SIZE (4 * 1000 * 1000) - --/* Differences in device names on ARMv7 (virtio-mmio), s/390x (CCW) vs -- * normal hardware with PCI. -+/* Differences in qemu device names on ARMv7 (virtio-mmio), s/390x -+ * (CCW) vs normal hardware with PCI. - */ - #if defined(__arm__) --#define VIRTIO_BLK "virtio-blk-device" --#define VIRTIO_SCSI "virtio-scsi-device" --#define VIRTIO_SERIAL "virtio-serial-device" --#define VIRTIO_NET "virtio-net-device" --#define VIRTIO_RNG "virtio-rng-device" -+#define VIRTIO_DEVICE_NAME(type) type "-device" - #elif defined(__s390x__) --#define VIRTIO_BLK "virtio-blk-ccw" --#define VIRTIO_SCSI "virtio-scsi-ccw" --#define VIRTIO_SERIAL "virtio-serial-ccw" --#define VIRTIO_NET "virtio-net-ccw" --#define VIRTIO_RNG "virtio-rng-ccw" -+#define VIRTIO_DEVICE_NAME(type) type "-ccw" - #else --#define VIRTIO_BLK "virtio-blk-pci" --#define VIRTIO_SCSI "virtio-scsi-pci" --#define VIRTIO_SERIAL "virtio-serial-pci" --#define VIRTIO_NET "virtio-net-pci" --#define VIRTIO_RNG "virtio-rng-pci" -+#define VIRTIO_DEVICE_NAME(type) type "-pci" - #endif - - /* Machine types. */ -diff --git a/lib/launch-direct.c b/lib/launch-direct.c -index c8841bfe4..0fef05927 100644 ---- a/lib/launch-direct.c -+++ b/lib/launch-direct.c -@@ -349,7 +349,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - */ - if (guestfs_int_qemu_supports (g, data->qemu_data, "-global")) { - ADD_CMDLINE ("-global"); -- ADD_CMDLINE (VIRTIO_BLK ".scsi=off"); -+ ADD_CMDLINE (VIRTIO_DEVICE_NAME ("virtio-blk") ".scsi=off"); - } - - if (guestfs_int_qemu_supports (g, data->qemu_data, "-nodefconfig")) -@@ -463,11 +463,11 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - * when needing entropy. - */ - if (guestfs_int_qemu_supports_device (g, data->qemu_data, -- VIRTIO_RNG)) { -+ VIRTIO_DEVICE_NAME ("virtio-rng"))) { - ADD_CMDLINE ("-object"); - ADD_CMDLINE ("rng-random,filename=/dev/urandom,id=rng0"); - ADD_CMDLINE ("-device"); -- ADD_CMDLINE (VIRTIO_RNG ",rng=rng0"); -+ ADD_CMDLINE (VIRTIO_DEVICE_NAME ("virtio-rng") ",rng=rng0"); - } - - /* Add drives */ -@@ -477,7 +477,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - if (virtio_scsi) { - /* Create the virtio-scsi bus. */ - ADD_CMDLINE ("-device"); -- ADD_CMDLINE (VIRTIO_SCSI ",id=scsi"); -+ ADD_CMDLINE (VIRTIO_DEVICE_NAME ("virtio-scsi") ",id=scsi"); - } - - ITER_DRIVES (g, i, drv) { -@@ -564,7 +564,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - ADD_CMDLINE ("-drive"); - ADD_CMDLINE_PRINTF ("%s,if=none" /* sic */, param); - ADD_CMDLINE ("-device"); -- ADD_CMDLINE_PRINTF (VIRTIO_BLK ",drive=hd%zu", i); -+ ADD_CMDLINE_PRINTF (VIRTIO_DEVICE_NAME ("virtio-blk") ",drive=hd%zu", i); - } - } - -@@ -581,7 +581,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - } - else { - ADD_CMDLINE ("-device"); -- ADD_CMDLINE (VIRTIO_BLK ",drive=appliance"); -+ ADD_CMDLINE (VIRTIO_DEVICE_NAME ("virtio-blk") ",drive=appliance"); - } - - appliance_dev = make_appliance_dev (g, virtio_scsi); -@@ -589,7 +589,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - - /* Create the virtio serial bus. */ - ADD_CMDLINE ("-device"); -- ADD_CMDLINE (VIRTIO_SERIAL); -+ ADD_CMDLINE (VIRTIO_DEVICE_NAME ("virtio-serial")); - - /* Create the serial console. */ - #ifndef __s390x__ -@@ -626,7 +626,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - ADD_CMDLINE ("-netdev"); - ADD_CMDLINE ("user,id=usernet,net=169.254.0.0/16"); - ADD_CMDLINE ("-device"); -- ADD_CMDLINE (VIRTIO_NET ",netdev=usernet"); -+ ADD_CMDLINE (VIRTIO_DEVICE_NAME ("virtio-net") ",netdev=usernet"); - } - - ADD_CMDLINE ("-append"); -diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c -index 49bd40583..d10c7cb40 100644 ---- a/lib/launch-libvirt.c -+++ b/lib/launch-libvirt.c -@@ -1803,7 +1803,7 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g, - } end_element (); - - start_element ("qemu:arg") { -- attribute ("value", VIRTIO_NET ",netdev=usernet"); -+ attribute ("value", VIRTIO_DEVICE_NAME ("virtio-net") ",netdev=usernet"); - } end_element (); - } - -diff --git a/lib/qemu.c b/lib/qemu.c -index c9debe937..887e31bc4 100644 ---- a/lib/qemu.c -+++ b/lib/qemu.c -@@ -619,7 +619,7 @@ guestfs_int_qemu_supports_virtio_scsi (guestfs_h *g, struct qemu_data *data, - if (old_or_broken_virtio_scsi (qemu_version)) - data->virtio_scsi = 2; - else { -- r = guestfs_int_qemu_supports_device (g, data, VIRTIO_SCSI); -+ r = guestfs_int_qemu_supports_device (g, data, VIRTIO_DEVICE_NAME ("virtio-scsi")); - if (r > 0) - data->virtio_scsi = 1; - else if (r == 0) --- -2.14.3 - diff --git a/SOURCES/0042-v2v-o-rhv-upload-install-RHV-tools-RHBZ-1561828.patch b/SOURCES/0042-v2v-o-rhv-upload-install-RHV-tools-RHBZ-1561828.patch new file mode 100644 index 0000000..234c4db --- /dev/null +++ b/SOURCES/0042-v2v-o-rhv-upload-install-RHV-tools-RHBZ-1561828.patch @@ -0,0 +1,31 @@ +From 18b5c51228765dbb481cad9db3b9fdc73a7056a2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= +Date: Sun, 22 Apr 2018 22:57:55 +0200 +Subject: [PATCH] v2v: -o rhv-upload: install RHV tools (RHBZ#1561828). +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Tomáš Golembiovský +(cherry picked from commit f3f00d3f9c6464aa31e3091bdee1191ef15512c6) +--- + v2v/output_rhv_upload.ml | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml +index dc0d96d53..0152b8d5a 100644 +--- a/v2v/output_rhv_upload.ml ++++ b/v2v/output_rhv_upload.ml +@@ -247,6 +247,9 @@ object + + method supported_firmware = [ TargetBIOS ] + ++ (* rhev-apt.exe will be installed (if available). *) ++ method install_rhev_apt = true ++ + method prepare_targets source targets = + let output_name = source.s_name in + let json_params = +-- +2.17.1 + diff --git a/SOURCES/0043-v2v-Map-Windows-Server-2012-R2-x86-64-to-ovirt-ID-25.patch b/SOURCES/0043-v2v-Map-Windows-Server-2012-R2-x86-64-to-ovirt-ID-25.patch new file mode 100644 index 0000000..bf5e99f --- /dev/null +++ b/SOURCES/0043-v2v-Map-Windows-Server-2012-R2-x86-64-to-ovirt-ID-25.patch @@ -0,0 +1,30 @@ +From c7de26ba87427294bae1d5e597f2c6cb80bd5dd3 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 1 May 2018 11:30:11 +0100 +Subject: [PATCH] v2v: Map Windows Server 2012 R2 x86-64 to ovirt ID 25. + +Thanks: Michal Skrivanek + +Fixes commit 593a19cc86cfa8f24c66518c8ba21222550b066a. + +(cherry picked from commit c6e89299299f1f620437ac3d05a1f0f12de0f208) +--- + v2v/create_ovf.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml +index c29b8421c..190cf8bed 100644 +--- a/v2v/create_ovf.ml ++++ b/v2v/create_ovf.ml +@@ -418,7 +418,7 @@ and get_ovirt_osid = function + + | { i_type = "windows"; i_major_version = 6; i_minor_version = 3; + i_arch = "x86_64" } -> +- 23 ++ 25 + + | { i_type = "windows"; i_major_version = 10; i_minor_version = 0; + i_arch = "i386" } -> +-- +2.17.1 + diff --git a/SOURCES/0043-v2v-i-vmx-Allow-deviceType-field-to-be-completely-om.patch b/SOURCES/0043-v2v-i-vmx-Allow-deviceType-field-to-be-completely-om.patch deleted file mode 100644 index 718d515..0000000 --- a/SOURCES/0043-v2v-i-vmx-Allow-deviceType-field-to-be-completely-om.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 46aaa657c76d473fcd6ac41a84101d7805306f58 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 11 Oct 2017 13:43:26 +0100 -Subject: [PATCH] v2v: -i vmx: Allow deviceType field to be completely omitted. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Microsoft make some VMX files available here which we could not parse. -These files lack the expected ‘scsi0:0.deviceType’ field: -https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/ - -According to -http://faq.sanbarrow.com/index.php?action=artikel&cat=7&id=54&artlang=en -this is permitted. Also several other deviceType values may be found. - -Allow such VMX to be parsed. - -Thanks: Tom Sorensen - -Cherry picked from commit 418289029da9641b74984eb15eb1563649c38dd1. -For RHEL 7.5: I inlined the Option.map function since that does not -exist in this branch. ---- - v2v/input_vmx.ml | 19 +++++++++++-------- - 1 file changed, 11 insertions(+), 8 deletions(-) - -diff --git a/v2v/input_vmx.ml b/v2v/input_vmx.ml -index bb09f0bf8..a4f77c2ab 100644 ---- a/v2v/input_vmx.ml -+++ b/v2v/input_vmx.ml -@@ -35,7 +35,8 @@ let rec find_disks vmx vmx_filename = - * - * In the VMX file: - * scsi0.virtualDev = "pvscsi" # or may be "lsilogic" etc. -- * scsi0:0.deviceType = "scsi-hardDisk" -+ * scsi0:0.deviceType = "disk" | "plainDisk" | "rawDisk" | "scsi-hardDisk" -+ * | omitted - * scsi0:0.fileName = "guest.vmdk" - *) - and find_scsi_disks vmx vmx_filename = -@@ -46,7 +47,8 @@ and find_scsi_disks vmx vmx_filename = - try ignore (get_scsi_controller_target ns); true - with Scanf.Scan_failure _ | End_of_file | Failure _ -> false - in -- let scsi_device_types = [ "scsi-harddisk" ] in -+ let scsi_device_types = [ Some "disk"; Some "plaindisk"; Some "rawdisk"; -+ Some "scsi-harddisk"; None ] in - let scsi_controller = Source_SCSI in - - find_hdds vmx vmx_filename -@@ -67,7 +69,7 @@ and find_ide_disks vmx vmx_filename = - try ignore (get_ide_controller_target ns); true - with Scanf.Scan_failure _ | End_of_file | Failure _ -> false - in -- let ide_device_types = [ "ata-harddisk" ] in -+ let ide_device_types = [ Some "ata-harddisk" ] in - let ide_controller = Source_IDE in - - find_hdds vmx vmx_filename -@@ -86,11 +88,12 @@ and find_hdds vmx vmx_filename - if not (is_controller_target ns) then false - else ( - (* Check the deviceType is one we are looking for. *) -- match Parse_vmx.get_string vmx [ns; "deviceType"] with -- | Some str -> -- let str = String.lowercase_ascii str in -- List.mem str device_types -- | None -> false -+ let dt = Parse_vmx.get_string vmx [ns; "deviceType"] in -+ let dt = -+ match dt with -+ | None -> None -+ | Some dt -> Some (String.lowercase_ascii dt) in -+ List.mem dt device_types - ) - | _ -> false - ) vmx in --- -2.14.3 - diff --git a/SOURCES/0044-v2v-fix-build-rules-for-output_rhv_upload_-_source.m.patch b/SOURCES/0044-v2v-fix-build-rules-for-output_rhv_upload_-_source.m.patch new file mode 100644 index 0000000..7090b86 --- /dev/null +++ b/SOURCES/0044-v2v-fix-build-rules-for-output_rhv_upload_-_source.m.patch @@ -0,0 +1,54 @@ +From 5510a19932860b170bf6186f0bf5624342d1241a Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 22 May 2018 17:24:18 +0200 +Subject: [PATCH] v2v: fix build rules for output_rhv_upload_*_source.ml files + +Use the $(srcdir) variable where needed, to make sure it builds also +with srcdir != builddir. + +Furthermore, make sure that the OCaml dependencies calculation depend on +the generated output_rhv_upload_*_source.ml files, otherwise there will +be incomplete OCaml rules for them in the generated .depend. + +Fixes commit cc04573927cca97de60d544d37467e67c25867a7. + +(cherry picked from commit a4e3b7c0598370d8d068b21909da95b6031eb688) +--- + v2v/Makefile.am | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/v2v/Makefile.am b/v2v/Makefile.am +index 0f8c5120b..64bf5235c 100644 +--- a/v2v/Makefile.am ++++ b/v2v/Makefile.am +@@ -143,12 +143,12 @@ SOURCES_C = \ + + # These files are generated and contain rhv-upload-*.py embedded as an + # OCaml string. +-output_rhv_upload_createvm_source.ml: rhv-upload-createvm.py +- ./embed.sh code $^ $@ +-output_rhv_upload_plugin_source.ml: rhv-upload-plugin.py +- ./embed.sh code $^ $@ +-output_rhv_upload_precheck_source.ml: rhv-upload-precheck.py +- ./embed.sh code $^ $@ ++output_rhv_upload_createvm_source.ml: $(srcdir)/rhv-upload-createvm.py ++ $(srcdir)/embed.sh code $^ $@ ++output_rhv_upload_plugin_source.ml: $(srcdir)/rhv-upload-plugin.py ++ $(srcdir)/embed.sh code $^ $@ ++output_rhv_upload_precheck_source.ml: $(srcdir)/rhv-upload-precheck.py ++ $(srcdir)/embed.sh code $^ $@ + + if HAVE_OCAML + +@@ -573,7 +573,7 @@ v2v_unit_tests_LINK = \ + $(v2v_unit_tests_THEOBJECTS) -o $@ + + # Dependencies. +-.depend: $(srcdir)/*.mli $(srcdir)/*.ml ++.depend: $(srcdir)/*.mli $(srcdir)/*.ml output_rhv_upload_createvm_source.ml output_rhv_upload_plugin_source.ml output_rhv_upload_precheck_source.ml + $(top_builddir)/ocaml-dep.sh $^ + -include .depend + +-- +2.17.1 + diff --git a/SOURCES/0044-v2v-i-vmx-Add-a-test-case-which-lacks-scsi0-0.device.patch b/SOURCES/0044-v2v-i-vmx-Add-a-test-case-which-lacks-scsi0-0.device.patch deleted file mode 100644 index f0522a5..0000000 --- a/SOURCES/0044-v2v-i-vmx-Add-a-test-case-which-lacks-scsi0-0.device.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 18f83f6a6945e7356a880c6b861c758e399ac55c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 11 Oct 2017 13:33:12 +0100 -Subject: [PATCH] v2v: -i vmx: Add a test case which lacks scsi0:0.deviceType = - "scsi-hardDisk" - -VMX file from: -https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/ - -Thanks: Tom Sorensen -(cherry picked from commit 6c54b68acb707d8f3dcd80453c23f57c54989be9) ---- - v2v/test-v2v-i-vmx-5.expected | 19 ++++++++++ - v2v/test-v2v-i-vmx-5.vmx | 80 +++++++++++++++++++++++++++++++++++++++++++ - v2v/test-v2v-i-vmx.sh | 2 +- - 3 files changed, 100 insertions(+), 1 deletion(-) - create mode 100644 v2v/test-v2v-i-vmx-5.expected - create mode 100644 v2v/test-v2v-i-vmx-5.vmx - -diff --git a/v2v/test-v2v-i-vmx-5.expected b/v2v/test-v2v-i-vmx-5.expected -new file mode 100644 -index 000000000..4a33db13c ---- /dev/null -+++ b/v2v/test-v2v-i-vmx-5.expected -@@ -0,0 +1,19 @@ -+ -+Source guest information (--print-source option): -+ -+ source name: MSEdge - Win10_preview -+hypervisor type: vmware -+ memory: 2147483648 (bytes) -+ nr vCPUs: 1 -+ CPU features: -+ firmware: bios -+ display: -+ video: -+ sound: -+disks: -+ /MSEdge - Win10_preview.vmdk (vmdk) [scsi] -+removable media: -+ -+NICs: -+ Bridge "ethernet0" mac: 00:0c:29:bf:e4:5d [e1000e] -+ -diff --git a/v2v/test-v2v-i-vmx-5.vmx b/v2v/test-v2v-i-vmx-5.vmx -new file mode 100644 -index 000000000..eb54d85be ---- /dev/null -+++ b/v2v/test-v2v-i-vmx-5.vmx -@@ -0,0 +1,80 @@ -+.encoding = "UTF-8" -+config.version = "8" -+virtualHW.version = "11" -+memsize = "2048" -+MemAllowAutoScaleDown = "FALSE" -+displayName = "MSEdge - Win10_preview" -+guestOS = "windows9-64" -+cpuid.coresPerSocket = "1" -+vmci0.present = "TRUE" -+ethernet0.present = "TRUE" -+ethernet0.addressType = "generated" -+ethernet0.connectionType = "bridged" -+ethernet0.virtualDev = "e1000e" -+ethernet0.startConnected = "TRUE" -+scsi0.present = "TRUE" -+scsi0.virtualDev = "lsisas1068" -+scsi0:0.present = "TRUE" -+scsi0:0.fileName = "MSEdge - Win10_preview.vmdk" -+bios.bootorder = "hdd,CDROM" -+cleanshutdown = "TRUE" -+ethernet0.bsdname = "en0" -+ethernet0.displayname = "Ethernet" -+ethernet0.linkstatepropagation.enable = "FALSE" -+gui.fullscreenatpoweron = "FALSE" -+gui.viewmodeatpoweron = "windowed" -+hgfs.linkrootshare = "TRUE" -+hgfs.maprootshare = "TRUE" -+isolation.tools.hgfs.disable = "FALSE" -+monitor.phys_bits_used = "42" -+msg.autoanswer = "true" -+numa.autosize.cookie = "10001" -+numa.autosize.vcpu.maxpervirtualnode = "1" -+nvram = "MSEdge - Win10_preview.nvram" -+proxyapps.publishtohost = "FALSE" -+remotedisplay.vnc.enabled = "FALSE" -+remotedisplay.vnc.port = "5900" -+replay.filename = "" -+replay.supported = "FALSE" -+scsi0:0.redo = "" -+softpoweroff = "TRUE" -+tools.synctime = "true" -+uuid.action = "create" -+virtualhw.productcompatibility = "hosted" -+vm.genid = "-570734802784577186" -+vm.genidx = "-5042519231342505152" -+vmotion.checkpointfbsize = "33554432" -+pciBridge0.present = "TRUE" -+tools.upgrade.policy = "useGlobal" -+pciBridge4.present = "TRUE" -+pciBridge4.virtualDev = "pcieRootPort" -+pciBridge4.functions = "8" -+pciBridge5.present = "TRUE" -+pciBridge5.virtualDev = "pcieRootPort" -+pciBridge5.functions = "8" -+pciBridge6.present = "TRUE" -+pciBridge6.virtualDev = "pcieRootPort" -+pciBridge6.functions = "8" -+pciBridge7.present = "TRUE" -+pciBridge7.virtualDev = "pcieRootPort" -+pciBridge7.functions = "8" -+hpet0.present = "TRUE" -+extendedConfigFile = "MSEdge - Win10_preview.vmxf" -+uuid.bios = "56 4d 54 59 5d 0c 51 8d-d3 40 38 4f fe bf e4 5d" -+uuid.location = "56 4d 54 59 5d 0c 51 8d-d3 40 38 4f fe bf e4 5d" -+migrate.hostlog = ".\MSEdge - Win10_preview-aee69569.hlog" -+pciBridge0.pciSlotNumber = "17" -+pciBridge4.pciSlotNumber = "21" -+pciBridge5.pciSlotNumber = "22" -+pciBridge6.pciSlotNumber = "23" -+pciBridge7.pciSlotNumber = "24" -+scsi0.pciSlotNumber = "160" -+ethernet0.pciSlotNumber = "192" -+vmci0.pciSlotNumber = "32" -+scsi0.sasWWID = "50 05 05 69 5d 0c 51 80" -+ethernet0.generatedAddress = "00:0c:29:bf:e4:5d" -+ethernet0.generatedAddressOffset = "0" -+vmci0.id = "-20978595" -+vmotion.checkpointSVGAPrimarySize = "33554432" -+toolsInstallManager.updateCounter = "1" -+toolsInstallManager.lastInstallError = "21004" -diff --git a/v2v/test-v2v-i-vmx.sh b/v2v/test-v2v-i-vmx.sh -index 997103d41..3822e7426 100755 ---- a/v2v/test-v2v-i-vmx.sh -+++ b/v2v/test-v2v-i-vmx.sh -@@ -29,7 +29,7 @@ export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win" - - rm -f test-v2v-i-vmx-*.actual - --for i in 1 2 3 4; do -+for i in 1 2 3 4 5; do - $VG virt-v2v --debug-gc \ - -i vmx test-v2v-i-vmx-$i.vmx \ - --print-source > test-v2v-i-vmx-$i.actual --- -2.14.3 - diff --git a/SOURCES/0045-v2v-fix-rhevexp-typo-in-documentation.patch b/SOURCES/0045-v2v-fix-rhevexp-typo-in-documentation.patch new file mode 100644 index 0000000..f2659d0 --- /dev/null +++ b/SOURCES/0045-v2v-fix-rhevexp-typo-in-documentation.patch @@ -0,0 +1,37 @@ +From c49781bcea6367dd17e9245783a14964fd45e555 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 29 May 2018 06:49:23 +0200 +Subject: [PATCH] v2v: fix "rhevexp" typo in documentation + +Spotted by Ming Xie. + +(cherry picked from commit c021ac5e64053052a392762aaff9c8ed73fc2082) +--- + v2v/virt-v2v.pod | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 62b726b8f..806225be0 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -601,7 +601,7 @@ Currently there are two possible flavours: + + =over 4 + +-=item rhevexp ++=item rhvexp + + The OVF format used in RHV export storage domain. + +@@ -611,7 +611,7 @@ The OVF format understood by oVirt REST API. + + =back + +-For backward compatibility the default is I, but this may change in ++For backward compatibility the default is I, but this may change in + the future. + + =item B<-op> file +-- +2.17.1 + diff --git a/SOURCES/0045-v2v-vddk-Print-passthrough-options.patch b/SOURCES/0045-v2v-vddk-Print-passthrough-options.patch deleted file mode 100644 index 355d423..0000000 --- a/SOURCES/0045-v2v-vddk-Print-passthrough-options.patch +++ /dev/null @@ -1,78 +0,0 @@ -From e94aedc6fc64f255ab1fa2fcd31f78e86c28c5de Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 16 Oct 2017 14:32:28 +0100 -Subject: [PATCH] v2v: vddk: Print passthrough options. - -Changes the output to look like: - -[ 0.0] Opening the source -i libvirt -ic vpx://... guestname --vddk ... --vddk-thumbprint ... - -(cherry picked from commit ce2aa47d1d79223c1a7a49b3f41e09078f22f554) ---- - v2v/input_libvirt_vddk.ml | 42 ++++++++++++++++++++++++++++++++---------- - 1 file changed, 32 insertions(+), 10 deletions(-) - -diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml -index 89d2552f6..b322a9c49 100644 ---- a/v2v/input_libvirt_vddk.ml -+++ b/v2v/input_libvirt_vddk.ml -@@ -101,8 +101,34 @@ See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") library_path - error (f_"You must pass the ‘--vddk-thumbprint’ option with the SSL thumbprint of the VMware server. To find the thumbprint, see the nbdkit-vddk-plugin(1) manual. See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") - in - -+ (* List of passthrough parameters. *) -+ let vddk_passthrus = -+ [ "config", (fun { vddk_config } -> vddk_config); -+ "cookie", (fun { vddk_cookie } -> vddk_cookie); -+ "nfchostport", (fun { vddk_nfchostport } -> vddk_nfchostport); -+ "port", (fun { vddk_port } -> vddk_port); -+ "snapshot", (fun { vddk_snapshot } -> vddk_snapshot); -+ "thumbprint", (fun { vddk_thumbprint } -> vddk_thumbprint); -+ "transports", (fun { vddk_transports } -> vddk_transports); -+ "vimapiver", (fun { vddk_vimapiver } -> vddk_vimapiver) ] in -+ - object -- inherit input_libvirt password libvirt_uri guest -+ inherit input_libvirt password libvirt_uri guest as super -+ -+ method as_options = -+ let pt_options = -+ String.concat "" ( -+ List.map ( -+ fun (name, get_field) -> -+ match get_field vddk_options with -+ | None -> "" -+ | Some field -> sprintf " --vddk-%s %s" name field -+ ) vddk_passthrus -+ ) in -+ sprintf "%s --vddk %s%s" -+ super#as_options (* superclass prints "-i libvirt etc" *) -+ vddk_options.vddk_libdir -+ pt_options - - method source () = - error_unless_vddk_libdir (); -@@ -209,15 +235,11 @@ object - add_arg (sprintf "libdir=%s" libdir); - - (* The passthrough parameters. *) -- let pt name = may (fun field -> add_arg (sprintf "%s=%s" name field)) in -- pt "config" vddk_options.vddk_config; -- pt "cookie" vddk_options.vddk_cookie; -- pt "nfchostport" vddk_options.vddk_nfchostport; -- pt "port" vddk_options.vddk_port; -- pt "snapshot" vddk_options.vddk_snapshot; -- pt "thumbprint" vddk_options.vddk_thumbprint; -- pt "transports" vddk_options.vddk_transports; -- pt "vimapiver" vddk_options.vddk_vimapiver; -+ List.iter ( -+ fun (name, get_field) -> -+ may (fun field -> add_arg (sprintf "%s=%s" name field)) -+ (get_field vddk_options) -+ ) vddk_passthrus; - - get_args () in - --- -2.14.3 - diff --git a/SOURCES/0046-v2v-add-and-use-Create_ovf.ovf_flavour_to_string.patch b/SOURCES/0046-v2v-add-and-use-Create_ovf.ovf_flavour_to_string.patch new file mode 100644 index 0000000..6662b99 --- /dev/null +++ b/SOURCES/0046-v2v-add-and-use-Create_ovf.ovf_flavour_to_string.patch @@ -0,0 +1,66 @@ +From ecbd5983e10adb6c5d95fdae1dc878a9905ae1b4 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 29 May 2018 07:04:50 +0200 +Subject: [PATCH] v2v: add and use Create_ovf.ovf_flavour_to_string + +Add an helper to convert an OVF flavour to string, and use it in +-o vdsm to print the actual value of the vdsm-ovf-flavour option. + +Thanks to Ming Xie. + +(cherry picked from commit c0da02f90d9b52413c24dd9dae61662ad033cc16) +--- + v2v/create_ovf.ml | 4 ++++ + v2v/create_ovf.mli | 3 +++ + v2v/output_vdsm.ml | 5 +++-- + 3 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml +index 190cf8bed..ac3c61b13 100644 +--- a/v2v/create_ovf.ml ++++ b/v2v/create_ovf.ml +@@ -40,6 +40,10 @@ let ovf_flavour_of_string = function + | "rhvexp" -> RHVExportStorageDomain + | flav -> invalid_arg flav + ++let ovf_flavour_to_string = function ++ | OVirt -> "ovirt" ++ | RHVExportStorageDomain -> "rhvexp" ++ + (* We set the creation time to be the same for all dates in + * all metadata files. All dates in OVF are UTC. + *) +diff --git a/v2v/create_ovf.mli b/v2v/create_ovf.mli +index 2d80660e3..8200b76f9 100644 +--- a/v2v/create_ovf.mli ++++ b/v2v/create_ovf.mli +@@ -29,6 +29,9 @@ val ovf_flavours : string list + valid flavour. *) + val ovf_flavour_of_string : string -> ovf_flavour + ++(** Convert an OVF flavour to its string representation. *) ++val ovf_flavour_to_string : ovf_flavour -> string ++ + (** Create OVF and related files for RHV. + + The format for RHV export storage domain is described in: +diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml +index 92b3fd122..9a1b748bc 100644 +--- a/v2v/output_vdsm.ml ++++ b/v2v/output_vdsm.ml +@@ -118,9 +118,10 @@ object + | "0.10" -> "" (* currently this is the default, so don't print it *) + | s -> sprintf " -oo vdsm-compat=%s" s) + (match vdsm_options.ovf_flavour with +- | Create_ovf.OVirt -> "-oo vdsm-ovf-flavour=ovf" + (* currently this is the default, so don't print it *) +- | Create_ovf.RHVExportStorageDomain -> "") ++ | Create_ovf.RHVExportStorageDomain -> "" ++ | flav -> sprintf "-oo vdsm-ovf-flavour=%s" ++ (Create_ovf.ovf_flavour_to_string flav)) + + method supported_firmware = [ TargetBIOS ] + +-- +2.17.1 + diff --git a/SOURCES/0046-v2v-vddk-Check-if-nbdkit-supports-selinux-label-befo.patch b/SOURCES/0046-v2v-vddk-Check-if-nbdkit-supports-selinux-label-befo.patch deleted file mode 100644 index 1401342..0000000 --- a/SOURCES/0046-v2v-vddk-Check-if-nbdkit-supports-selinux-label-befo.patch +++ /dev/null @@ -1,51 +0,0 @@ -From bf7dba21337b2671f877f4e37e5eb031b26fc6e2 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 17 Oct 2017 10:43:30 +0100 -Subject: [PATCH] v2v: vddk: Check if nbdkit supports --selinux-label before - using. - -Give a better error message if not. - -Thanks: Ming Xie. -(cherry picked from commit 59b4c4779f7dac645c794393d91c46467afab91c) ---- - v2v/input_libvirt_vddk.ml | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml -index b322a9c49..f0b150efa 100644 ---- a/v2v/input_libvirt_vddk.ml -+++ b/v2v/input_libvirt_vddk.ml -@@ -101,6 +101,20 @@ See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") library_path - error (f_"You must pass the ‘--vddk-thumbprint’ option with the SSL thumbprint of the VMware server. To find the thumbprint, see the nbdkit-vddk-plugin(1) manual. See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") - in - -+ (* Check that nbdkit was compiled with SELinux support (for the -+ * --selinux-label option). -+ *) -+ let error_unless_nbdkit_compiled_with_selinux () = -+ let lines = external_command "nbdkit --dump-config" in -+ (* In nbdkit <= 1.1.15 the selinux attribute was not present -+ * at all in --dump-config output so there was no way to tell. -+ * Ignore this case because there will be an error later when -+ * we try to use the --selinux-label parameter. -+ *) -+ if List.mem "selinux=no" (List.map String.trim lines) then -+ 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.") -+ in -+ - (* List of passthrough parameters. *) - let vddk_passthrus = - [ "config", (fun { vddk_config } -> vddk_config); -@@ -135,6 +149,8 @@ object - error_unless_nbdkit_working (); - error_unless_nbdkit_vddk_working (); - error_unless_thumbprint (); -+ if have_selinux then -+ error_unless_nbdkit_compiled_with_selinux (); - - (* Get the libvirt XML. This also checks (as a side-effect) - * that the domain is not running. (RHBZ#1138586) --- -2.14.3 - diff --git a/SOURCES/0047-daemon-Move-lvmetad-to-early-in-the-appliance-boot-p.patch b/SOURCES/0047-daemon-Move-lvmetad-to-early-in-the-appliance-boot-p.patch new file mode 100644 index 0000000..016437f --- /dev/null +++ b/SOURCES/0047-daemon-Move-lvmetad-to-early-in-the-appliance-boot-p.patch @@ -0,0 +1,225 @@ +From 3ad6840403edac13249d373d29c7d1f72b35c8b0 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 24 May 2018 10:24:25 +0100 +Subject: [PATCH] daemon: Move lvmetad to early in the appliance boot process. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When the daemon starts up it creates a fresh (empty) LVM configuration +and starts up lvmetad (which depends on the LVM configuration). + +However this appears to cause problems: Some types of PV seem to +require lvmetad and don't work without it +(https://bugzilla.redhat.com/show_bug.cgi?id=1581810). If we don't +start lvmetad earlier, the device nodes are not created. + +Therefore move the whole initialization step into appliance/init. + +Two further changes had to be made: + +Now we are using lvmetad all the time, using vgchange is incorrect. +With lvmetad activated early we must use ‘pvscan --cache --activate ay’ +to scan all disks for PVs and activate any VGs on them (although the +documentation is complex, confusing and contradictory so I'm not +completely sure about this). + +The ‘lvm_system_dir’ local variable in ‘daemon/lvm-filter.c’ +previously contained the path of the directory above $LVM_SYSTEM_DIR +(eg. $LVM_SYSTEM_DIR = "/etc/lvm", lvm_system_dir = "/etc"). As this +was highly confusing, I have changed it so the local variable and the +environment variable have identical contents. This involved removing +the ‘lvm/’ component from a couple of paths since it is now included +in the local variable. + +(cherry picked from commit dd162d2cd56a2ecf4bcd40a7f463940eaac875b8) +--- + appliance/init | 11 +++++- + daemon/daemon.h | 4 --- + daemon/guestfsd.c | 8 ----- + daemon/lvm-filter.c | 81 +++++++++++++-------------------------------- + 4 files changed, 33 insertions(+), 71 deletions(-) + +diff --git a/appliance/init b/appliance/init +index 1cd264e08..471d83cae 100755 +--- a/appliance/init ++++ b/appliance/init +@@ -130,9 +130,17 @@ echo nameserver 169.254.2.3 > /etc/resolv.conf + # Scan for MDs but don't run arrays unless all expected drives are present + mdadm -As --auto=yes --no-degraded + ++# Set up a clean LVM environment. ++# Empty LVM configuration file means "all defaults". ++mkdir -p /tmp/lvm ++touch /tmp/lvm/lvm.conf ++LVM_SYSTEM_DIR=/tmp/lvm ++export LVM_SYSTEM_DIR ++lvmetad ++ + # Scan for LVM. + modprobe dm_mod ||: +-lvm vgchange -aay --sysinit ++lvm pvscan --cache --activate ay + + # Scan for MDs and run all found arrays even they are in degraded state + mdadm -As --auto=yes --run +@@ -146,6 +154,7 @@ if test "$guestfs_verbose" = 1 && test "$guestfs_boot_analysis" != 1; then + ls -lR /dev + cat /proc/mounts + cat /proc/mdstat ++ lvm config + lvm pvs + lvm vgs + lvm lvs +diff --git a/daemon/daemon.h b/daemon/daemon.h +index 7958ba781..faaf1237e 100644 +--- a/daemon/daemon.h ++++ b/daemon/daemon.h +@@ -249,10 +249,6 @@ extern char *get_blkid_tag (const char *device, const char *tag); + /* lvm.c */ + extern int lv_canonical (const char *device, char **ret); + +-/* lvm-filter.c */ +-extern void clean_lvm_config (void); +-extern void start_lvmetad (void); +- + /* zero.c */ + extern void wipe_device_before_mkfs (const char *device); + +diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c +index 68d3de2ec..ae428e573 100644 +--- a/daemon/guestfsd.c ++++ b/daemon/guestfsd.c +@@ -233,14 +233,6 @@ main (int argc, char *argv[]) + _umask (0); + #endif + +- /* Make a private copy of /etc/lvm so we can change the config (see +- * daemon/lvm-filter.c). +- */ +- if (!test_mode) { +- clean_lvm_config (); +- start_lvmetad (); +- } +- + /* Connect to virtio-serial channel. */ + if (!channel) + channel = VIRTIO_SERIAL_CHANNEL; +diff --git a/daemon/lvm-filter.c b/daemon/lvm-filter.c +index ad85a7cc4..9d877c104 100644 +--- a/daemon/lvm-filter.c ++++ b/daemon/lvm-filter.c +@@ -36,71 +36,36 @@ + #include "daemon.h" + #include "actions.h" + +-/* This runs during daemon start up and creates a fresh LVM +- * configuration which we can modify as we desire. LVM allows +- * configuration to be completely empty (meaning "all defaults"). +- * +- * The final directory layout is: +- * +- * /tmp/lvmXXXXXX (lvm_system_dir set to this) +- * /tmp/lvmXXXXXX/lvm ($LVM_SYSTEM_DIR set to this) +- * /tmp/lvmXXXXXX/lvm/lvm.conf (configuration file - initially empty) +- */ +-static char lvm_system_dir[] = "/tmp/lvmXXXXXX"; +- +-static void rm_lvm_system_dir (void); + static void debug_lvm_config (void); + +-void +-clean_lvm_config (void) +-{ +- char env[64], conf[64]; +- FILE *fp; +- +- if (mkdtemp (lvm_system_dir) == NULL) +- error (EXIT_FAILURE, errno, "mkdtemp: %s", lvm_system_dir); +- +- snprintf (env, sizeof env, "%s/lvm", lvm_system_dir); +- mkdir (env, 0755); +- snprintf (conf, sizeof conf, "%s/lvm/lvm.conf", lvm_system_dir); +- fp = fopen (conf, "w"); +- if (fp == NULL) { +- perror ("clean_lvm_config: cannot create empty lvm.conf"); +- exit (EXIT_FAILURE); +- } +- fclose (fp); +- +- /* Set environment variable so we use the clean configuration. */ +- setenv ("LVM_SYSTEM_DIR", env, 1); +- +- /* Set a handler to remove the temporary directory at exit. */ +- atexit (rm_lvm_system_dir); ++/* Read LVM_SYSTEM_DIR environment variable, or set it to a default ++ * value if the environment variable is not set. ++ */ ++static char *lvm_system_dir; ++static void get_lvm_system_dir (void) __attribute__((constructor)); ++static void free_lvm_system_dir (void) __attribute__((destructor)); + +- debug_lvm_config (); +-} +- +-/* Try to run lvmetad, without failing if it couldn't. */ +-void +-start_lvmetad (void) ++static void ++get_lvm_system_dir (void) + { +- int r; ++ const char *p; + +- if (verbose) +- printf ("%s\n", "lvmetad"); +- r = system ("lvmetad"); +- if (r == -1) +- perror ("system/lvmetad"); +- else if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) +- fprintf (stderr, "warning: lvmetad command failed\n"); ++ p = getenv ("LVM_SYSTEM_DIR"); ++ if (p) { ++ lvm_system_dir = strdup (p); ++ if (lvm_system_dir == NULL) abort (); ++ } ++ if (!lvm_system_dir) { ++ lvm_system_dir = strdup ("/etc/lvm"); ++ if (lvm_system_dir == NULL) abort (); ++ } ++ fprintf (stderr, "lvm_system_dir = %s\n", lvm_system_dir); + } + + static void +-rm_lvm_system_dir (void) ++free_lvm_system_dir (void) + { +- char cmd[64]; +- +- snprintf (cmd, sizeof cmd, "rm -rf %s", lvm_system_dir); +- ignore_value (system (cmd)); ++ free (lvm_system_dir); + } + + /* Rewrite the 'filter = [ ... ]' line in lvm.conf. */ +@@ -112,7 +77,7 @@ set_filter (char *const *filters) + FILE *fp; + size_t i, j; + +- if (asprintf (&conf, "%s/lvm/lvm.conf", lvm_system_dir) == -1) { ++ if (asprintf (&conf, "%s/lvm.conf", lvm_system_dir) == -1) { + reply_with_perror ("asprintf"); + return -1; + } +@@ -177,7 +142,7 @@ static int + rescan (void) + { + char lvm_cache[64]; +- snprintf (lvm_cache, sizeof lvm_cache, "%s/lvm/cache/.cache", lvm_system_dir); ++ snprintf (lvm_cache, sizeof lvm_cache, "%s/cache/.cache", lvm_system_dir); + + unlink (lvm_cache); + +-- +2.17.1 + diff --git a/SOURCES/0047-v2v-vddk-Force-source-format-to-raw.patch b/SOURCES/0047-v2v-vddk-Force-source-format-to-raw.patch deleted file mode 100644 index 0771002..0000000 --- a/SOURCES/0047-v2v-vddk-Force-source-format-to-raw.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 37f2bf9dff5e01904556248203f1dce9c9034eed Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 17 Oct 2017 10:56:14 +0100 -Subject: [PATCH] v2v: vddk: Force source format to raw. - -Thanks: Ming Xie. -(cherry picked from commit 2ff287c4a7f12c26b8fb3a574129fbfb9a9157e7) ---- - v2v/input_libvirt_vddk.ml | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml -index f0b150efa..33b34bd2e 100644 ---- a/v2v/input_libvirt_vddk.ml -+++ b/v2v/input_libvirt_vddk.ml -@@ -338,7 +338,11 @@ If the messages above are not sufficient to diagnose the problem then add the - *) - chmod sock 0o777; - -- { disk with s_qemu_uri = qemu_uri } -+ (* nbdkit from a vddk source always presents us with the raw -+ * disk blocks from the guest, so force the format to raw here. -+ *) -+ { disk with s_qemu_uri = qemu_uri; -+ s_format = Some "raw" } - ) disks in - - if verbose () then ( --- -2.14.3 - diff --git a/SOURCES/0048-v2v-Remove-dcpath-parameter-and-related-functionalit.patch b/SOURCES/0048-v2v-Remove-dcpath-parameter-and-related-functionalit.patch deleted file mode 100644 index 5eeaae5..0000000 --- a/SOURCES/0048-v2v-Remove-dcpath-parameter-and-related-functionalit.patch +++ /dev/null @@ -1,322 +0,0 @@ -From 8018cf4c1206253c0f58e79b9afc171b3855b826 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 13 Oct 2017 15:45:39 +0100 -Subject: [PATCH] v2v: Remove --dcpath parameter and related functionality. - -With modern libvirt, when fetching the XML of a VMware guest libvirt -passes us the datacenter path (dcpath). However with older libvirt we -had to guess this value, or else the user had to supply it on the -command line. - -This commit removes all the guessing code and the --dcpath parameter -(which will now give an error). - -This requires libvirt >= 1.2.20 for virt-v2v, released Oct 2015. - -(cherry picked from commit 3fdd923ce2d31e21a441042f9ded3c45dec6bbcb) ---- - v2v/cmdline.ml | 6 +---- - v2v/copy_to_local.ml | 15 ++++++------ - v2v/input_libvirt.ml | 4 ++-- - v2v/input_libvirt.mli | 4 ++-- - v2v/input_libvirt_vcenter_https.ml | 31 +++++++----------------- - v2v/input_libvirt_vcenter_https.mli | 2 +- - v2v/test-v2v-docs.sh | 2 +- - v2v/vCenter.ml | 47 +------------------------------------ - v2v/vCenter.mli | 8 ------- - v2v/virt-v2v.pod | 13 ---------- - 10 files changed, 24 insertions(+), 108 deletions(-) - -diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml -index 3050104d0..dfbb776ab 100644 ---- a/v2v/cmdline.ml -+++ b/v2v/cmdline.ml -@@ -54,7 +54,6 @@ let parse_cmdline () = - let print_source = ref false in - let qemu_boot = ref false in - -- let dcpath = ref None in - let input_conn = ref None in - let input_format = ref None in - let in_place = ref false in -@@ -181,8 +180,6 @@ let parse_cmdline () = - let argspec = [ - [ S 'b'; L"bridge" ], Getopt.String ("in:out", add_bridge), s_"Map bridge 'in' to 'out'"; - [ L"compressed" ], Getopt.Set compressed, s_"Compress output file (-of qcow2 only)"; -- [ L"dcpath"; L"dcPath" ], Getopt.String ("path", set_string_option_once "--dcpath" dcpath), -- s_"Override dcPath (for vCenter)"; - [ L"debug-overlay"; L"debug-overlays" ], Getopt.Set debug_overlays, s_"Save overlay files"; - [ S 'i' ], Getopt.String (i_options, set_input_mode), s_"Set input mode (default: libvirt)"; - [ M"ic" ], Getopt.String ("uri", set_string_option_once "-ic" input_conn), -@@ -268,7 +265,6 @@ read the man page virt-v2v(1). - (* Dereference the arguments. *) - let args = List.rev !args in - let compressed = !compressed in -- let dcpath = !dcpath in - let debug_overlays = !debug_overlays in - let do_copy = !do_copy in - let input_conn = !input_conn in -@@ -367,7 +363,7 @@ read the man page virt-v2v(1). - | [guest] -> guest - | _ -> - error (f_"expecting a libvirt guest name on the command line") in -- Input_libvirt.input_libvirt dcpath vddk_options password input_conn guest -+ Input_libvirt.input_libvirt vddk_options password input_conn guest - - | `LibvirtXML -> - (* -i libvirtxml: Expecting a filename (XML file). *) -diff --git a/v2v/copy_to_local.ml b/v2v/copy_to_local.ml -index 88fd9abde..ca5578f3f 100644 ---- a/v2v/copy_to_local.ml -+++ b/v2v/copy_to_local.ml -@@ -144,6 +144,11 @@ read the man page virt-v2v-copy-to-local(1). - let disks = - match source with - | ESXi server -> -+ let dcpath = -+ match dcpath with -+ | Some dcpath -> dcpath -+ | None -> -+ error (f_"vcenter: was not found in the XML. You need to upgrade to libvirt ≥ 1.2.20.") in - List.map ( - fun (remote_disk, local_disk) -> - let url, sslverify = -@@ -242,14 +247,10 @@ and parse_libvirt_xml guest_name xml = - let xpathctx = Xml.xpath_new_context doc in - Xml.xpath_register_ns xpathctx - "vmware" "http://libvirt.org/schemas/domain/vmware/1.0"; -- let xpath_string = xpath_string xpathctx -- and xpath_string_default = xpath_string_default xpathctx in -+ let xpath_string = xpath_string xpathctx in - -- (* Get the dcpath, only present for libvirt >= 1.2.20 so use a -- * sensible default for older versions. -- *) -- let dcpath = -- xpath_string_default "/domain/vmware:datacenterpath" "ha-datacenter" in -+ (* Get the dcpath, present in libvirt >= 1.2.20. *) -+ let dcpath = xpath_string "/domain/vmware:datacenterpath" in - - (* Parse the disks. *) - let get_disks, add_disk = -diff --git a/v2v/input_libvirt.ml b/v2v/input_libvirt.ml -index e8143b6ad..f4a8114f0 100644 ---- a/v2v/input_libvirt.ml -+++ b/v2v/input_libvirt.ml -@@ -27,7 +27,7 @@ open Types - open Utils - - (* Choose the right subclass based on the URI. *) --let input_libvirt dcpath vddk_options password libvirt_uri guest = -+let input_libvirt vddk_options password libvirt_uri guest = - match libvirt_uri with - | None -> - Input_libvirt_other.input_libvirt_other password libvirt_uri guest -@@ -54,7 +54,7 @@ let input_libvirt dcpath vddk_options password libvirt_uri guest = - (match vddk_options with - | None -> - Input_libvirt_vcenter_https.input_libvirt_vcenter_https -- dcpath password libvirt_uri parsed_uri scheme server guest -+ password libvirt_uri parsed_uri scheme server guest - | Some vddk_options -> - Input_libvirt_vddk.input_libvirt_vddk vddk_options password - libvirt_uri parsed_uri guest -diff --git a/v2v/input_libvirt.mli b/v2v/input_libvirt.mli -index 0a6aa3c54..acf2ca417 100644 ---- a/v2v/input_libvirt.mli -+++ b/v2v/input_libvirt.mli -@@ -18,7 +18,7 @@ - - (** [-i libvirt] source. *) - --val input_libvirt : string option -> Types.vddk_options option -> string option -> string option -> string -> Types.input --(** [input_libvirt dcpath vddk_options password libvirt_uri guest] creates -+val input_libvirt : Types.vddk_options option -> string option -> string option -> string -> Types.input -+(** [input_libvirt vddk_options password libvirt_uri guest] creates - and returns a new {!Types.input} object specialized for reading input - from libvirt sources. *) -diff --git a/v2v/input_libvirt_vcenter_https.ml b/v2v/input_libvirt_vcenter_https.ml -index df0e89315..497caca4f 100644 ---- a/v2v/input_libvirt_vcenter_https.ml -+++ b/v2v/input_libvirt_vcenter_https.ml -@@ -36,7 +36,7 @@ let readahead_for_copying = Some (64 * 1024 * 1024) - - (* Subclass specialized for handling VMware vCenter over https. *) - class input_libvirt_vcenter_https -- cmdline_dcPath password libvirt_uri parsed_uri scheme server guest = -+ password libvirt_uri parsed_uri scheme server guest = - object - inherit input_libvirt password libvirt_uri guest - -@@ -68,33 +68,18 @@ object - let xml = Libvirt_utils.dumpxml ?password ?conn:libvirt_uri guest in - let source, disks = parse_libvirt_xml ?conn:libvirt_uri xml in - -- (* Find the element from the XML, if it -- * exists. This was added in libvirt >= 1.2.20. -+ (* Find the element from the XML. This -+ * was added in libvirt >= 1.2.20. - *) -- let xml_dcPath = -+ dcPath <- ( - let doc = Xml.parse_memory xml in - let xpathctx = Xml.xpath_new_context doc in - Xml.xpath_register_ns xpathctx - "vmware" "http://libvirt.org/schemas/domain/vmware/1.0"; -- let xpath_string = xpath_string xpathctx in -- xpath_string "/domain/vmware:datacenterpath" in -- -- (* Calculate the dcPath we're going to use. *) -- dcPath <- ( -- match cmdline_dcPath, xml_dcPath with -- (* Command line --dcpath parameter overrides everything, allowing -- * users to correct any mistakes in v2v or libvirt. -- *) -- | Some p, (None|Some _) -> -- debug "vcenter: using --dcpath from the command line: %s" p; -- p -- | None, Some p -> -- debug "vcenter: using from libvirt: %s" p; -- p -- | None, None -> -- let p = VCenter.guess_dcPath parsed_uri scheme in -- debug "vcenter: guessed dcPath from URI: %s" p; -- p -+ match xpath_string xpathctx "/domain/vmware:datacenterpath" with -+ | Some dcPath -> dcPath -+ | None -> -+ error (f_"vcenter: was not found in the XML. You need to upgrade to libvirt ≥ 1.2.20.") - ); - - (* Save the original source paths, so that we can remap them again -diff --git a/v2v/input_libvirt_vcenter_https.mli b/v2v/input_libvirt_vcenter_https.mli -index 840b5a90f..d347f5fe6 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 : string option -> string option -> string option -> Xml.uri -> string -> string -> string -> Types.input -+val input_libvirt_vcenter_https : string option -> string option -> Xml.uri -> string -> string -> string -> Types.input -diff --git a/v2v/test-v2v-docs.sh b/v2v/test-v2v-docs.sh -index c5d98de7f..5e49d5240 100755 ---- a/v2v/test-v2v-docs.sh -+++ b/v2v/test-v2v-docs.sh -@@ -22,4 +22,4 @@ $TEST_FUNCTIONS - skip_if_skipped - - $top_srcdir/podcheck.pl virt-v2v.pod virt-v2v \ -- --ignore=--dcPath,--debug-overlay,--ic,--if,--in-place,--no-trim,--oa,--oc,--of,--on,--os,--vmtype -+ --ignore=--debug-overlay,--ic,--if,--in-place,--no-trim,--oa,--oc,--of,--on,--os,--vmtype -diff --git a/v2v/vCenter.ml b/v2v/vCenter.ml -index f6e4288f2..2f7e32ad6 100644 ---- a/v2v/vCenter.ml -+++ b/v2v/vCenter.ml -@@ -99,7 +99,7 @@ let get_session_cookie password scheme uri sslverify url = - - if status = "404" then ( - dump_response stderr; -- error (f_"vcenter: URL not found: %s\n\nThe '--dcpath' parameter may be useful. See the explanation in the virt-v2v(1) man page OPTIONS section.") url -+ error (f_"vcenter: URL not found: %s") url - ); - - if status <> "200" then ( -@@ -126,51 +126,6 @@ let get_session_cookie password scheme uri sslverify url = - Some !session_cookie - ) - --let multiple_slash = Str.regexp "/+" --let default_dc = "ha-datacenter" -- --let guess_dcPath uri = function -- | "vpx" -> -- (match uri.uri_path with -- | None -> -- warning (f_"vcenter: URI (-ic parameter) contains no path, so we cannot determine the dcPath (datacenter name)"); -- default_dc -- | Some path -> -- (* vCenter: URIs are *usually* '/Folder/Datacenter/esxi' so we can -- * just chop off the first '/' and final '/esxi' to get the dcPath. -- * -- * The libvirt driver allows things like '/DC///esxi////' so we also -- * have to handle trailing slashes and collapse multiple slashes into -- * single (RHBZ#1258342). -- * -- * However if there is a cluster involved then the URI may be -- * /Folder/Datacenter/Cluster/esxi but dcPath=Folder/Datacenter/Cluster -- * won't work. In this case the user has to adjust the path to -- * remove the Cluster name (which still works in libvirt). -- *) -- (* Collapse multiple slashes to single slash. *) -- let path = Str.global_replace multiple_slash "/" path in -- (* Chop off the first and trailing '/' (if found). *) -- let path = -- let len = String.length path in -- if len > 0 && path.[0] = '/' then -- String.sub path 1 (len-1) -- else path in -- let path = -- let len = String.length path in -- if len > 0 && path.[len-1] = '/' then -- String.sub path 0 (len-1) -- else path in -- (* Chop off the final element (ESXi hostname). *) -- let len = -- try String.rindex path '/' with Not_found -> String.length path in -- String.sub path 0 len -- ); -- | "esx" -> (* Connecting to an ESXi hypervisor directly, so it's fixed. *) -- default_dc -- | _ -> (* Don't know, so guess. *) -- default_dc -- - let source_re = Str.regexp "^\\[\\(.*\\)\\] \\(.*\\)\\.vmdk$" - - let map_source_to_https dcPath uri server path = -diff --git a/v2v/vCenter.mli b/v2v/vCenter.mli -index 224f45009..55d70b486 100644 ---- a/v2v/vCenter.mli -+++ b/v2v/vCenter.mli -@@ -35,14 +35,6 @@ val get_session_cookie : string option -> string -> Xml.uri -> bool -> string -> - The session cookie is memoized so you can call this function as - often as you want, and only a single log in is made. *) - --val guess_dcPath : Xml.uri -> string -> string --(** Try to guess the dcPath parameter from a URI. The mapping is -- not precise. -- -- This function is only used with [libvirt < 1.2.20] because later -- versions of libvirt provide the dcPath (see -- https://bugzilla.redhat.com/1263574). *) -- - val map_source_to_uri : int option -> string -> string option -> Xml.uri -> string -> string -> string -> string - (** [map_source_to_uri readahead dcPath password uri scheme server path] - maps the [] string to a qemu URI. -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index d713d0b1f..92ed147d7 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -172,19 +172,6 @@ Write a compressed output file. This is only allowed if the output - format is qcow2 (see I<-of> below), and is equivalent to the I<-c> - option of L. - --=item B<--dcpath> Folder/Datacenter -- --B You don't need to use this parameter if you have --S 1.2.20>. -- --For VMware vCenter, override the C parameter used to --select the datacenter. Virt-v2v can usually calculate this from the --C URI, but if it gets it wrong, then you can override it using --this setting. Go to your vCenter web folder interface, eg. --C (I a trailing slash), --and examine the C parameter in the URLs that appear on this --page. -- - =item B<--debug-overlays> - - Save the overlay file(s) created during conversion. This option is --- -2.14.3 - diff --git a/SOURCES/0048-v2v-o-rhv-upload-Set-inactivity-timeout-RHBZ-1586198.patch b/SOURCES/0048-v2v-o-rhv-upload-Set-inactivity-timeout-RHBZ-1586198.patch new file mode 100644 index 0000000..0355230 --- /dev/null +++ b/SOURCES/0048-v2v-o-rhv-upload-Set-inactivity-timeout-RHBZ-1586198.patch @@ -0,0 +1,42 @@ +From 92035bb2924846ea96aeeec9f9d76839c146eaca Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 5 Jun 2018 19:09:43 +0100 +Subject: [PATCH] v2v: -o rhv-upload: Set inactivity timeout (RHBZ#1586198). +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This increases the inactivity timeout for transfers from the default +(60 seconds in oVirt < 4.2.3, 600 seconds in >= 4.2.3), up to 1 hour, +so that we should never hit it for ordinary transfers. + +Note this requires oVirt >= 4.2.3. The corresponding oVirt fix was +https://bugzilla.redhat.com/1563278 + +I also replaced the deprecated ‘image’ parameter with ‘disk’. + +Thanks: Nir Soffer, Daniel Erez. +(cherry picked from commit f25404c65f8e078a3ca5bd5a1ab91343edd22506) +--- + v2v/rhv-upload-plugin.py | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 791c9e7d2..b4557b83c 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -123,9 +123,8 @@ def open(readonly): + # Create a new image transfer. + transfer = transfers_service.add( + types.ImageTransfer( +- image = types.Image( +- id = disk.id +- ) ++ disk = types.Disk(id = disk.id), ++ inactivity_timeout = 3600, + ) + ) + debug("transfer.id = %r" % transfer.id) +-- +2.17.1 + diff --git a/SOURCES/0049-v2v-linux-fix-kernel-detection-when-split-in-differe.patch b/SOURCES/0049-v2v-linux-fix-kernel-detection-when-split-in-differe.patch new file mode 100644 index 0000000..82eb875 --- /dev/null +++ b/SOURCES/0049-v2v-linux-fix-kernel-detection-when-split-in-differe.patch @@ -0,0 +1,110 @@ +From f9586e74f18110ab7a70e29a5a577afed0666ca0 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 22 May 2018 10:46:21 +0200 +Subject: [PATCH] v2v: linux: fix kernel detection when split in different + packages + +The current detection code for Linux kernels assumes that a kernel +package contains everything in it, i.e. the kernel itself, its modules, +and its configuration. However, since recent Ubuntu versions (e.g. +starting from 18.04) modules & config (with few more files) are split in +an own package, thus not detecting the modpath from installed vmlinuz +files. + +To overcome this situation, rework this detection a bit: +1) find the vmlinuz file as before, but then immediately make sure it + exists by stat'ing it +2) find the modules path from the package as before: +2a) if found, extract the version in the same step +2b) if not found, get the kernel version from the vmlinuz filename, + and use it to detect the modules path +3) check that the modules path exists + +The detection done in (2b) is based on the current packaging scheme +found in the most important Linux distributions (Fedora, RHEL, CentOS, +Debian, Ubuntu, openSUSE, AltLinux, and possibly more). The notable +exception is Arch Linux. + +As additional change, do not assume the config file is in the same +package as vmlinuz, but directly look into the filesystem using the +version we already have. + +(cherry picked from commit 500acb15f8f777e9fe99a60c4216daf84a92aae3) +--- + v2v/linux_kernels.ml | 47 +++++++++++++++++++++++++++++--------------- + 1 file changed, 31 insertions(+), 16 deletions(-) + +diff --git a/v2v/linux_kernels.ml b/v2v/linux_kernels.ml +index c047d6deb..24f61429d 100644 +--- a/v2v/linux_kernels.ml ++++ b/v2v/linux_kernels.ml +@@ -103,27 +103,42 @@ let detect_kernels (g : G.guestfs) inspect family bootloader = + None + ) + else ( +- (* Which of these is the kernel itself? *) ++ (* Which of these is the kernel itself? Also, make sure to check ++ * it exists by stat'ing it. ++ *) + let vmlinuz = List.find ( + fun filename -> String.is_prefix filename "/boot/vmlinuz-" + ) files in +- (* Which of these is the modpath? *) +- let modpath = List.find ( +- fun filename -> +- String.length filename >= 14 && +- String.is_prefix filename "/lib/modules/" +- ) files in +- +- (* Check vmlinuz & modpath exist. *) +- if not (g#is_dir ~followsymlinks:true modpath) then +- raise Not_found; + let vmlinuz_stat = + try g#statns vmlinuz with G.Error _ -> raise Not_found in + +- (* Get/construct the version. XXX Read this from kernel file. *) +- let version = +- let prefix_len = String.length "/lib/modules/" in +- String.sub modpath prefix_len (String.length modpath - prefix_len) in ++ (* Determine the modpath from the package, falling back to the ++ * version in the vmlinuz file name. ++ *) ++ let modpath, version = ++ let prefix = "/lib/modules/" in ++ try ++ let prefix_len = String.length prefix in ++ List.find_map ( ++ fun filename -> ++ let filename_len = String.length filename in ++ if filename_len > prefix_len && ++ String.is_prefix filename prefix then ( ++ let version = String.sub filename prefix_len ++ (filename_len - prefix_len) in ++ Some (filename, version) ++ ) else ++ None ++ ) files ++ with Not_found -> ++ let version = ++ String.sub vmlinuz 14 (String.length vmlinuz - 14) in ++ let modpath = prefix ^ version in ++ modpath, version in ++ ++ (* Check that the modpath exists. *) ++ if not (g#is_dir ~followsymlinks:true modpath) then ++ raise Not_found; + + (* Find the initramfs which corresponds to the kernel. + * Since the initramfs is built at runtime, and doesn't have +@@ -188,7 +203,7 @@ let detect_kernels (g : G.guestfs) inspect family bootloader = + + let config_file = + let cfg = "/boot/config-" ^ version in +- if List.mem cfg files then Some cfg ++ if g#is_file ~followsymlinks:true cfg then Some cfg + else None in + + let kernel_supports what kconf = +-- +2.17.1 + diff --git a/SOURCES/0049-v2v-vCenter-Refactor-the-API-to-this-module.patch b/SOURCES/0049-v2v-vCenter-Refactor-the-API-to-this-module.patch deleted file mode 100644 index fe05d32..0000000 --- a/SOURCES/0049-v2v-vCenter-Refactor-the-API-to-this-module.patch +++ /dev/null @@ -1,496 +0,0 @@ -From f00bde700faf0708c8af440efdcc6b48e93f3ce4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 13 Oct 2017 16:30:16 +0100 -Subject: [PATCH] v2v: vCenter: Refactor the API to this module. - -This module had a selection of functions taking a different mix of -parameters and doing slightly different things. You could call one -function to return an https://... URL, or another function to return a -qemu URL, and there was a third function to get the session cookie but -you generally had to call that anyway (and it was implicitly called -when making the qemu URL!) - -Integrate these into a single function which returns a struct -returning all possible values. - -This is conceptually refactoring, except that the session cookie is no -longer memoized, but we didn't use this feature (of calling -get_session_cookie multiple times) anyway. - -(cherry picked from commit fb79fcde2947ff7e73f96343e8311e43b22a6f66) ---- - v2v/copy_to_local.ml | 12 +- - v2v/input_libvirt_vcenter_https.ml | 12 +- - v2v/vCenter.ml | 319 +++++++++++++++++++------------------ - v2v/vCenter.mli | 66 +++++--- - 4 files changed, 211 insertions(+), 198 deletions(-) - -diff --git a/v2v/copy_to_local.ml b/v2v/copy_to_local.ml -index ca5578f3f..5fb1b79ff 100644 ---- a/v2v/copy_to_local.ml -+++ b/v2v/copy_to_local.ml -@@ -151,14 +151,10 @@ read the man page virt-v2v-copy-to-local(1). - error (f_"vcenter: was not found in the XML. You need to upgrade to libvirt ≥ 1.2.20.") in - List.map ( - fun (remote_disk, local_disk) -> -- let url, sslverify = -- VCenter.map_source_to_https dcpath parsed_uri -- server remote_disk in -- debug "esxi: source disk %s (sslverify=%b)" url sslverify; -- let cookie = -- VCenter.get_session_cookie password "esx" -- parsed_uri sslverify url in -- (url, local_disk, sslverify, cookie) -+ let { VCenter.https_url; sslverify; session_cookie } = -+ VCenter.map_source dcpath parsed_uri "esx" server remote_disk in -+ debug "esxi: source disk %s (sslverify=%b)" https_url sslverify; -+ (https_url, local_disk, sslverify, session_cookie) - ) disks - | Test | Xen_ssh _ -> - List.map (fun (remote_disk, local_disk) -> -diff --git a/v2v/input_libvirt_vcenter_https.ml b/v2v/input_libvirt_vcenter_https.ml -index 497caca4f..1153e74a3 100644 ---- a/v2v/input_libvirt_vcenter_https.ml -+++ b/v2v/input_libvirt_vcenter_https.ml -@@ -102,9 +102,9 @@ object - | { p_source = P_source_dev _ } -> assert false - | { p_source_disk = disk; p_source = P_dont_rewrite } -> disk - | { p_source_disk = disk; p_source = P_source_file path } -> -- let qemu_uri = -- VCenter.map_source_to_uri readahead dcPath password -- parsed_uri scheme server path in -+ let { VCenter.qemu_uri } = -+ VCenter.map_source ?readahead ?password -+ dcPath parsed_uri scheme server path in - - (* The libvirt ESX driver doesn't normally specify a format, but - * the format of the -flat file is *always* raw, so force it here. -@@ -123,9 +123,9 @@ object - | None -> () - | Some orig_path -> - let readahead = readahead_for_copying in -- let backing_qemu_uri = -- VCenter.map_source_to_uri readahead dcPath password -- parsed_uri scheme server orig_path in -+ let { VCenter.qemu_uri = backing_qemu_uri } = -+ VCenter.map_source ?readahead ?password -+ dcPath parsed_uri scheme server orig_path in - - (* Rebase the qcow2 overlay to adjust the readahead parameter. *) - let cmd = [ "qemu-img"; "rebase"; "-u"; "-b"; backing_qemu_uri; -diff --git a/v2v/vCenter.ml b/v2v/vCenter.ml -index 2f7e32ad6..341a40b25 100644 ---- a/v2v/vCenter.ml -+++ b/v2v/vCenter.ml -@@ -38,167 +38,168 @@ let uri_quote str = - done; - String.concat "" (List.rev !xs) - --(* Memoized session cookie. *) --let session_cookie = ref "" -- --let get_session_cookie password scheme uri sslverify url = -- if !session_cookie <> "" then -- Some !session_cookie -- else ( -- let curl_args = ref [ -- "head", None; -- "silent", None; -- "url", Some url; -- ] in -- (match uri.uri_user, password with -- | None, None -> () -- | None, Some _ -> -- warning (f_"--password-file parameter ignored because 'user@' was not given in the URL") -- | Some user, None -> -- push_back curl_args ("user", Some user) -- | Some user, Some password -> -- push_back curl_args ("user", Some (user ^ ":" ^ password)) -- ); -- if not sslverify then push_back curl_args ("insecure", None); -- -- let curl_h = Curl.create !curl_args in -- let lines = Curl.run curl_h in -- -- let dump_response chan = -- Curl.print chan curl_h; -- -- (* Dump out the output of the command. *) -- List.iter (fun x -> fprintf chan "%s\n" x) lines; -- flush chan -- in -- -- if verbose () then dump_response stderr; -- -- (* Look for the last HTTP/x.y NNN status code in the output. *) -- let status = ref "" in -- List.iter ( -- fun line -> -- let len = String.length line in -- if len >= 12 && String.sub line 0 5 = "HTTP/" then -- status := String.sub line 9 3 -- ) lines; -- let status = !status in -- if status = "" then ( -- dump_response stderr; -- error (f_"vcenter: no status code in output of 'curl' command. Is 'curl' installed?") -- ); -- -- if status = "401" then ( -- dump_response stderr; -- if uri.uri_user <> None then -- error (f_"vcenter: incorrect username or password") -- else -- error (f_"vcenter: incorrect username or password. You might need to specify the username in the URI like this: %s://USERNAME@[etc]") -- scheme -- ); -- -- if status = "404" then ( -- dump_response stderr; -- error (f_"vcenter: URL not found: %s") url -- ); -- -- if status <> "200" then ( -- dump_response stderr; -- error (f_"vcenter: invalid response from server") -- ); -- -- (* Get the cookie. *) -- List.iter ( -- fun line -> -- let len = String.length line in -- if len >= 12 && String.sub line 0 12 = "Set-Cookie: " then ( -- let line = String.sub line 12 (len-12) in -- let cookie, _ = String.split ";" line in -- session_cookie := cookie -- ) -- ) lines; -- if !session_cookie = "" then ( -- dump_response stderr; -- warning (f_"vcenter: could not read session cookie from the vCenter Server, conversion may consume all sessions on the server and fail part way through"); -- None -- ) -- else -- Some !session_cookie -- ) -+type remote_resource = { -+ https_url : string; -+ qemu_uri : string; -+ session_cookie : string option; -+ sslverify : bool; -+} - - let source_re = Str.regexp "^\\[\\(.*\\)\\] \\(.*\\)\\.vmdk$" - --let map_source_to_https dcPath uri server path = -- if not (Str.string_match source_re path 0) then -- (path, true) -- else ( -- let datastore = Str.matched_group 1 path -- and path = Str.matched_group 2 path in -- -- let port = -- match uri.uri_port with -- | 443 -> "" -- | n when n >= 1 -> ":" ^ string_of_int n -- | _ -> "" in -- -- (* XXX Old virt-v2v could also handle snapshots, ie: -- * "[datastore1] Fedora 20/Fedora 20-NNNNNN.vmdk" -- * XXX Need to handle templates. The file is called "-delta.vmdk" in -- * place of "-flat.vmdk". -- *) -- let url = -- sprintf -- "https://%s%s/folder/%s-flat.vmdk?dcPath=%s&dsName=%s" -- server port -- (uri_quote path) (uri_quote dcPath) (uri_quote datastore) in -- -- (* If no_verify=1 was passed in the libvirt URI, then we have to -- * turn off certificate verification here too. -- *) -- let sslverify = -- match uri.uri_query_raw with -- | None -> true -- | Some query -> -- (* XXX only works if the query string is not URI-quoted *) -- String.find query "no_verify=1" = -1 in -- -- (url, sslverify) -- ) -- --let map_source_to_uri readahead dcPath password uri scheme server path = -- let url, sslverify = map_source_to_https dcPath uri server path in -- -- (* Now we have to query the server to get the session cookie. *) -- let session_cookie = get_session_cookie password scheme uri sslverify url in -- -- (* Construct the JSON parameters. *) -- let json_params = [ -- "file.driver", JSON.String "https"; -- "file.url", JSON.String url; -- (* https://bugzilla.redhat.com/show_bug.cgi?id=1146007#c10 *) -- "file.timeout", JSON.Int 2000; -- ] in -- -- let json_params = -- match readahead with -- | None -> json_params -- | Some readahead -> -- ("file.readahead", JSON.Int readahead) :: json_params in -- -- let json_params = -- if sslverify then json_params -- else ("file.sslverify", JSON.String "off") :: json_params in -- -- let json_params = -- match session_cookie with -- | None -> json_params -- | Some cookie -> ("file.cookie", JSON.String cookie) :: json_params in -- -- debug "vcenter: json parameters: %s" (JSON.string_of_doc json_params); -- -- (* Turn the JSON parameters into a 'json:' protocol string. -- * Note this requires qemu-img >= 2.1.0. -+let rec map_source ?readahead ?password dcPath uri scheme server path = -+ (* If no_verify=1 was passed in the libvirt URI, then we have to -+ * turn off certificate verification here too. - *) -- let qemu_uri = "json: " ^ JSON.string_of_doc json_params in -+ let sslverify = -+ match uri.uri_query_raw with -+ | None -> true -+ | Some query -> -+ (* XXX only works if the query string is not URI-quoted *) -+ String.find query "no_verify=1" = -1 in - -- qemu_uri -+ let https_url = -+ if not (Str.string_match source_re path 0) then -+ path -+ else ( -+ let datastore = Str.matched_group 1 path -+ and path = Str.matched_group 2 path in -+ -+ let port = -+ match uri.uri_port with -+ | 443 -> "" -+ | n when n >= 1 -> ":" ^ string_of_int n -+ | _ -> "" in -+ -+ (* XXX Old virt-v2v could also handle snapshots, ie: -+ * "[datastore1] Fedora 20/Fedora 20-NNNNNN.vmdk" -+ * XXX Need to handle templates. The file is called "-delta.vmdk" in -+ * place of "-flat.vmdk". -+ *) -+ sprintf "https://%s%s/folder/%s-flat.vmdk?dcPath=%s&dsName=%s" -+ server port -+ (uri_quote path) (uri_quote dcPath) (uri_quote datastore) -+ ) in -+ -+ let session_cookie = -+ get_session_cookie password scheme uri sslverify https_url in -+ -+ let qemu_uri = -+ (* Construct the JSON parameters for the qemu URI. *) -+ let json_params = [ -+ "file.driver", JSON.String "https"; -+ "file.url", JSON.String https_url; -+ (* https://bugzilla.redhat.com/show_bug.cgi?id=1146007#c10 *) -+ "file.timeout", JSON.Int 2000; -+ ] in -+ -+ let json_params = -+ match readahead with -+ | None -> json_params -+ | Some readahead -> -+ ("file.readahead", JSON.Int readahead) :: json_params in -+ -+ let json_params = -+ if sslverify then json_params -+ else ("file.sslverify", JSON.String "off") :: json_params in -+ -+ let json_params = -+ match session_cookie with -+ | None -> json_params -+ | Some cookie -> ("file.cookie", JSON.String cookie) :: json_params in -+ -+ debug "vcenter: json parameters: %s" (JSON.string_of_doc json_params); -+ -+ (* Turn the JSON parameters into a 'json:' protocol string. -+ * Note this requires qemu-img >= 2.1.0. -+ *) -+ let qemu_uri = "json: " ^ JSON.string_of_doc json_params in -+ -+ qemu_uri in -+ -+ (* Return the struct. *) -+ { https_url = https_url; -+ qemu_uri = qemu_uri; -+ session_cookie = session_cookie; -+ sslverify = sslverify } -+ -+and get_session_cookie password scheme uri sslverify https_url = -+ let curl_args = ref [ -+ "head", None; -+ "silent", None; -+ "url", Some https_url; -+ ] in -+ (match uri.uri_user, password with -+ | None, None -> () -+ | None, Some _ -> -+ warning (f_"--password-file parameter ignored because 'user@' was not given in the URL") -+ | Some user, None -> -+ push_back curl_args ("user", Some user) -+ | Some user, Some password -> -+ push_back curl_args ("user", Some (user ^ ":" ^ password)) -+ ); -+ if not sslverify then push_back curl_args ("insecure", None); -+ -+ let curl_h = Curl.create !curl_args in -+ let lines = Curl.run curl_h in -+ -+ let dump_response chan = -+ Curl.print chan curl_h; -+ -+ (* Dump out the output of the command. *) -+ List.iter (fun x -> fprintf chan "%s\n" x) lines; -+ flush chan -+ in -+ -+ if verbose () then dump_response stderr; -+ -+ (* Look for the last HTTP/x.y NNN status code in the output. *) -+ let status = ref "" in -+ List.iter ( -+ fun line -> -+ let len = String.length line in -+ if len >= 12 && String.sub line 0 5 = "HTTP/" then -+ status := String.sub line 9 3 -+ ) lines; -+ let status = !status in -+ if status = "" then ( -+ dump_response stderr; -+ error (f_"vcenter: no status code in output of ‘curl’ command. Is ‘curl’ installed?") -+ ); -+ -+ if status = "401" then ( -+ dump_response stderr; -+ if uri.uri_user <> None then -+ error (f_"vcenter: incorrect username or password") -+ else -+ error (f_"vcenter: incorrect username or password. You might need to specify the username in the URI like this: %s://USERNAME@[etc]") -+ scheme -+ ); -+ -+ if status = "404" then ( -+ dump_response stderr; -+ error (f_"vcenter: URL not found: %s") https_url -+ ); -+ -+ if status <> "200" then ( -+ dump_response stderr; -+ error (f_"vcenter: invalid response from server") -+ ); -+ -+ (* Get the cookie. *) -+ let rec loop = function -+ | [] -> -+ dump_response stderr; -+ warning (f_"vcenter: could not read session cookie from the vCenter Server, conversion may consume all sessions on the server and fail part way through"); -+ None -+ | line :: lines -> -+ let len = String.length line in -+ if len >= 12 && String.sub line 0 12 = "Set-Cookie: " then ( -+ let line = String.sub line 12 (len-12) in -+ let cookie, _ = String.split ";" line in -+ Some cookie -+ ) -+ else -+ loop lines -+ in -+ loop lines -diff --git a/v2v/vCenter.mli b/v2v/vCenter.mli -index 55d70b486..03749966f 100644 ---- a/v2v/vCenter.mli -+++ b/v2v/vCenter.mli -@@ -18,35 +18,51 @@ - - (** Functions for dealing with VMware vCenter. *) - --val get_session_cookie : string option -> string -> Xml.uri -> bool -> string -> string option --(** [get_session_cookie password scheme uri sslverify url] -- contacts the vCenter server, logs in, and gets the session cookie, -- which can later be passed back to the server instead of having to -- log in each time (this is also more efficient since it avoids -- vCenter running out of authentication sessions). -+type remote_resource = { -+ https_url : string; -+ (** The full URL of the remote disk as an https link on the vCenter -+ server. It will have the general form -+ [https://vcenter/folder/.../guest-flat.vmdk?dcPath=...&...] *) - -- Returns [None] if the session cookie could not be read (but -- authentication was successful). You can proceed without the -- session cookie in this case, but there is an unavoidable -- danger of running out of authentication sessions. If the -- session cookie could not be read, this function prints a -- warning. -+ qemu_uri : string; -+ (** The remote disk as a QEMU URI. This opaque blob (usually a -+ [json:] URL) can be passed to [qemu] or [qemu-img] as a backing -+ file. *) - -- The session cookie is memoized so you can call this function as -- often as you want, and only a single log in is made. *) -+ session_cookie : string option; -+ (** When creating the URLs above, the module contacts the vCenter -+ server, logs in, and gets the session cookie, which can later -+ be passed back to the server instead of having to log in each -+ time (this is also more efficient since it avoids vCenter -+ running out of authentication sessions). - --val map_source_to_uri : int option -> string -> string option -> Xml.uri -> string -> string -> string -> string --(** [map_source_to_uri readahead dcPath password uri scheme server path] -- maps the [] string to a qemu URI. -+ This can be [None] if the session cookie could not be read (but -+ authentication was successful). You can proceed without the -+ session cookie in this case, but there is an unavoidable -+ danger of running out of authentication sessions. If the -+ session cookie could not be read, this function prints a -+ warning. - -- The [path] will be something like: -+ If authentication {i failed} then the {!map_source} function -+ would exit with an error, so [None] does not indicate auth -+ failure. *) - -+ sslverify : bool; -+ (** This is true except when the libvirt URI had [?no_verify=1] in -+ the parameters. *) -+} -+(** The "remote resource" is the structure returned by the {!map_source} -+ function. *) -+ -+val map_source : ?readahead:int -> ?password:string -> string -> Xml.uri -> string -> string -> string -> remote_resource -+(** [map_source ?readahead ?password dcPath uri scheme server path] -+ maps the [] string to a {!remote_resource} -+ structure containing both an [https://] URL and a qemu URI, -+ both pointing the guest disk. -+ -+ The input [path] comes from libvirt and will be something like: - ["[datastore1] Fedora 20/Fedora 20.vmdk"] -+ (including those literal spaces in the string). - -- including those literal spaces in the string. *) -- --val map_source_to_https : string -> Xml.uri -> string -> string -> string * bool --(** [map_source_to_https dcPath uri server path] is the same as -- {!map_source_to_uri} but it produces a regular [https://...] URL. -- The returned boolean is whether TLS certificate verification -- should be done. *) -+ This checks that the disk exists and that authentication is -+ correct, otherwise it will fail. *) --- -2.14.3 - diff --git a/SOURCES/0050-New-API-inspect_get_osinfo.patch b/SOURCES/0050-New-API-inspect_get_osinfo.patch new file mode 100644 index 0000000..7bac8ad --- /dev/null +++ b/SOURCES/0050-New-API-inspect_get_osinfo.patch @@ -0,0 +1,136 @@ +From 5fb23eb5171b6b93adf513ea9025199e2a21c076 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Wed, 21 Feb 2018 17:33:28 +0100 +Subject: [PATCH] New API: inspect_get_osinfo + +Try to guess the possible osinfo-db short ID for the specified OS. + +Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1544842 + +(cherry picked from commit 286b88891c2288fb7f64c9538296599ece04bcb1) +--- + generator/actions_inspection.ml | 14 ++++++ + lib/Makefile.am | 1 + + lib/inspect-osinfo.c | 75 +++++++++++++++++++++++++++++++++ + 3 files changed, 90 insertions(+) + create mode 100644 lib/inspect-osinfo.c + +diff --git a/generator/actions_inspection.ml b/generator/actions_inspection.ml +index 0ac282435..ff5083114 100644 +--- a/generator/actions_inspection.ml ++++ b/generator/actions_inspection.ml +@@ -770,4 +770,18 @@ advice before using trademarks in applications. + + =back" }; + ++ { defaults with ++ name = "inspect_get_osinfo"; added = (1, 39, 1); ++ style = RString (RPlainString, "id"), [String (Mountable, "root")], []; ++ shortdesc = "get a possible osinfo short ID corresponding to this operating system"; ++ longdesc = "\ ++This function returns a possible short ID for libosinfo corresponding ++to the guest. ++ ++I The returned ID is only a guess by libguestfs, and nothing ++ensures that it actually exists in osinfo-db. ++ ++If no ID could not be determined, then the string C is ++returned." }; ++ + ] +diff --git a/lib/Makefile.am b/lib/Makefile.am +index 91c4e0a2e..bd753d786 100644 +--- a/lib/Makefile.am ++++ b/lib/Makefile.am +@@ -95,6 +95,7 @@ libguestfs_la_SOURCES = \ + info.c \ + inspect-apps.c \ + inspect-icon.c \ ++ inspect-osinfo.c \ + journal.c \ + launch.c \ + launch-direct.c \ +diff --git a/lib/inspect-osinfo.c b/lib/inspect-osinfo.c +new file mode 100644 +index 000000000..816d317f1 +--- /dev/null ++++ b/lib/inspect-osinfo.c +@@ -0,0 +1,75 @@ ++/* libguestfs ++ * Copyright (C) 2018 Red Hat Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library 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 ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include ++ ++#include "guestfs.h" ++#include "guestfs-internal.h" ++#include "guestfs-internal-actions.h" ++ ++char * ++guestfs_impl_inspect_get_osinfo (guestfs_h *g, const char *root) ++{ ++ CLEANUP_FREE char *type = NULL; ++ CLEANUP_FREE char *distro = NULL; ++ int major, minor; ++ ++ type = guestfs_inspect_get_type (g, root); ++ if (!type) ++ return NULL; ++ distro = guestfs_inspect_get_distro (g, root); ++ if (!distro) ++ return NULL; ++ major = guestfs_inspect_get_major_version (g, root); ++ minor = guestfs_inspect_get_minor_version (g, root); ++ ++ if (STREQ (type, "linux")) { ++ if (STREQ (distro, "centos")) { ++ if (major >= 7) ++ return safe_asprintf (g, "%s%d.0", distro, major); ++ else if (major == 6) ++ return safe_asprintf (g, "%s%d.%d", distro, major, minor); ++ } ++ else if (STREQ (distro, "debian")) { ++ if (major >= 4) ++ return safe_asprintf (g, "%s%d", distro, major); ++ } ++ else if (STREQ (distro, "fedora") || STREQ (distro, "mageia")) ++ return safe_asprintf (g, "%s%d", distro, major); ++ else if (STREQ (distro, "sles")) { ++ if (minor == 0) ++ return safe_asprintf (g, "%s%d", distro, major); ++ else ++ return safe_asprintf (g, "%s%dsp%d", distro, major, minor); ++ } ++ else if (STREQ (distro, "ubuntu")) ++ return safe_asprintf (g, "%s%d.%02d", distro, major, minor); ++ ++ if (major > 0 || minor > 0) ++ return safe_asprintf (g, "%s%d.%d", distro, major, minor); ++ } ++ else if (STREQ (type, "freebsd") || STREQ (type, "netbsd") || STREQ (type, "openbsd")) ++ return safe_asprintf (g, "%s%d.%d", distro, major, minor); ++ else if (STREQ (type, "dos")) { ++ if (STREQ (distro, "msdos")) ++ return safe_strdup (g, "msdos6.22"); ++ } ++ ++ /* No ID could be guessed, return "unknown". */ ++ return safe_strdup (g, "unknown"); ++} +-- +2.17.1 + diff --git a/SOURCES/0050-v2v-vCenter-Split-up-get_session_cookie-function.patch b/SOURCES/0050-v2v-vCenter-Split-up-get_session_cookie-function.patch deleted file mode 100644 index 9267e21..0000000 --- a/SOURCES/0050-v2v-vCenter-Split-up-get_session_cookie-function.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 4965f1eae5bb56c47c7acf295822afb1108f624e Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 13 Oct 2017 17:01:04 +0100 -Subject: [PATCH] v2v: vCenter: Split up get_session_cookie function. - -This is a small refactoring where we split get_session_cookie into a -function to fetch the URL and a function to parse the cookie. - -(cherry picked from commit 2052fb7d1f9a173d71ab88358281def0c6b03f06) ---- - v2v/vCenter.ml | 106 ++++++++++++++++++++++++++++++++------------------------- - 1 file changed, 59 insertions(+), 47 deletions(-) - -diff --git a/v2v/vCenter.ml b/v2v/vCenter.ml -index 341a40b25..7fc0811a4 100644 ---- a/v2v/vCenter.ml -+++ b/v2v/vCenter.ml -@@ -124,6 +124,45 @@ let rec map_source ?readahead ?password dcPath uri scheme server path = - sslverify = sslverify } - - and get_session_cookie password scheme uri sslverify https_url = -+ let status, headers, dump_response = -+ fetch_headers_from_url password scheme uri sslverify https_url in -+ -+ if status = "401" then ( -+ dump_response stderr; -+ if uri.uri_user <> None then -+ error (f_"vcenter: incorrect username or password") -+ else -+ error (f_"vcenter: incorrect username or password. You might need to specify the username in the URI like this: %s://USERNAME@[etc]") -+ scheme -+ ); -+ -+ if status = "404" then ( -+ dump_response stderr; -+ error (f_"vcenter: URL not found: %s") https_url -+ ); -+ -+ if status <> "200" then ( -+ dump_response stderr; -+ error (f_"vcenter: invalid response from server") -+ ); -+ -+ (* Get the cookie. *) -+ let rec loop = function -+ | [] -> -+ dump_response stderr; -+ warning (f_"vcenter: could not read session cookie from the vCenter Server, conversion may consume all sessions on the server and fail part way through"); -+ None -+ | ("set-cookie", cookie) :: _ -> -+ let cookie, _ = String.split ";" cookie in -+ Some cookie -+ -+ | _ :: headers -> -+ loop headers -+ in -+ loop headers -+ -+(* Fetch the status and reply headers from a URL. *) -+and fetch_headers_from_url password scheme uri sslverify https_url = - let curl_args = ref [ - "head", None; - "silent", None; -@@ -153,53 +192,26 @@ and get_session_cookie password scheme uri sslverify https_url = - - if verbose () then dump_response stderr; - -+ let statuses, headers = -+ List.partition ( -+ fun line -> -+ let len = String.length line in -+ len >= 12 && String.sub line 0 5 = "HTTP/" -+ ) lines in -+ - (* Look for the last HTTP/x.y NNN status code in the output. *) -- let status = ref "" in -- List.iter ( -- fun line -> -- let len = String.length line in -- if len >= 12 && String.sub line 0 5 = "HTTP/" then -- status := String.sub line 9 3 -- ) lines; -- let status = !status in -- if status = "" then ( -- dump_response stderr; -- error (f_"vcenter: no status code in output of ‘curl’ command. Is ‘curl’ installed?") -- ); -- -- if status = "401" then ( -- dump_response stderr; -- if uri.uri_user <> None then -- error (f_"vcenter: incorrect username or password") -- else -- error (f_"vcenter: incorrect username or password. You might need to specify the username in the URI like this: %s://USERNAME@[etc]") -- scheme -- ); -- -- if status = "404" then ( -- dump_response stderr; -- error (f_"vcenter: URL not found: %s") https_url -- ); -- -- if status <> "200" then ( -- dump_response stderr; -- error (f_"vcenter: invalid response from server") -- ); -- -- (* Get the cookie. *) -- let rec loop = function -+ let status = -+ match statuses with - | [] -> - dump_response stderr; -- warning (f_"vcenter: could not read session cookie from the vCenter Server, conversion may consume all sessions on the server and fail part way through"); -- None -- | line :: lines -> -- let len = String.length line in -- if len >= 12 && String.sub line 0 12 = "Set-Cookie: " then ( -- let line = String.sub line 12 (len-12) in -- let cookie, _ = String.split ";" line in -- Some cookie -- ) -- else -- loop lines -- in -- loop lines -+ 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 -+ -+ let headers = -+ List.map ( -+ fun header -> -+ let h, c = String.split ": " header in -+ String.lowercase_ascii h, c -+ ) headers in -+ -+ status, headers, dump_response --- -2.14.3 - diff --git a/SOURCES/0051-inspector-show-the-per-OS-osinfo-guess-RHBZ-1544842.patch b/SOURCES/0051-inspector-show-the-per-OS-osinfo-guess-RHBZ-1544842.patch new file mode 100644 index 0000000..c0f6acd --- /dev/null +++ b/SOURCES/0051-inspector-show-the-per-OS-osinfo-guess-RHBZ-1544842.patch @@ -0,0 +1,99 @@ +From 6357a82435d328b1da23ab4995f26836427747a4 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Wed, 21 Feb 2018 17:37:30 +0100 +Subject: [PATCH] inspector: show the per-OS osinfo guess (RHBZ#1544842) + +Output also the osinfo guess for each OS in the generated XML output; +adapt the RNG schema, and the test data to it. + +(cherry picked from commit 2f8ec91fc1f3e81c8fb81d45849bc7462ee13642) +--- + inspector/expected-coreos.img.xml | 1 + + inspector/expected-debian.img.xml | 1 + + inspector/expected-fedora.img.xml | 1 + + inspector/expected-ubuntu.img.xml | 1 + + inspector/inspector.c | 7 +++++++ + inspector/virt-inspector.rng | 1 + + 6 files changed, 12 insertions(+) + +diff --git a/inspector/expected-coreos.img.xml b/inspector/expected-coreos.img.xml +index e4a5d1134..0cdfba6e6 100644 +--- a/inspector/expected-coreos.img.xml ++++ b/inspector/expected-coreos.img.xml +@@ -8,6 +8,7 @@ + 899 + 13 + coreos.invalid ++ coreos899.13 + + / + /usr +diff --git a/inspector/expected-debian.img.xml b/inspector/expected-debian.img.xml +index 37ecfa049..6583dc262 100644 +--- a/inspector/expected-debian.img.xml ++++ b/inspector/expected-debian.img.xml +@@ -11,6 +11,7 @@ + deb + apt + debian.invalid ++ debian5 + + / + /usr +diff --git a/inspector/expected-fedora.img.xml b/inspector/expected-fedora.img.xml +index 8d40e8cb7..df6060a73 100644 +--- a/inspector/expected-fedora.img.xml ++++ b/inspector/expected-fedora.img.xml +@@ -11,6 +11,7 @@ + rpm + yum + fedora.invalid ++ fedora14 + + / + /boot +diff --git a/inspector/expected-ubuntu.img.xml b/inspector/expected-ubuntu.img.xml +index c19c14cd5..4ebcd76d6 100644 +--- a/inspector/expected-ubuntu.img.xml ++++ b/inspector/expected-ubuntu.img.xml +@@ -11,6 +11,7 @@ + deb + apt + ubuntu.invalid ++ ubuntu10.10 + + / + /boot +diff --git a/inspector/inspector.c b/inspector/inspector.c +index d608b1b63..5075a8f04 100644 +--- a/inspector/inspector.c ++++ b/inspector/inspector.c +@@ -443,6 +443,13 @@ output_root (xmlTextWriterPtr xo, char *root) + BAD_CAST str)); + free (str); + ++ str = guestfs_inspect_get_osinfo (g, root); ++ if (!str) exit (EXIT_FAILURE); ++ if (STRNEQ (str, "unknown")) ++ XMLERROR (-1, ++ xmlTextWriterWriteElement (xo, BAD_CAST "osinfo", BAD_CAST str)); ++ free (str); ++ + output_mountpoints (xo, root); + + output_filesystems (xo, root); +diff --git a/inspector/virt-inspector.rng b/inspector/virt-inspector.rng +index 314785202..1e3a58af8 100644 +--- a/inspector/virt-inspector.rng ++++ b/inspector/virt-inspector.rng +@@ -38,6 +38,7 @@ + + + ++ + + + +-- +2.17.1 + diff --git a/SOURCES/0051-v2v-vCenter-Factor-out-get_https_url-code.patch b/SOURCES/0051-v2v-vCenter-Factor-out-get_https_url-code.patch deleted file mode 100644 index 2ee10a3..0000000 --- a/SOURCES/0051-v2v-vCenter-Factor-out-get_https_url-code.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 56835fbc66a9ae540764d1628922afaaa5b2fffc Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 13 Oct 2017 17:08:23 +0100 -Subject: [PATCH] v2v: vCenter: Factor out get_https_url code. - -Pure refactoring. - -(cherry picked from commit 388a70139910ed4b03d9765e403c35bb26cbe422) ---- - v2v/vCenter.ml | 46 ++++++++++++++++++++++++---------------------- - 1 file changed, 24 insertions(+), 22 deletions(-) - -diff --git a/v2v/vCenter.ml b/v2v/vCenter.ml -index 7fc0811a4..f53affb48 100644 ---- a/v2v/vCenter.ml -+++ b/v2v/vCenter.ml -@@ -58,28 +58,7 @@ let rec map_source ?readahead ?password dcPath uri scheme server path = - (* XXX only works if the query string is not URI-quoted *) - String.find query "no_verify=1" = -1 in - -- let https_url = -- if not (Str.string_match source_re path 0) then -- path -- else ( -- let datastore = Str.matched_group 1 path -- and path = Str.matched_group 2 path in -- -- let port = -- match uri.uri_port with -- | 443 -> "" -- | n when n >= 1 -> ":" ^ string_of_int n -- | _ -> "" in -- -- (* XXX Old virt-v2v could also handle snapshots, ie: -- * "[datastore1] Fedora 20/Fedora 20-NNNNNN.vmdk" -- * XXX Need to handle templates. The file is called "-delta.vmdk" in -- * place of "-flat.vmdk". -- *) -- sprintf "https://%s%s/folder/%s-flat.vmdk?dcPath=%s&dsName=%s" -- server port -- (uri_quote path) (uri_quote dcPath) (uri_quote datastore) -- ) in -+ let https_url = get_https_url dcPath uri server path in - - let session_cookie = - get_session_cookie password scheme uri sslverify https_url in -@@ -123,6 +102,29 @@ let rec map_source ?readahead ?password dcPath uri scheme server path = - session_cookie = session_cookie; - sslverify = sslverify } - -+and get_https_url dcPath uri server path = -+ if not (Str.string_match source_re path 0) then -+ path -+ else ( -+ let datastore = Str.matched_group 1 path -+ and path = Str.matched_group 2 path in -+ -+ let port = -+ match uri.uri_port with -+ | 443 -> "" -+ | n when n >= 1 -> ":" ^ string_of_int n -+ | _ -> "" in -+ -+ (* XXX Old virt-v2v could also handle snapshots, ie: -+ * "[datastore1] Fedora 20/Fedora 20-NNNNNN.vmdk" -+ * XXX Need to handle templates. The file is called "-delta.vmdk" in -+ * place of "-flat.vmdk". -+ *) -+ sprintf "https://%s%s/folder/%s-flat.vmdk?dcPath=%s&dsName=%s" -+ server port -+ (uri_quote path) (uri_quote dcPath) (uri_quote datastore) -+ ) -+ - and get_session_cookie password scheme uri sslverify https_url = - let status, headers, dump_response = - fetch_headers_from_url password scheme uri sslverify https_url in --- -2.14.3 - diff --git a/SOURCES/0052-lib-libvirt-Convert-all-socket-parameters-to-an-abso.patch b/SOURCES/0052-lib-libvirt-Convert-all-socket-parameters-to-an-abso.patch new file mode 100644 index 0000000..5bdf29a --- /dev/null +++ b/SOURCES/0052-lib-libvirt-Convert-all-socket-parameters-to-an-abso.patch @@ -0,0 +1,48 @@ +From 1db9a763c92eae49d05e5c7a4c9c5527cced2ad0 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 14 Jun 2018 11:19:49 +0100 +Subject: [PATCH] lib: libvirt: Convert all socket parameters to an absolute + path (RHBZ#1588451). + +(cherry picked from commit 70bc83f893e6e0daf20ca7c9b7bfe875ceaed594) +--- + lib/launch-libvirt.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c +index c709c4fe2..4df26825a 100644 +--- a/lib/launch-libvirt.c ++++ b/lib/launch-libvirt.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1706,8 +1707,20 @@ construct_libvirt_xml_disk_source_hosts (guestfs_h *g, + } + + case drive_transport_unix: { ++ /* libvirt requires sockets to be specified as an absolute path ++ * (RHBZ#1588451). ++ */ ++ const char *socket = src->servers[i].u.socket; ++ CLEANUP_FREE char *abs_socket = realpath (socket, NULL); ++ ++ if (abs_socket == NULL) { ++ perrorf (g, _("realpath: could not convert ‘%s’ to absolute path"), ++ socket); ++ return -1; ++ } ++ + attribute ("transport", "unix"); +- attribute ("socket", src->servers[i].u.socket); ++ attribute ("socket", abs_socket); + break; + } + } +-- +2.17.1 + diff --git a/SOURCES/0052-v2v-vCenter-Handle-disks-with-snapshots-RHBZ-1172425.patch b/SOURCES/0052-v2v-vCenter-Handle-disks-with-snapshots-RHBZ-1172425.patch deleted file mode 100644 index f4b8b62..0000000 --- a/SOURCES/0052-v2v-vCenter-Handle-disks-with-snapshots-RHBZ-1172425.patch +++ /dev/null @@ -1,71 +0,0 @@ -From bdeb7926bea75bb62a5165eb94ee4084d678f7fe Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 13 Oct 2017 17:14:07 +0100 -Subject: [PATCH] v2v: vCenter: Handle disks with snapshots (RHBZ#1172425). - -This implements a missing feature from old virt-v2v, namely being able -to cope with a guest with snapshots. Note this only converts the top -(latest) snapshot. As in old virt-v2v it does NOT convert the whole -chain of snapshots. - -(cherry picked from commit c380920034612290eef4476ab4e731c492c68869) ---- - v2v/vCenter.ml | 28 ++++++++++++++++++++++++---- - 1 file changed, 24 insertions(+), 4 deletions(-) - -diff --git a/v2v/vCenter.ml b/v2v/vCenter.ml -index f53affb48..a1aaf7b7e 100644 ---- a/v2v/vCenter.ml -+++ b/v2v/vCenter.ml -@@ -46,6 +46,7 @@ type remote_resource = { - } - - let source_re = Str.regexp "^\\[\\(.*\\)\\] \\(.*\\)\\.vmdk$" -+let snapshot_re = Str.regexp "^\\(.*\\)-[0-9][0-9][0-9][0-9][0-9][0-9]\\(\\.vmdk\\)$" - - let rec map_source ?readahead ?password dcPath uri scheme server path = - (* If no_verify=1 was passed in the libvirt URI, then we have to -@@ -58,7 +59,28 @@ let rec map_source ?readahead ?password dcPath uri scheme server path = - (* XXX only works if the query string is not URI-quoted *) - String.find query "no_verify=1" = -1 in - -- let https_url = get_https_url dcPath uri server path in -+ let https_url = -+ let https_url = get_https_url dcPath uri server path in -+ (* Check the URL exists. *) -+ let status, _, _ = -+ fetch_headers_from_url password scheme uri sslverify https_url in -+ (* If a disk is actually a snapshot image it will have '-00000n' -+ * appended to its name, e.g.: -+ * [yellow:storage1] RHEL4-X/RHEL4-X-000003.vmdk -+ * The flat storage is still called RHEL4-X-flat, however. If we got -+ * a 404 and the vmdk name looks like it might be a snapshot, try -+ * again without the snapshot suffix. -+ *) -+ if status = "404" && Str.string_match snapshot_re path 0 then ( -+ let path = Str.matched_group 1 path ^ Str.matched_group 2 path in -+ get_https_url dcPath uri server path -+ ) -+ else -+ (* Note that other non-200 status errors will be handled -+ * in get_session_cookie below, so we don't have to worry -+ * about them here. -+ *) -+ https_url in - - let session_cookie = - get_session_cookie password scheme uri sslverify https_url in -@@ -115,9 +137,7 @@ and get_https_url dcPath uri server path = - | n when n >= 1 -> ":" ^ string_of_int n - | _ -> "" in - -- (* XXX Old virt-v2v could also handle snapshots, ie: -- * "[datastore1] Fedora 20/Fedora 20-NNNNNN.vmdk" -- * XXX Need to handle templates. The file is called "-delta.vmdk" in -+ (* XXX Need to handle templates. The file is called "-delta.vmdk" in - * place of "-flat.vmdk". - *) - sprintf "https://%s%s/folder/%s-flat.vmdk?dcPath=%s&dsName=%s" --- -2.14.3 - diff --git a/SOURCES/0053-generator-Deprecate-direct-mode-guestfs_set_direct-g.patch b/SOURCES/0053-generator-Deprecate-direct-mode-guestfs_set_direct-g.patch deleted file mode 100644 index 09a4f80..0000000 --- a/SOURCES/0053-generator-Deprecate-direct-mode-guestfs_set_direct-g.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 9dcd0326952b2d0ad6f95f51bd9e0f5487603e30 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 2 Mar 2017 12:42:46 +0000 -Subject: [PATCH] generator: Deprecate direct mode (guestfs_set_direct, - guestfs_get_direct). - -(cherry picked from commit 26948d5cb17391a32856b18b8a5d6ae58a179507) ---- - generator/actions_properties.ml | 28 ---------------------------- - generator/actions_properties_deprecated.ml | 30 ++++++++++++++++++++++++++++++ - rescue/rescue.c | 3 +++ - test-tool/test-tool.c | 1 - - 4 files changed, 33 insertions(+), 29 deletions(-) - -diff --git a/generator/actions_properties.ml b/generator/actions_properties.ml -index 8f6455b81..87144b14f 100644 ---- a/generator/actions_properties.ml -+++ b/generator/actions_properties.ml -@@ -259,34 +259,6 @@ C)." }; - longdesc = "\ - Return the command trace flag." }; - -- { defaults with -- name = "set_direct"; added = (1, 0, 72); -- style = RErr, [Bool "direct"], []; -- fish_alias = ["direct"]; config_only = true; -- blocking = false; -- shortdesc = "enable or disable direct appliance mode"; -- longdesc = "\ --If the direct appliance mode flag is enabled, then stdin and --stdout are passed directly through to the appliance once it --is launched. -- --One consequence of this is that log messages aren't caught --by the library and handled by C, --but go straight to stdout. -- --You probably don't want to use this unless you know what you --are doing. -- --The default is disabled." }; -- -- { defaults with -- name = "get_direct"; added = (1, 0, 72); -- style = RBool "direct", [], []; -- blocking = false; -- shortdesc = "get direct appliance mode flag"; -- longdesc = "\ --Return the direct appliance mode flag." }; -- - { defaults with - name = "set_recovery_proc"; added = (1, 0, 77); - style = RErr, [Bool "recoveryproc"], []; -diff --git a/generator/actions_properties_deprecated.ml b/generator/actions_properties_deprecated.ml -index def17b926..53277822e 100644 ---- a/generator/actions_properties_deprecated.ml -+++ b/generator/actions_properties_deprecated.ml -@@ -125,6 +125,36 @@ Return the current backend. - - See C and L." }; - -+ { defaults with -+ name = "set_direct"; added = (1, 0, 72); -+ style = RErr, [Bool "direct"], []; -+ deprecated_by = Deprecated_no_replacement; -+ fish_alias = ["direct"]; config_only = true; -+ blocking = false; -+ shortdesc = "enable or disable direct appliance mode"; -+ longdesc = "\ -+If the direct appliance mode flag is enabled, then stdin and -+stdout are passed directly through to the appliance once it -+is launched. -+ -+One consequence of this is that log messages aren't caught -+by the library and handled by C, -+but go straight to stdout. -+ -+You probably don't want to use this unless you know what you -+are doing. -+ -+The default is disabled." }; -+ -+ { defaults with -+ name = "get_direct"; added = (1, 0, 72); -+ style = RBool "direct", [], []; -+ deprecated_by = Deprecated_no_replacement; -+ blocking = false; -+ shortdesc = "get direct appliance mode flag"; -+ longdesc = "\ -+Return the direct appliance mode flag." }; -+ - ] - - let daemon_functions = [ -diff --git a/rescue/rescue.c b/rescue/rescue.c -index 45967b2ad..b692e5a07 100644 ---- a/rescue/rescue.c -+++ b/rescue/rescue.c -@@ -295,9 +295,12 @@ main (int argc, char *argv[]) - usage (EXIT_FAILURE); - } - -+#pragma GCC diagnostic push -+#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - /* Setting "direct mode" is required for the rescue appliance. */ - if (guestfs_set_direct (g, 1) == -1) - exit (EXIT_FAILURE); -+#pragma GCC diagnostic pop - - { - /* The libvirt backend doesn't support direct mode. As a temporary -diff --git a/test-tool/test-tool.c b/test-tool/test-tool.c -index 20e2a32fa..2ae266d7d 100644 ---- a/test-tool/test-tool.c -+++ b/test-tool/test-tool.c -@@ -224,7 +224,6 @@ main (int argc, char *argv[]) - p = guestfs_get_cachedir (g); - printf ("guestfs_get_cachedir: %s\n", p ? : "(null)"); - free (p); -- printf ("guestfs_get_direct: %d\n", guestfs_get_direct (g)); - p = guestfs_get_hv (g); - printf ("guestfs_get_hv: %s\n", p); - free (p); --- -2.14.3 - diff --git a/SOURCES/0053-v2v-o-rhv-upload-Optimize-http-request-sending.patch b/SOURCES/0053-v2v-o-rhv-upload-Optimize-http-request-sending.patch new file mode 100644 index 0000000..af251f6 --- /dev/null +++ b/SOURCES/0053-v2v-o-rhv-upload-Optimize-http-request-sending.patch @@ -0,0 +1,90 @@ +From dc6afe583853bc2e18a689aa06685e69d65ede84 Mon Sep 17 00:00:00 2001 +From: Nir Soffer +Date: Thu, 14 Jun 2018 21:16:01 +0300 +Subject: [PATCH] v2v: -o rhv-upload: Optimize http request sending + +When sending request with small or no payload, it is simpler and +possibly more efficient to use the high level HTTPSConnection.request(), +instead of the lower level APIs. + +The only reason to use the lower level APIs is to avoid copying the +payload, or on python 2, to use a bigger buffer size when streaming a +file-like object. + +(cherry picked from commit 77a412c0a1cd0e303a072fc5088c8f3bfed36583) +--- + v2v/rhv-upload-plugin.py | 35 ++++++++++++++++------------------- + 1 file changed, 16 insertions(+), 19 deletions(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index b4557b83c..9ad354b84 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -237,12 +237,12 @@ def pread(h, count, offset): + transfer = h['transfer'] + transfer_service = h['transfer_service'] + +- http.putrequest("GET", h['path']) ++ headers = {"Range", "bytes=%d-%d" % (offset, offset+count-1)} + # Authorization is only needed for old imageio. + if h['needs_auth']: +- http.putheader("Authorization", transfer.signed_ticket) +- http.putheader("Range", "bytes=%d-%d" % (offset, offset+count-1)) +- http.endheaders() ++ headers["Authorization"] = transfer.signed_ticket ++ ++ http.request("GET", h['path'], headers=headers) + + r = http.getresponse() + # 206 = HTTP Partial Content. +@@ -297,11 +297,10 @@ def zero(h, count, offset, may_trim): + 'size': count, + 'flush': False}).encode() + +- http.putrequest("PATCH", h['path']) +- http.putheader("Content-Type", "application/json") +- http.putheader("Content-Length", len(buf)) +- http.endheaders() +- http.send(buf) ++ headers = {"Content-Type": "application/json", ++ "Content-Length": str(len(buf))} ++ ++ http.request("PATCH", h['path'], body=buf, headers=headers) + + r = http.getresponse() + if r.status != 200: +@@ -349,11 +348,10 @@ def trim(h, count, offset): + 'size': count, + 'flush': False}).encode() + +- http.putrequest("PATCH", h['path']) +- http.putheader("Content-Type", "application/json") +- http.putheader("Content-Length", len(buf)) +- http.endheaders() +- http.send(buf) ++ headers = {"Content-Type": "application/json", ++ "Content-Length": str(len(buf))} ++ ++ http.request("PATCH", h['path'], body=buf, headers=headers) + + r = http.getresponse() + if r.status != 200: +@@ -370,11 +368,10 @@ def flush(h): + # Construct the JSON request for flushing. + buf = json.dumps({'op': "flush"}).encode() + +- http.putrequest("PATCH", h['path']) +- http.putheader("Content-Type", "application/json") +- http.putheader("Content-Length", len(buf)) +- http.endheaders() +- http.send(buf) ++ headers = {"Content-Type": "application/json", ++ "Content-Length": str(len(buf))} ++ ++ http.request("PATCH", h['path'], body=buf, headers=headers) + + r = http.getresponse() + if r.status != 200: +-- +2.17.1 + diff --git a/SOURCES/0054-New-API-internal-get-console-socket-to-support-virt-.patch b/SOURCES/0054-New-API-internal-get-console-socket-to-support-virt-.patch deleted file mode 100644 index 30eced5..0000000 --- a/SOURCES/0054-New-API-internal-get-console-socket-to-support-virt-.patch +++ /dev/null @@ -1,184 +0,0 @@ -From 78588ae92828fad9b8ea09e2edf3899466975470 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 2 Mar 2017 11:06:27 +0000 -Subject: [PATCH] New API: internal-get-console-socket to support virt-rescue. - -This API intended for use by virt-rescue only gets the file descriptor -of the console socket. - -(cherry picked from commit 84c9f98c2e09a459ced3c7e85191f2e47d149a52) ---- - generator/actions_core.ml | 11 +++++++ - generator/actions_properties_deprecated.ml | 4 +-- - lib/Makefile.am | 1 + - lib/conn-socket.c | 16 +++++++++- - lib/guestfs-internal.h | 3 ++ - lib/rescue.c | 47 ++++++++++++++++++++++++++++++ - 6 files changed, 79 insertions(+), 3 deletions(-) - create mode 100644 lib/rescue.c - -diff --git a/generator/actions_core.ml b/generator/actions_core.ml -index ee2539c09..dbacdfadf 100644 ---- a/generator/actions_core.ml -+++ b/generator/actions_core.ml -@@ -1678,6 +1678,17 @@ call it returns a simple true/false boolean result, instead - of throwing an exception if a feature is not found. For - other documentation see C." }; - -+ { defaults with -+ name = "internal_get_console_socket"; added = (1, 37, 1); -+ style = RInt "fd", [], []; -+ visibility = VInternal; -+ test_excuse = "writing to the socket may block"; -+ shortdesc = "get the appliance console socket"; -+ longdesc = "\ -+This call is used by L to write directly to -+appliance console (for passing through keystrokes). It should -+not normally be used by other libguestfs users." }; -+ - ] - - let daemon_functions = [ -diff --git a/generator/actions_properties_deprecated.ml b/generator/actions_properties_deprecated.ml -index 53277822e..f36509e75 100644 ---- a/generator/actions_properties_deprecated.ml -+++ b/generator/actions_properties_deprecated.ml -@@ -128,7 +128,7 @@ See C and L." }; - { defaults with - name = "set_direct"; added = (1, 0, 72); - style = RErr, [Bool "direct"], []; -- deprecated_by = Deprecated_no_replacement; -+ deprecated_by = Replaced_by "internal_get_console_socket"; - fish_alias = ["direct"]; config_only = true; - blocking = false; - shortdesc = "enable or disable direct appliance mode"; -@@ -149,7 +149,7 @@ The default is disabled." }; - { defaults with - name = "get_direct"; added = (1, 0, 72); - style = RBool "direct", [], []; -- deprecated_by = Deprecated_no_replacement; -+ deprecated_by = Replaced_by "internal_get_console_socket"; - blocking = false; - shortdesc = "get direct appliance mode flag"; - longdesc = "\ -diff --git a/lib/Makefile.am b/lib/Makefile.am -index 22974187f..c3e013a52 100644 ---- a/lib/Makefile.am -+++ b/lib/Makefile.am -@@ -117,6 +117,7 @@ libguestfs_la_SOURCES = \ - private-data.c \ - proto.c \ - qemu.c \ -+ rescue.c \ - stringsbuf.c \ - structs-compare.c \ - structs-copy.c \ -diff --git a/lib/conn-socket.c b/lib/conn-socket.c -index 2cd261a2b..8ecfed856 100644 ---- a/lib/conn-socket.c -+++ b/lib/conn-socket.c -@@ -1,5 +1,5 @@ - /* libguestfs -- * Copyright (C) 2013 Red Hat Inc. -+ * Copyright (C) 2013-2017 Red Hat Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public -@@ -397,6 +397,19 @@ handle_log_message (guestfs_h *g, - return 1; - } - -+static int -+get_console_sock (guestfs_h *g, struct connection *connv) -+{ -+ struct connection_socket *conn = (struct connection_socket *) connv; -+ -+ if (conn->console_sock == -1) { -+ error (g, _("console socket not connected")); -+ return -1; -+ } -+ -+ return conn->console_sock; -+} -+ - static void - free_conn_socket (guestfs_h *g, struct connection *connv) - { -@@ -418,6 +431,7 @@ static struct connection_ops ops = { - .read_data = read_data, - .write_data = write_data, - .can_read_data = can_read_data, -+ .get_console_sock = get_console_sock, - }; - - /** -diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h -index d962aacd4..3bae02b8a 100644 ---- a/lib/guestfs-internal.h -+++ b/lib/guestfs-internal.h -@@ -369,6 +369,9 @@ struct connection_ops { - * Returns: 1 = yes, 0 = no, -1 = error - */ - int (*can_read_data) (guestfs_h *g, struct connection *); -+ -+ /* Get the console socket (to support virt-rescue). */ -+ int (*get_console_sock) (guestfs_h *g, struct connection *); - }; - - /** -diff --git a/lib/rescue.c b/lib/rescue.c -new file mode 100644 -index 000000000..ae7811a31 ---- /dev/null -+++ b/lib/rescue.c -@@ -0,0 +1,47 @@ -+/* libguestfs -+ * Copyright (C) 2017 Red Hat Inc. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library 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 -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/** -+ * Support for virt-rescue(1). -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "guestfs.h" -+#include "guestfs-internal.h" -+#include "guestfs-internal-actions.h" -+ -+int -+guestfs_impl_internal_get_console_socket (guestfs_h *g) -+{ -+ if (!g->conn) { -+ error (g, _("no console socket, the handle must be launched")); -+ return -1; -+ } -+ -+ if (!g->conn->ops->get_console_sock) -+ NOT_SUPPORTED (g, -1, -+ _("connection class does not support getting the console socket")); -+ -+ return g->conn->ops->get_console_sock (g, g->conn); -+} --- -2.14.3 - diff --git a/SOURCES/0054-v2v-o-rhv-upload-Log-full-imageio-response-on-failur.patch b/SOURCES/0054-v2v-o-rhv-upload-Log-full-imageio-response-on-failur.patch new file mode 100644 index 0000000..dfa8aa6 --- /dev/null +++ b/SOURCES/0054-v2v-o-rhv-upload-Log-full-imageio-response-on-failur.patch @@ -0,0 +1,153 @@ +From ed2835440ba7d1a4bc4f9aeb92a14c644522bbfd Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 5 Jun 2018 13:27:43 +0100 +Subject: [PATCH] v2v: -o rhv-upload: Log full imageio response on failure. + +Thanks: Nir Soffer +(cherry picked from commit 831a75cd11c5a87e40fccdadcb62353f6a4d5a72) +--- + v2v/rhv-upload-plugin.py | 69 ++++++++++++++++++++++++---------------- + 1 file changed, 42 insertions(+), 27 deletions(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 9ad354b84..7c5084efd 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -227,6 +227,32 @@ def can_flush(h): + def get_size(h): + return params['disk_size'] + ++# Any unexpected HTTP response status from the server will end up ++# calling this function which logs the full error, pauses the ++# transfer, sets the failed state, and raises a RuntimeError ++# exception. ++def request_failed(h, r, msg): ++ # Setting the failed flag in the handle causes the disk to be ++ # cleaned up on close. ++ h['failed'] = True ++ h['transfer_service'].pause() ++ ++ status = r.status ++ reason = r.reason ++ try: ++ body = r.read() ++ except EnvironmentError as e: ++ body = "(Unable to read response body: %s)" % e ++ ++ # Log the full error if we're verbose. ++ debug("unexpected response from imageio server:") ++ debug(msg) ++ debug("%d: %s" % (status, reason)) ++ debug(body) ++ ++ # Only a short error is included in the exception. ++ raise RuntimeError("%s: %d %s: %r", msg, status, reason, body[:200]) ++ + # For documentation see: + # https://github.com/oVirt/ovirt-imageio/blob/master/docs/random-io.md + # For examples of working code to read/write from the server, see: +@@ -247,16 +273,14 @@ def pread(h, count, offset): + r = http.getresponse() + # 206 = HTTP Partial Content. + if r.status != 206: +- h['transfer_service'].pause() +- h['failed'] = True +- raise RuntimeError("could not read sector (%d, %d): %d: %s" % +- (offset, count, r.status, r.reason)) ++ request_failed(h, r, ++ "could not read sector offset %d size %d" % ++ (offset, count)) + return r.read() + + def pwrite(h, buf, offset): + http = h['http'] + transfer = h['transfer'] +- transfer_service = h['transfer_service'] + + count = len(buf) + h['highestwrite'] = max(h['highestwrite'], offset+count) +@@ -274,15 +298,13 @@ def pwrite(h, buf, offset): + + r = http.getresponse() + if r.status != 200: +- transfer_service.pause() +- h['failed'] = True +- raise RuntimeError("could not write sector (%d, %d): %d: %s" % +- (offset, count, r.status, r.reason)) ++ request_failed(h, r, ++ "could not write sector offset %d size %d" % ++ (offset, count)) + + def zero(h, count, offset, may_trim): + http = h['http'] + transfer = h['transfer'] +- transfer_service = h['transfer_service'] + + # Unlike the trim and flush calls, there is no 'can_zero' method + # so nbdkit could call this even if the server doesn't support +@@ -304,10 +326,9 @@ def zero(h, count, offset, may_trim): + + r = http.getresponse() + if r.status != 200: +- transfer_service.pause() +- h['failed'] = True +- raise RuntimeError("could not zero sector (%d, %d): %d: %s" % +- (offset, count, r.status, r.reason)) ++ request_failed(h, r, ++ "could not zero sector offset %d size %d" % ++ (offset, count)) + + def emulate_zero(h, count, offset): + # qemu-img convert starts by trying to zero/trim the whole device. +@@ -332,15 +353,13 @@ def emulate_zero(h, count, offset): + + r = http.getresponse() + if r.status != 200: +- transfer_service.pause() +- h['failed'] = True +- raise RuntimeError("could not write zeroes (%d, %d): %d: %s" % +- (offset, count, r.status, r.reason)) ++ request_failed(h, r, ++ "could not write zeroes offset %d size %d" % ++ (offset, count)) + + def trim(h, count, offset): + http = h['http'] + transfer = h['transfer'] +- transfer_service = h['transfer_service'] + + # Construct the JSON request for trimming. + buf = json.dumps({'op': "trim", +@@ -355,15 +374,13 @@ def trim(h, count, offset): + + r = http.getresponse() + if r.status != 200: +- transfer_service.pause() +- h['failed'] = True +- raise RuntimeError("could not trim sector (%d, %d): %d: %s" % +- (offset, count, r.status, r.reason)) ++ request_failed(h, r, ++ "could not trim sector offset %d size %d" % ++ (offset, count)) + + def flush(h): + http = h['http'] + transfer = h['transfer'] +- transfer_service = h['transfer_service'] + + # Construct the JSON request for flushing. + buf = json.dumps({'op': "flush"}).encode() +@@ -375,9 +392,7 @@ def flush(h): + + r = http.getresponse() + if r.status != 200: +- transfer_service.pause() +- h['failed'] = True +- raise RuntimeError("could not flush: %d: %s" % (r.status, r.reason)) ++ request_failed(h, r, "could not flush") + + def delete_disk_on_failure(h): + disk_service = h['disk_service'] +-- +2.17.1 + diff --git a/SOURCES/0055-lib-Return-EPIPE-for-appliance-closed-the-connection.patch b/SOURCES/0055-lib-Return-EPIPE-for-appliance-closed-the-connection.patch deleted file mode 100644 index 62ca9b1..0000000 --- a/SOURCES/0055-lib-Return-EPIPE-for-appliance-closed-the-connection.patch +++ /dev/null @@ -1,39 +0,0 @@ -From ef4efa57d1c0fffe4d81ea70ad8f44d07667cfeb Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 3 Mar 2017 10:14:20 +0000 -Subject: [PATCH] lib: Return EPIPE for "appliance closed the connection - unexpectedly". - -(cherry picked from commit 8af9acd4e31e9880e14735b2242c496ee017c0d9) ---- - lib/errors.c | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - -diff --git a/lib/errors.c b/lib/errors.c -index c2af611ee..ace6a89cf 100644 ---- a/lib/errors.c -+++ b/lib/errors.c -@@ -358,12 +358,15 @@ void - guestfs_int_unexpected_close_error (guestfs_h *g) - { - if (g->verbose) -- error (g, _("appliance closed the connection unexpectedly, see earlier error messages")); -+ guestfs_int_error_errno (g, EPIPE, -+ _("appliance closed the connection unexpectedly, " -+ "see earlier error messages")); - else -- error (g, _( -- "appliance closed the connection unexpectedly.\n" -- "This usually means the libguestfs appliance crashed.\n" -- DEBUG_ADVICE)); -+ guestfs_int_error_errno (g, EPIPE, -+ _("appliance closed the connection unexpectedly.\n" -+ "This usually means the libguestfs appliance " -+ "crashed.\n" -+ DEBUG_ADVICE)); - } - - /** --- -2.14.3 - diff --git a/SOURCES/0055-v2v-Add-Disk-ovf-capacity-attribute-containing-disk-.patch b/SOURCES/0055-v2v-Add-Disk-ovf-capacity-attribute-containing-disk-.patch new file mode 100644 index 0000000..64568db --- /dev/null +++ b/SOURCES/0055-v2v-Add-Disk-ovf-capacity-attribute-containing-disk-.patch @@ -0,0 +1,37 @@ +From 4c82b8c137b9337a80f0658c1712f2318e631bef Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 18 Jun 2018 10:31:18 +0100 +Subject: [PATCH] v2v: Add attribute containing disk + virtual size (RHBZ#1592468). + +Virt-v2v transfers to newer versions of ovirt-engine can fail with: + + ovirtsdk4.Error: Fault reason is "Operation Failed". Fault detail is "failed to parse a given ovf configuration ovf error: [empty name]: cannot read '//*/disksection' with value: null". HTTP response code is 400. + +This was caused by a change made to oVirt: + + https://gerrit.ovirt.org/#/c/91902/ + +so that it now requires the attribute. + +Thanks: Arik Hadas +(cherry picked from commit 7c2afc88fd6aceb869a5e1c47a8183879ddec5fc) +--- + v2v/create_ovf.ml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml +index ac3c61b13..e0f81e0a2 100644 +--- a/v2v/create_ovf.ml ++++ b/v2v/create_ovf.ml +@@ -835,6 +835,7 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids + | OVirt -> image_uuid + | RHVExportStorageDomain -> vol_uuid); + "ovf:size", Int64.to_string size_gb; ++ "ovf:capacity", Int64.to_string ov.ov_virtual_size; + "ovf:fileRef", fileref; + "ovf:parentRef", ""; + "ovf:vm_snapshot_id", uuidgen (); +-- +2.17.1 + diff --git a/SOURCES/0056-rescue-Modify-virt-rescue-so-it-doesn-t-use-direct-m.patch b/SOURCES/0056-rescue-Modify-virt-rescue-so-it-doesn-t-use-direct-m.patch deleted file mode 100644 index 314e154..0000000 --- a/SOURCES/0056-rescue-Modify-virt-rescue-so-it-doesn-t-use-direct-m.patch +++ /dev/null @@ -1,535 +0,0 @@ -From 2d013d5d67d5896869dff4b08c0674b2d91e721f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 2 Mar 2017 13:46:48 +0000 -Subject: [PATCH] rescue: Modify virt-rescue so it doesn't use direct mode - (RHBZ#1152819, RHBZ#1171654). - -Instead of using "direct mode" (which was basically a quick hack), -virt-rescue now launches the appliance with a running daemon. - -The daemon doesn't do much -- there is still a bash shell which the -user interacts with. The daemon is there simply to provide the -initial GUESTFS_LAUNCH_FLAG message and to handle shutdown a bit more -gracefully. - -To interact with the shell, and replacing direct mode, virt-rescue now -prints out log messages (the output of the shell), and sends input -typed by the user directly to the console socket. This uses the -guestfs_internal_get_console_socket API added previously. Most of the -complexity behind this is hidden in virt-rescue. - -This fully fixes the handling of ^C (RHBZ#1152819). Also there were -earlier reports that full screen commands like 'vim' didn't work well, -(RHBZ#1171654), but in this version vim appears to work fine, albeit -only using 80x24 of the screen because of the serial console. - -(cherry picked from commit 32d60801443647b3523b9374c431fefdbf054e3c) ---- - appliance/init | 93 ++++++++-------- - rescue/Makefile.am | 1 + - rescue/rescue.c | 306 +++++++++++++++++++++++++++++++++++++++++++++-------- - 3 files changed, 313 insertions(+), 87 deletions(-) - -diff --git a/appliance/init b/appliance/init -index 735ba8946..ea763c2d3 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -160,60 +160,63 @@ if test "$guestfs_verbose" = 1 && test "$guestfs_boot_analysis" != 1; then - echo -n "uptime: "; cat /proc/uptime - fi - --if ! test "$guestfs_rescue" = 1; then -- # Run the daemon. -- cmd="guestfsd" -- eval `grep -Eo 'guestfs_channel=[^[:space:]]+' /proc/cmdline` -- if test "x$guestfs_channel" != "x"; then -+# Run the daemon. -+cmd="guestfsd" -+eval `grep -Eo 'guestfs_channel=[^[:space:]]+' /proc/cmdline` -+if test "x$guestfs_channel" != "x"; then - cmd="$cmd --channel $guestfs_channel" -- fi -- if test "$guestfs_verbose" = 1; then -+fi -+if test "$guestfs_verbose" = 1; then - cmd="$cmd --verbose" -- fi -- if test "$guestfs_network" = 1; then -+fi -+if test "$guestfs_network" = 1; then - cmd="$cmd --network" -- fi -- echo $cmd -- $cmd -+fi -+if ! test "$guestfs_rescue" = 1; then -+ echo $cmd -+ $cmd - else -- # Run virt-rescue shell. -+ # Run virt-rescue shell. - -- # Get name of the serial port, from console= passed by libguestfs. -- # XXX Consider using /proc/consoles -- guestfs_serial=$(grep -Eo 'console=[^[:space:]]+' /proc/cmdline | -- sed s/console=//) -+ # We need a daemon, even in virt-rescue. -+ $cmd & - -- # Remove LD_PRELOAD=libSegFault set above. -- unset LD_PRELOAD -+ # Get name of the serial port, from console= passed by libguestfs. -+ # XXX Consider using /proc/consoles -+ guestfs_serial=$(grep -Eo 'console=[^[:space:]]+' /proc/cmdline | -+ sed s/console=//) - -- :> $HOME/.bashrc -- grep -Eo 'TERM=[^[:space:]]+' /proc/cmdline >> $HOME/.bashrc -- echo "PS1='> '" >> $HOME/.bashrc -- echo "export TERM PS1" >> $HOME/.bashrc -+ # Remove LD_PRELOAD=libSegFault set above. -+ unset LD_PRELOAD - -- # The shell is opened by default on /dev/console, which (on Linux) -- # is not a controlling terminal, causing job control to fail. For -- # how we work around this, see: -- # https://busybox.net/FAQ.html#job_control -- run_bash_with_ctty () -- { -- setsid bash -c \ -- "exec bash /dev/$guestfs_serial 2>&1" -- } -+ :> $HOME/.bashrc -+ grep -Eo 'TERM=[^[:space:]]+' /proc/cmdline >> $HOME/.bashrc -+ echo "PS1='> '" >> $HOME/.bashrc -+ echo "export TERM PS1" >> $HOME/.bashrc - -- echo -- echo "------------------------------------------------------------" -- echo -- echo "Welcome to virt-rescue, the libguestfs rescue shell." -- echo -- echo "Note: The contents of / are the rescue appliance." -- echo "You have to mount the guest's partitions under /sysroot" -- echo "before you can examine them." -- echo -- run_bash_with_ctty -- echo -- echo "virt-rescue: Syncing the disk now before exiting ..." -- echo -+ # The shell is opened by default on /dev/console, which (on Linux) -+ # is not a controlling terminal, causing job control to fail. For -+ # how we work around this, see: -+ # https://busybox.net/FAQ.html#job_control -+ run_bash_with_ctty () -+ { -+ setsid bash -c \ -+ "exec bash /dev/$guestfs_serial 2>&1" -+ } -+ -+ echo -+ echo "------------------------------------------------------------" -+ echo -+ echo "Welcome to virt-rescue, the libguestfs rescue shell." -+ echo -+ echo "Note: The contents of / (root) are the rescue appliance." -+ echo "You have to mount the guest's partitions under /sysroot" -+ echo "before you can examine them." -+ echo -+ run_bash_with_ctty -+ echo -+ echo "virt-rescue: Syncing the disk now before exiting ..." -+ echo - fi - - sync -diff --git a/rescue/Makefile.am b/rescue/Makefile.am -index 7919aafd5..99d4b79ae 100644 ---- a/rescue/Makefile.am -+++ b/rescue/Makefile.am -@@ -30,6 +30,7 @@ virt_rescue_SOURCES = \ - - virt_rescue_CPPFLAGS = \ - -DGUESTFS_WARN_DEPRECATED=1 \ -+ -DGUESTFS_PRIVATE=1 \ - -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ - -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ - -I$(top_srcdir)/lib -I$(top_builddir)/lib \ -diff --git a/rescue/rescue.c b/rescue/rescue.c -index b692e5a07..b145dcd40 100644 ---- a/rescue/rescue.c -+++ b/rescue/rescue.c -@@ -23,21 +23,32 @@ - #include - #include - #include -+#include - #include - #include - #include -+#include -+#include -+#include - #include - #include - #include - -+#include "full-write.h" -+#include "getprogname.h" - #include "ignore-value.h" - #include "xvasprintf.h" --#include "getprogname.h" - - #include "guestfs.h" - #include "options.h" - #include "display-options.h" - -+static void log_message_callback (guestfs_h *g, void *opaque, uint64_t event, int event_handle, int flags, const char *buf, size_t buf_len, const uint64_t *array, size_t array_len); -+static void do_rescue (int sock); -+static void raw_tty (void); -+static void restore_tty (void); -+static void tstp_handler (int sig); -+static void cont_handler (int sig); - static void add_scratch_disks (int n, struct drv **drvs); - static void do_suggestion (struct drv *drvs); - -@@ -54,6 +65,9 @@ int inspector = 0; - int in_guestfish = 0; - int in_virt_rescue = 1; - -+/* Old terminal settings. */ -+static struct termios old_termios; -+ - static void __attribute__((noreturn)) - usage (int status) - { -@@ -135,6 +149,8 @@ main (int argc, char *argv[]) - int memsize = 0; - int smp = 0; - int suggest = 0; -+ char *append_full; -+ int sock; - - g = guestfs_create (); - if (g == NULL) -@@ -295,30 +311,6 @@ main (int argc, char *argv[]) - usage (EXIT_FAILURE); - } - --#pragma GCC diagnostic push --#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -- /* Setting "direct mode" is required for the rescue appliance. */ -- if (guestfs_set_direct (g, 1) == -1) -- exit (EXIT_FAILURE); --#pragma GCC diagnostic pop -- -- { -- /* The libvirt backend doesn't support direct mode. As a temporary -- * workaround, force the appliance backend, but warn about it. -- */ -- CLEANUP_FREE char *backend = guestfs_get_backend (g); -- if (backend) { -- if (STREQ (backend, "libvirt") || -- STRPREFIX (backend, "libvirt:")) { -- fprintf (stderr, _("%s: warning: virt-rescue doesn't work with the libvirt backend\n" -- "at the moment. As a workaround, forcing backend = 'direct'.\n"), -- getprogname ()); -- if (guestfs_set_backend (g, "direct") == -1) -- exit (EXIT_FAILURE); -- } -- } -- } -- - /* Set other features. */ - if (memsize > 0) - if (guestfs_set_memsize (g, memsize) == -1) -@@ -330,16 +322,15 @@ main (int argc, char *argv[]) - if (guestfs_set_smp (g, smp) == -1) - exit (EXIT_FAILURE); - -- { -- /* Kernel command line must include guestfs_rescue=1 (see -- * appliance/init) as well as other options. -- */ -- CLEANUP_FREE char *append_full = xasprintf ("guestfs_rescue=1%s%s", -- append ? " " : "", -- append ? append : ""); -- if (guestfs_set_append (g, append_full) == -1) -- exit (EXIT_FAILURE); -- } -+ /* Kernel command line must include guestfs_rescue=1 (see -+ * appliance/init) as well as other options. -+ */ -+ append_full = xasprintf ("guestfs_rescue=1%s%s", -+ append ? " " : "", -+ append ? append : ""); -+ if (guestfs_set_append (g, append_full) == -1) -+ exit (EXIT_FAILURE); -+ free (append_full); - - /* Add drives. */ - add_drives (drvs); -@@ -347,22 +338,253 @@ main (int argc, char *argv[]) - /* Free up data structures, no longer needed after this point. */ - free_drives (drvs); - -- /* Run the appliance. This won't return until the user quits the -- * appliance. -+ /* Add an event handler to print "log messages". These will be the -+ * output of the appliance console during launch and shutdown. -+ * After launch, we will read the console messages directly from the -+ * socket and they won't be passed through the event callback. - */ -- if (!verbose) -- guestfs_set_error_handler (g, NULL, NULL); -+ if (guestfs_set_event_callback (g, log_message_callback, -+ GUESTFS_EVENT_APPLIANCE, 0, NULL) == -1) -+ exit (EXIT_FAILURE); - -- /* We expect launch to fail, so ignore the return value, and don't -- * bother with explicit guestfs_shutdown either. -+ /* Run the appliance. */ -+ if (guestfs_launch (g) == -1) -+ exit (EXIT_FAILURE); -+ -+ sock = guestfs_internal_get_console_socket (g); -+ if (sock == -1) -+ exit (EXIT_FAILURE); -+ -+ /* Try to set all sockets to non-blocking. */ -+ if (fcntl (STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1) -+ perror ("could not set stdin to non-blocking"); -+ if (fcntl (STDOUT_FILENO, F_SETFL, O_NONBLOCK) == -1) -+ perror ("could not set stdout to non-blocking"); -+ if (fcntl (sock, F_SETFL, O_NONBLOCK) == -1) -+ perror ("could not set console socket to non-blocking"); -+ -+ /* Save the initial state of the tty so we always have the original -+ * state to go back to. -+ */ -+ if (tcgetattr (STDIN_FILENO, &old_termios) == -1) { -+ perror ("tcgetattr: stdin"); -+ exit (EXIT_FAILURE); -+ } -+ -+ /* Put stdin in raw mode so that we can receive ^C and other -+ * special keys. -+ */ -+ raw_tty (); -+ -+ /* Restore the tty settings when the process exits. */ -+ atexit (restore_tty); -+ -+ /* Catch tty stop and cont signals so we can cleanup. -+ * See https://www.gnu.org/software/libc/manual/html_node/Signaling-Yourself.html - */ -- ignore_value (guestfs_launch (g)); -+ signal (SIGTSTP, tstp_handler); -+ signal (SIGCONT, cont_handler); -+ -+ do_rescue (sock); -+ -+ restore_tty (); -+ -+ /* Shut down the appliance. */ -+ guestfs_push_error_handler (g, NULL, NULL); -+ if (guestfs_shutdown (g) == -1) { -+ const char *err; -+ -+ /* Ignore "appliance closed the connection unexpectedly" since -+ * this can happen if the user reboots the appliance. -+ */ -+ if (guestfs_last_errno (g) == EPIPE) -+ goto next; - -+ /* Otherwise it's a real error. */ -+ err = guestfs_last_error (g); -+ fprintf (stderr, "libguestfs: error: %s\n", err); -+ exit (EXIT_FAILURE); -+ } -+ next: -+ guestfs_pop_error_handler (g); - guestfs_close (g); - - exit (EXIT_SUCCESS); - } - -+static void -+log_message_callback (guestfs_h *g, void *opaque, uint64_t event, -+ int event_handle, int flags, -+ const char *buf, size_t buf_len, -+ const uint64_t *array, size_t array_len) -+{ -+ if (buf_len > 0) { -+ ignore_value (full_write (STDOUT_FILENO, buf, buf_len)); -+ } -+} -+ -+/* This is the main loop for virt-rescue. We read and write -+ * directly to the console socket. -+ */ -+#define BUFSIZE 4096 -+static char rbuf[BUFSIZE]; /* appliance -> local tty */ -+static char wbuf[BUFSIZE]; /* local tty -> appliance */ -+ -+static void -+do_rescue (int sock) -+{ -+ size_t rlen = 0; -+ size_t wlen = 0; -+ -+ while (sock >= 0 || rlen > 0) { -+ struct pollfd fds[3]; -+ nfds_t nfds = 2; -+ int r; -+ ssize_t n; -+ -+ fds[0].fd = STDIN_FILENO; -+ fds[0].events = 0; -+ if (BUFSIZE-wlen > 0) -+ fds[0].events = POLLIN; -+ fds[0].revents = 0; -+ -+ fds[1].fd = STDOUT_FILENO; -+ fds[1].events = 0; -+ if (rlen > 0) -+ fds[1].events |= POLLOUT; -+ fds[1].revents = 0; -+ -+ if (sock >= 0) { -+ fds[2].fd = sock; -+ fds[2].events = 0; -+ if (BUFSIZE-rlen > 0) -+ fds[2].events |= POLLIN; -+ if (wlen > 0) -+ fds[2].events |= POLLOUT; -+ fds[2].revents = 0; -+ nfds++; -+ } -+ -+ r = poll (fds, nfds, -1); -+ if (r == -1) { -+ if (errno == EINTR || errno == EAGAIN) -+ continue; -+ perror ("poll"); -+ return; -+ } -+ -+ /* Input from local tty. */ -+ if ((fds[0].revents & POLLIN) != 0) { -+ assert (BUFSIZE-wlen > 0); -+ n = read (STDIN_FILENO, wbuf+wlen, BUFSIZE-wlen); -+ if (n == -1) { -+ if (errno == EINTR || errno == EAGAIN) -+ continue; -+ perror ("read"); -+ return; -+ } -+ if (n == 0) { -+ /* We don't expect this to happen. Maybe the whole tty went away? -+ * Anyway, we should exit as soon as possible. -+ */ -+ return; -+ } -+ if (n > 0) -+ wlen += n; -+ } -+ -+ /* Log message from appliance. */ -+ if (nfds > 2 && (fds[2].revents & POLLIN) != 0) { -+ assert (BUFSIZE-rlen > 0); -+ n = read (sock, rbuf+rlen, BUFSIZE-rlen); -+ if (n == -1) { -+ if (errno == EINTR || errno == EAGAIN) -+ continue; -+ if (errno == ECONNRESET) -+ goto appliance_closed; -+ perror ("read"); -+ return; -+ } -+ if (n == 0) { -+ appliance_closed: -+ sock = -1; -+ /* Don't actually close the socket, because it's owned by -+ * the guestfs handle. -+ */ -+ continue; -+ } -+ if (n > 0) -+ rlen += n; -+ } -+ -+ /* Write log messages to local tty. */ -+ if ((fds[1].revents & POLLOUT) != 0) { -+ assert (rlen > 0); -+ n = write (STDOUT_FILENO, rbuf, rlen); -+ if (n == -1) { -+ perror ("write"); -+ continue; -+ } -+ rlen -= n; -+ memmove (rbuf, rbuf+n, rlen); -+ } -+ -+ /* Write commands to the appliance. */ -+ if (nfds > 2 && (fds[2].revents & POLLOUT) != 0) { -+ assert (wlen > 0); -+ n = write (sock, wbuf, wlen); -+ if (n == -1) { -+ perror ("write"); -+ continue; -+ } -+ wlen -= n; -+ memmove (wbuf, wbuf+n, wlen); -+ } -+ } -+} -+ -+/* Put the tty in raw mode. */ -+static void -+raw_tty (void) -+{ -+ struct termios termios; -+ -+ if (tcgetattr (STDIN_FILENO, &termios) == -1) { -+ perror ("tcgetattr: stdin"); -+ exit (EXIT_FAILURE); -+ } -+ cfmakeraw (&termios); -+ if (tcsetattr (STDIN_FILENO, TCSANOW, &termios) == -1) { -+ perror ("tcsetattr: stdin"); -+ exit (EXIT_FAILURE); -+ } -+} -+ -+/* Restore the tty to (presumably) cooked mode as it was when -+ * the program was started. -+ */ -+static void -+restore_tty (void) -+{ -+ tcsetattr (STDIN_FILENO, TCSANOW, &old_termios); -+} -+ -+/* When we get SIGTSTP, switch back to cooked mode. */ -+static void -+tstp_handler (int sig) -+{ -+ restore_tty (); -+ signal (SIGTSTP, SIG_DFL); -+ raise (SIGTSTP); -+} -+ -+/* When we get SIGCONF, switch to raw mode. */ -+static void -+cont_handler (int sig) -+{ -+ raw_tty (); -+} -+ - static void suggest_filesystems (void); - - static int --- -2.14.3 - diff --git a/SOURCES/0056-v2v-File-ovf-size-changed-to-the-actual-size-if-know.patch b/SOURCES/0056-v2v-File-ovf-size-changed-to-the-actual-size-if-know.patch new file mode 100644 index 0000000..002959b --- /dev/null +++ b/SOURCES/0056-v2v-File-ovf-size-changed-to-the-actual-size-if-know.patch @@ -0,0 +1,41 @@ +From b91e15593f5853a9dfabf734aabacb1cc871da07 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 18 Jun 2018 10:31:18 +0100 +Subject: [PATCH] v2v: changed to the actual size (if known). + +Note that this attribute is optional. + +Thanks: Arik Hadas +(cherry picked from commit 75e8b1386766b18aecefdc8a75fbbf85ddb52037) +--- + v2v/create_ovf.ml | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml +index e0f81e0a2..9e0c772fd 100644 +--- a/v2v/create_ovf.ml ++++ b/v2v/create_ovf.ml +@@ -819,12 +819,17 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids + + (* Add disk to node. *) + let disk = +- e "File" [ ++ let attrs = ref [ + "ovf:href", fileref; + "ovf:id", vol_uuid; +- "ovf:size", Int64.to_string ov.ov_virtual_size; (* NB: in bytes *) + "ovf:description", generated_by; +- ] [] in ++ ] in ++ (match t.target_actual_size with ++ | None -> () ++ | Some actual_size -> ++ List.push_back attrs ("ovf:size", Int64.to_string actual_size) ++ ); ++ e "File" !attrs [] in + append_child disk references; + + (* Add disk to DiskSection. *) +-- +2.17.1 + diff --git a/SOURCES/0057-p2v-Allow-virt-v2v-input-and-output-drivers-containi.patch b/SOURCES/0057-p2v-Allow-virt-v2v-input-and-output-drivers-containi.patch new file mode 100644 index 0000000..d3a82d1 --- /dev/null +++ b/SOURCES/0057-p2v-Allow-virt-v2v-input-and-output-drivers-containi.patch @@ -0,0 +1,65 @@ +From ea9feae9d8793e417c393d6c61b558bb8764698d Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 12 Jun 2018 10:22:02 +0100 +Subject: [PATCH] p2v: Allow virt-v2v input and output drivers containing '-' + (RHBZ#1590220). +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The new ‘-o rhv-upload’ output mode contains a '-' character in the +name, but the regular expression which matched the output of the +virt-v2v command did not recognize '-' as a valid character. It ended +up mapping this to just "rhv" meaning two "rhv" entries would appear +in the list of output drivers. + +Thanks: Ming Xie. +(cherry picked from commit 3886a113f231f7b38a89333491888c4d9a0c19da) +--- + p2v/ssh.c | 7 +++++-- + v2v/modules_list.ml | 11 +++++++++-- + 2 files changed, 14 insertions(+), 4 deletions(-) + +diff --git a/p2v/ssh.c b/p2v/ssh.c +index d2699fffd..15f53b692 100644 +--- a/p2v/ssh.c ++++ b/p2v/ssh.c +@@ -181,8 +181,11 @@ compile_regexps (void) + 0); + COMPILE (feature_libguestfs_rewrite_re, "libguestfs-rewrite", 0); + COMPILE (feature_colours_option_re, "colours-option", 0); +- COMPILE (feature_input_re, "input:((?:\\w)*)", 0); +- COMPILE (feature_output_re, "output:((?:\\w)*)", 0); ++ /* The input and output regexps must match the same pattern in ++ * v2v/modules_list.ml. ++ */ ++ COMPILE (feature_input_re, "input:((?:[-\\w])+)", 0); ++ COMPILE (feature_output_re, "output:((?:[-\\w])+)", 0); + COMPILE (portfwd_re, "Allocated port ((?:\\d)+) for remote forward", 0); + } + +diff --git a/v2v/modules_list.ml b/v2v/modules_list.ml +index 91b029b07..b7accc4f9 100644 +--- a/v2v/modules_list.ml ++++ b/v2v/modules_list.ml +@@ -21,8 +21,15 @@ open Std_utils + let input_modules = ref [] + and output_modules = ref [] + +-let register_input_module name = List.push_front name input_modules +-and register_output_module name = List.push_front name output_modules ++(* Must match the regular expressions in p2v/ssh.c *) ++let module_name_re = PCRE.compile ~anchored:true "[-\\w]+" ++ ++let register_input_module name = ++ assert (PCRE.matches module_name_re name); ++ List.push_front name input_modules ++and register_output_module name = ++ assert (PCRE.matches module_name_re name); ++ List.push_front name output_modules + + let input_modules () = List.sort compare !input_modules + and output_modules () = List.sort compare !output_modules +-- +2.17.1 + diff --git a/SOURCES/0057-rescue-Implement-m-and-i-options.patch b/SOURCES/0057-rescue-Implement-m-and-i-options.patch deleted file mode 100644 index cc57d7f..0000000 --- a/SOURCES/0057-rescue-Implement-m-and-i-options.patch +++ /dev/null @@ -1,400 +0,0 @@ -From 5b0f9d72d49053d246463b7bb024f21f1c24d983 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 3 Mar 2017 13:52:31 +0000 -Subject: [PATCH] rescue: Implement -m and -i options. - -`virt-rescue -a disk -i' does the right thing. - -`-m' was previously an alternate form of `--memsize'. By sniffing the -parameter we can make `-m MB' continue to work, while also allowing -`-m' to be used as a short form for the `--mount' option. - -This also removes most of the description of `--suggest' from the man -page, since it is no longer needed. - -(cherry picked from commit 33d2ae796119ae5dd38e2afcbf1ba4216bd99846) ---- - appliance/init | 12 +++++-- - rescue/Makefile.am | 3 +- - rescue/rescue.c | 87 +++++++++++++++++++++++++++++++++++++------------- - rescue/virt-rescue.pod | 80 ++++++++++++++++++++++++++++------------------ - 4 files changed, 126 insertions(+), 56 deletions(-) - -diff --git a/appliance/init b/appliance/init -index ea763c2d3..4133de434 100755 ---- a/appliance/init -+++ b/appliance/init -@@ -181,6 +181,10 @@ else - # We need a daemon, even in virt-rescue. - $cmd & - -+ # XXX This gives a bit of time for virt-rescue to connect to the -+ # daemon and mount any filesystems. -+ sleep 2 -+ - # Get name of the serial port, from console= passed by libguestfs. - # XXX Consider using /proc/consoles - guestfs_serial=$(grep -Eo 'console=[^[:space:]]+' /proc/cmdline | -@@ -210,8 +214,12 @@ else - echo "Welcome to virt-rescue, the libguestfs rescue shell." - echo - echo "Note: The contents of / (root) are the rescue appliance." -- echo "You have to mount the guest's partitions under /sysroot" -- echo "before you can examine them." -+ if ! test -d "/sysroot/dev"; then -+ echo "You have to mount the guest's partitions under /sysroot" -+ echo "before you can examine them." -+ else -+ echo "Use 'cd /sysroot' or 'chroot /sysroot' to see guest filesystems." -+ fi - echo - run_bash_with_ctty - echo -diff --git a/rescue/Makefile.am b/rescue/Makefile.am -index 99d4b79ae..c83c43458 100644 ---- a/rescue/Makefile.am -+++ b/rescue/Makefile.am -@@ -35,7 +35,7 @@ virt_rescue_CPPFLAGS = \ - -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ - -I$(top_srcdir)/lib -I$(top_builddir)/lib \ - -I$(top_srcdir)/common/options -I$(top_builddir)/common/options \ -- -I$(top_srcdir)/fish \ -+ -I$(top_srcdir)/common/windows -I$(top_builddir)/common/windows \ - -I$(srcdir)/../gnulib/lib -I../gnulib/lib - - virt_rescue_CFLAGS = \ -@@ -43,6 +43,7 @@ virt_rescue_CFLAGS = \ - $(LIBXML2_CFLAGS) - - virt_rescue_LDADD = \ -+ $(top_builddir)/common/windows/libwindows.la \ - $(top_builddir)/common/options/liboptions.la \ - $(top_builddir)/common/utils/libutils.la \ - $(top_builddir)/lib/libguestfs.la \ -diff --git a/rescue/rescue.c b/rescue/rescue.c -index b145dcd40..2b461378d 100644 ---- a/rescue/rescue.c -+++ b/rescue/rescue.c -@@ -23,7 +23,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -37,9 +36,11 @@ - #include "full-write.h" - #include "getprogname.h" - #include "ignore-value.h" -+#include "nonblocking.h" - #include "xvasprintf.h" - - #include "guestfs.h" -+#include "windows.h" - #include "options.h" - #include "display-options.h" - -@@ -87,7 +88,9 @@ usage (int status) - " -d|--domain guest Add disks from libvirt guest\n" - " --format[=raw|..] Force disk format for -a option\n" - " --help Display brief help\n" -- " -m|--memsize MB Set memory size in megabytes\n" -+ " -i|--inspector Automatically mount filesystems\n" -+ " -m|--mount dev[:mnt[:opts[:fstype]] Mount dev on mnt (if omitted, /)\n" -+ " --memsize MB Set memory size in megabytes\n" - " --network Enable network\n" - " -r|--ro Access read-only\n" - " --scratch[=N] Add scratch disk(s)\n" -@@ -116,7 +119,7 @@ main (int argc, char *argv[]) - - enum { HELP_OPTION = CHAR_MAX + 1 }; - -- static const char options[] = "a:c:d:m:rvVwx"; -+ static const char options[] = "a:c:d:im:rvVwx"; - static const struct option long_options[] = { - { "add", 1, 0, 'a' }, - { "append", 1, 0, 0 }, -@@ -124,8 +127,10 @@ main (int argc, char *argv[]) - { "domain", 1, 0, 'd' }, - { "format", 2, 0, 0 }, - { "help", 0, 0, HELP_OPTION }, -+ { "inspector", 0, 0, 'i' }, - { "long-options", 0, 0, 0 }, -- { "memsize", 1, 0, 'm' }, -+ { "mount", 1, 0, 'm' }, -+ { "memsize", 1, 0, 0 }, - { "network", 0, 0, 0 }, - { "ro", 0, 0, 'r' }, - { "rw", 0, 0, 'w' }, -@@ -140,13 +145,16 @@ main (int argc, char *argv[]) - }; - struct drv *drvs = NULL; - struct drv *drv; -+ struct mp *mps = NULL; -+ struct mp *mp; -+ char *p; - const char *format = NULL; - bool format_consumed = true; - int c; - int option_index; - int network = 0; - const char *append = NULL; -- int memsize = 0; -+ int memsize = 0, m; - int smp = 0; - int suggest = 0; - char *append_full; -@@ -196,6 +204,10 @@ main (int argc, char *argv[]) - _("--scratch parameter '%s' should be >= 1"), optarg); - add_scratch_disks (n, &drvs); - } -+ } else if (STREQ (long_options[option_index].name, "memsize")) { -+ if (sscanf (optarg, "%d", &memsize) != 1) -+ error (EXIT_FAILURE, 0, -+ _("could not parse memory size '%s'"), optarg); - } else - error (EXIT_FAILURE, 0, - _("unknown long option: %s (%d)"), -@@ -214,10 +226,19 @@ main (int argc, char *argv[]) - OPTION_d; - break; - -+ case 'i': -+ OPTION_i; -+ break; -+ - case 'm': -- if (sscanf (optarg, "%d", &memsize) != 1) -- error (EXIT_FAILURE, 0, -- _("could not parse memory size '%s'"), optarg); -+ /* For backwards compatibility with virt-rescue <= 1.36, we -+ * must handle -m as a synonym for --memsize. -+ */ -+ if (sscanf (optarg, "%d", &m) == 1) -+ memsize = m; -+ else { -+ OPTION_m; -+ } - break; - - case 'r': -@@ -288,7 +309,6 @@ main (int argc, char *argv[]) - * options parsing code. Assert here that they have known-good - * values. - */ -- assert (inspector == 0); - assert (keys_from_stdin == 0); - assert (echo_keys == 0); - assert (live == 0); -@@ -332,12 +352,6 @@ main (int argc, char *argv[]) - exit (EXIT_FAILURE); - free (append_full); - -- /* Add drives. */ -- add_drives (drvs); -- -- /* Free up data structures, no longer needed after this point. */ -- free_drives (drvs); -- - /* Add an event handler to print "log messages". These will be the - * output of the appliance console during launch and shutdown. - * After launch, we will read the console messages directly from the -@@ -347,21 +361,50 @@ main (int argc, char *argv[]) - GUESTFS_EVENT_APPLIANCE, 0, NULL) == -1) - exit (EXIT_FAILURE); - -- /* Run the appliance. */ -+ /* Do the guest drives and mountpoints. */ -+ add_drives (drvs); - if (guestfs_launch (g) == -1) - exit (EXIT_FAILURE); -+ if (inspector) -+ inspect_mount (); -+ mount_mps (mps); -+ -+ free_drives (drvs); -+ free_mps (mps); -+ -+ /* Also bind-mount /dev etc under /sysroot, if -i was given. */ -+ if (inspector) { -+ CLEANUP_FREE_STRING_LIST char **roots; -+ int windows; -+ -+ roots = guestfs_inspect_get_roots (g); -+ windows = roots && roots[0] && is_windows (g, roots[0]); -+ if (!windows) { -+ const char *cmd[5] = { "mount", "--rbind", NULL, NULL, NULL }; -+ char *r; -+ -+ cmd[2] = "/dev"; cmd[3] = "/sysroot/dev"; -+ r = guestfs_debug (g, "sh", (char **) cmd); -+ free (r); -+ -+ cmd[2] = "/proc"; cmd[3] = "/sysroot/proc"; -+ r = guestfs_debug (g, "sh", (char **) cmd); -+ free (r); -+ -+ cmd[2] = "/sys"; cmd[3] = "/sysroot/sys"; -+ r = guestfs_debug (g, "sh", (char **) cmd); -+ free (r); -+ } -+ } - - sock = guestfs_internal_get_console_socket (g); - if (sock == -1) - exit (EXIT_FAILURE); - - /* Try to set all sockets to non-blocking. */ -- if (fcntl (STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1) -- perror ("could not set stdin to non-blocking"); -- if (fcntl (STDOUT_FILENO, F_SETFL, O_NONBLOCK) == -1) -- perror ("could not set stdout to non-blocking"); -- if (fcntl (sock, F_SETFL, O_NONBLOCK) == -1) -- perror ("could not set console socket to non-blocking"); -+ ignore_value (set_nonblocking_flag (STDIN_FILENO, 1)); -+ ignore_value (set_nonblocking_flag (STDOUT_FILENO, 1)); -+ ignore_value (set_nonblocking_flag (sock, 1)); - - /* Save the initial state of the tty so we always have the original - * state to go back to. -diff --git a/rescue/virt-rescue.pod b/rescue/virt-rescue.pod -index b8aa32637..b651f84e7 100644 ---- a/rescue/virt-rescue.pod -+++ b/rescue/virt-rescue.pod -@@ -6,9 +6,7 @@ virt-rescue - Run a rescue shell on a virtual machine - - virt-rescue [--options] -d domname - -- virt-rescue [--options] -a disk.img [-a disk.img ...] -- -- virt-rescue --suggest (-d domname | -a disk.img ...) -+ virt-rescue [--options] -a disk.img [-a disk.img ...] [-i] - - Old style: - -@@ -26,13 +24,13 @@ machine or disk image. - You can run virt-rescue on any virtual machine known to libvirt, or - directly on disk image(s): - -- virt-rescue -d GuestName -+ virt-rescue -d GuestName -i - -- virt-rescue --ro -a /path/to/disk.img -+ virt-rescue --ro -a /path/to/disk.img -i - - virt-rescue -a /dev/sdc - --For live VMs you I use the --ro option. -+For live VMs you I use the I<--ro> option. - - When you run virt-rescue on a virtual machine or disk image, you are - placed in an interactive bash shell where you can use many ordinary -@@ -41,26 +39,10 @@ rescue appliance. You must mount the virtual machine's filesystems by - hand. There is an empty directory called F where you can - mount filesystems. - --You can get virt-rescue to suggest mount commands for you by using the --I<--suggest> option (in another terminal): -- -- $ virt-rescue --suggest -d Fedora15 -- Inspecting the virtual machine or disk image ... -- -- This disk contains one or more operating systems. You can use these -- mount commands in virt-rescue (at the > prompt) to mount the -- filesystems. -- -- # /dev/vg_f15x32/lv_root is the root of a linux operating system -- # type: linux, distro: fedora, version: 15.0 -- # Fedora release 15 (Lovelock) -- -- mount /dev/vg_f15x32/lv_root /sysroot/ -- mount /dev/vda1 /sysroot/boot -- mount --bind /dev /sysroot/dev -- mount --bind /dev/pts /sysroot/dev/pts -- mount --bind /proc /sysroot/proc -- mount --bind /sys /sysroot/sys -+To automatically mount the virtual machine's filesystems under -+F use the I<-i> option. This uses libguestfs inspection to -+find the filesystems and mount them in the right place. You can also -+mount filesystems individually using the I<-m> option. - - Another way is to list the logical volumes (with L) and - partitions (with L) and mount them by hand: -@@ -170,7 +152,15 @@ If you have untrusted raw-format guest disk images, you should use - this option to specify the disk format. This avoids a possible - security problem with malicious guests (CVE-2010-3851). - --=item B<-m> MB -+=item B<-i> -+ -+=item B<--inspector> -+ -+Using L code, inspect the disks looking for -+an operating system and mount filesystems as they would be -+mounted on the real virtual machine. -+ -+The filesystems are mounted on F in the rescue environment. - - =item B<--memsize> MB - -@@ -179,6 +169,33 @@ default is set by libguestfs and is small but adequate for running - system tools. The occasional program might need more memory. The - parameter is specified in megabytes. - -+=item B<-m> dev[:mountpoint[:options[:fstype]]] -+ -+=item B<--mount> dev[:mountpoint[:options[:fstype]]] -+ -+Mount the named partition or logical volume on the given mountpoint -+B (this has nothing to do with mountpoints in the host). -+ -+If the mountpoint is omitted, it defaults to F. You have to mount -+something on F. -+ -+The filesystems are mounted under F in the rescue environment. -+ -+The third (and rarely used) part of the mount parameter is the list of -+mount options used to mount the underlying filesystem. If this is not -+given, then the mount options are either the empty string or C -+(the latter if the I<--ro> flag is used). By specifying the mount -+options, you override this default choice. Probably the only time you -+would use this is to enable ACLs and/or extended attributes if the -+filesystem can support them: -+ -+ -m /dev/sda1:/:acl,user_xattr -+ -+The fourth part of the parameter is the filesystem driver to use, such -+as C or C. This is rarely needed, but can be useful if -+multiple drivers are valid for a filesystem (eg: C and C), -+or if libguestfs misidentifies a filesystem. -+ - =item B<--network> - - Enable QEMU user networking in the guest. See L. -@@ -217,9 +234,10 @@ Enable N E 2 virtual CPUs in the rescue appliance. - - =item B<--suggest> - --Inspect the disk image and suggest what mount commands should be used --to mount the disks. You should use the I<--suggest> option in a --second terminal, then paste the commands into another virt-rescue. -+This option was used in older versions of virt-rescue to suggest what -+commands you could use to mount filesystems under F. For -+the current version of virt-rescue, it is easier to use the I<-i> -+option instead. - - This option implies I<--ro> and is safe to use even if the guest is up - or if another virt-rescue is running. -@@ -240,7 +258,7 @@ Display version number and exit. - - =item B<--rw> - --This changes the I<-a> and I<-d> options so that disks are -+This changes the I<-a>, I<-d> and I<-m> options so that disks are - added and mounts are done read-write. - - See L. --- -2.14.3 - diff --git a/SOURCES/0058-rescue-Implement-escape-sequences.patch b/SOURCES/0058-rescue-Implement-escape-sequences.patch deleted file mode 100644 index 4c00900..0000000 --- a/SOURCES/0058-rescue-Implement-escape-sequences.patch +++ /dev/null @@ -1,615 +0,0 @@ -From 50e044064b4388f11912d96d2eb52aea1b292734 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 4 Mar 2017 11:47:59 +0000 -Subject: [PATCH] rescue: Implement escape sequences. - -This implements a few useful escape sequences: - -> ^]? -virt-rescue escape sequences: - ^] ? - print this message - ^] h - print this message - ^] q - quit virt-rescue - ^] s - sync the filesystems - ^] u - unmount filesystems - ^] x - quit virt-rescue - ^] z - suspend virt-rescue -to pass the escape key through to the rescue shell, type it twice - -^]i - -root device: /dev/sda3 - product name: Fedora 25 (Twenty Five) - type: linux - distro: fedora - -^]z -[3]+ Stopped ./run virt-rescue --scratch -$ fg - -> ^]u - -unmounting filesystems ... -[ 21.158558] XFS (sda3): Unmounting Filesystem - -(cherry picked from commit 3637c42f4e521eb647d7dfae7f48eb1689d0af54) ---- - rescue/Makefile.am | 4 +- - rescue/escape.c | 302 +++++++++++++++++++++++++++++++++++++++++++++++++ - rescue/rescue.c | 30 ++++- - rescue/rescue.h | 47 ++++++++ - rescue/virt-rescue.pod | 74 ++++++++++++ - 5 files changed, 454 insertions(+), 3 deletions(-) - create mode 100644 rescue/escape.c - create mode 100644 rescue/rescue.h - -diff --git a/rescue/Makefile.am b/rescue/Makefile.am -index c83c43458..eb60bafa4 100644 ---- a/rescue/Makefile.am -+++ b/rescue/Makefile.am -@@ -26,7 +26,9 @@ EXTRA_DIST = \ - bin_PROGRAMS = virt-rescue - - virt_rescue_SOURCES = \ -- rescue.c -+ escape.c \ -+ rescue.c \ -+ rescue.h - - virt_rescue_CPPFLAGS = \ - -DGUESTFS_WARN_DEPRECATED=1 \ -diff --git a/rescue/escape.c b/rescue/escape.c -new file mode 100644 -index 000000000..f7f7d84c4 ---- /dev/null -+++ b/rescue/escape.c -@@ -0,0 +1,302 @@ -+/* virt-rescue -+ * Copyright (C) 2010-2017 Red Hat Inc. -+ * -+ * 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. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "c-ctype.h" -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ -+#include "rescue.h" -+ -+static void print_help (void); -+static void print_inspector (void); -+static void crlf (void); -+static void print_escape_key (void); -+ -+/* Parse the -e parameter from the command line. */ -+int -+parse_escape_key (const char *arg) -+{ -+ size_t len; -+ -+ if (STREQ (arg, "none")) -+ return 0; -+ -+ len = strlen (arg); -+ if (arg == 0) -+ return -1; -+ -+ switch (arg[0]) { -+ case '^': -+ if (len == 2 && -+ ((arg[1] >= 'a' && arg[1] <= 'z') || -+ (arg[1] >= 'A' && arg[1] <= '_'))) { -+ return c_toupper (arg[1]) - '@'; -+ } -+ else -+ return -1; -+ break; -+ } -+ -+ return -1; -+} -+ -+/* Print one-line end user description of the escape key. -+ * -+ * This is printed when virt-rescue starts. -+ */ -+void -+print_escape_key_help (void) -+{ -+ crlf (); -+ /* Difficult to translate this string. XXX */ -+ printf ("The virt-rescue escape key is ‘"); -+ print_escape_key (); -+ printf ("’. Type ‘"); -+ print_escape_key (); -+ printf (" h’ for help."); -+ crlf (); -+} -+ -+void -+init_escape_state (struct escape_state *state) -+{ -+ state->in_escape = false; -+} -+ -+/* Process escapes in the tty input buffer. -+ * -+ * This function has a state parameter so that we can handle an escape -+ * sequence split over the end of the buffer. -+ * -+ * Escape sequences are removed from the buffer. -+ * -+ * Returns true iff virt-rescue should exit. -+ */ -+bool -+process_escapes (struct escape_state *state, char *buf, size_t *len) -+{ -+ size_t i; -+ -+ for (i = 0; i < *len; ++i) { -+#define DROP_CURRENT_CHAR() \ -+ memmove (&buf[i], &buf[i+1], --(*len)) -+#define PRINT_ESC() \ -+ do { print_escape_key (); putchar (buf[i]); crlf (); } while (0) -+ -+ if (!state->in_escape) { -+ if (buf[i] == escape_key) { -+ /* Drop the escape key from the buffer and go to escape mode. */ -+ DROP_CURRENT_CHAR (); -+ state->in_escape = true; -+ } -+ } -+ else /* in escape sequence */ { -+ if (buf[i] == escape_key) /* ^] ^] means send ^] to rescue shell */ -+ state->in_escape = false; -+ else { -+ switch (buf[i]) { -+ case '?': case 'h': -+ PRINT_ESC (); -+ print_help (); -+ break; -+ -+ case 'i': -+ PRINT_ESC (); -+ print_inspector (); -+ break; -+ -+ case 'q': case 'x': -+ PRINT_ESC (); -+ return true /* exit virt-rescue at once */; -+ -+ case 's': -+ PRINT_ESC (); -+ printf (_("attempting to sync filesystems ...")); -+ crlf (); -+ guestfs_sync (g); -+ break; -+ -+ case 'u': -+ PRINT_ESC (); -+ printf (_("unmounting filesystems ...")); -+ crlf (); -+ guestfs_umount_all (g); -+ break; -+ -+ case 'z': -+ PRINT_ESC (); -+ raise (SIGTSTP); -+ break; -+ -+ default: -+ /* Any unrecognized escape sequence will be dropped. We -+ * could be obnoxious and ring the bell, but I hate it when -+ * programs do that. -+ */ -+ break; -+ } -+ -+ /* Drop the escape key and return to non-escape mode. */ -+ DROP_CURRENT_CHAR (); -+ state->in_escape = false; -+ -+ /* The output is line buffered, this is just to make sure -+ * everything gets written to stdout before we continue -+ * writing to STDOUT_FILENO. -+ */ -+ fflush (stdout); -+ } -+ } /* in escape sequence */ -+ } /* for */ -+ -+ return false /* don't exit */; -+} -+ -+/* This is called when the user types ^] h */ -+static void -+print_help (void) -+{ -+ printf (_("virt-rescue escape sequences:")); -+ crlf (); -+ -+ putchar (' '); -+ print_escape_key (); -+ printf (_(" ? - print this message")); -+ crlf (); -+ -+ putchar (' '); -+ print_escape_key (); -+ printf (_(" h - print this message")); -+ crlf (); -+ -+ if (inspector) { -+ putchar (' '); -+ print_escape_key (); -+ printf (_(" i - print inspection data")); -+ crlf (); -+ } -+ -+ putchar (' '); -+ print_escape_key (); -+ printf (_(" q - quit virt-rescue")); -+ crlf (); -+ -+ putchar (' '); -+ print_escape_key (); -+ printf (_(" s - sync the filesystems")); -+ crlf (); -+ -+ putchar (' '); -+ print_escape_key (); -+ printf (_(" u - unmount filesystems")); -+ crlf (); -+ -+ putchar (' '); -+ print_escape_key (); -+ printf (_(" x - quit virt-rescue")); -+ crlf (); -+ -+ putchar (' '); -+ print_escape_key (); -+ printf (_(" z - suspend virt-rescue")); -+ crlf (); -+ -+ printf (_("to pass the escape key through to the rescue shell, type it twice")); -+ crlf (); -+} -+ -+/* This is called when the user types ^] i */ -+static void -+print_inspector (void) -+{ -+ CLEANUP_FREE_STRING_LIST char **roots; -+ size_t i; -+ const char *root; -+ char *str; -+ -+ if (inspector) { -+ roots = guestfs_inspect_get_roots (g); -+ if (roots) { -+ crlf (); -+ for (i = 0; roots[i] != NULL; ++i) { -+ root = roots[i]; -+ printf (_("root device: %s"), root); -+ crlf (); -+ -+ str = guestfs_inspect_get_product_name (g, root); -+ if (str) { -+ printf (_(" product name: %s"), str); -+ crlf (); -+ } -+ free (str); -+ -+ str = guestfs_inspect_get_type (g, root); -+ if (str) { -+ printf (_(" type: %s"), str); -+ crlf (); -+ } -+ free (str); -+ -+ str = guestfs_inspect_get_distro (g, root); -+ if (str) { -+ printf (_(" distro: %s"), str); -+ crlf (); -+ } -+ free (str); -+ } -+ } -+ } -+} -+ -+/* Because the terminal is in raw mode, we have to send CR LF instead -+ * of printing just \n. -+ */ -+static void -+crlf (void) -+{ -+ putchar ('\r'); -+ putchar ('\n'); -+} -+ -+static void -+print_escape_key (void) -+{ -+ switch (escape_key) { -+ case 0: -+ printf ("none"); -+ break; -+ case '\x1'...'\x1f': -+ putchar ('^'); -+ putchar (escape_key + '@'); -+ break; -+ default: -+ abort (); -+ } -+} -diff --git a/rescue/rescue.c b/rescue/rescue.c -index 2b461378d..5281b1161 100644 ---- a/rescue/rescue.c -+++ b/rescue/rescue.c -@@ -1,5 +1,5 @@ - /* virt-rescue -- * Copyright (C) 2010-2012 Red Hat Inc. -+ * Copyright (C) 2010-2017 Red Hat Inc. - * - * 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 -@@ -40,10 +40,14 @@ - #include "xvasprintf.h" - - #include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ - #include "windows.h" - #include "options.h" - #include "display-options.h" - -+#include "rescue.h" -+ - static void log_message_callback (guestfs_h *g, void *opaque, uint64_t event, int event_handle, int flags, const char *buf, size_t buf_len, const uint64_t *array, size_t array_len); - static void do_rescue (int sock); - static void raw_tty (void); -@@ -65,6 +69,7 @@ const char *libvirt_uri = NULL; - int inspector = 0; - int in_guestfish = 0; - int in_virt_rescue = 1; -+int escape_key = '\x1d'; /* ^] */ - - /* Old terminal settings. */ - static struct termios old_termios; -@@ -86,6 +91,7 @@ usage (int status) - " --append kernelopts Append kernel options\n" - " -c|--connect uri Specify libvirt URI for -d option\n" - " -d|--domain guest Add disks from libvirt guest\n" -+ " -e ^x|none Set or disable escape key (default ^])\n" - " --format[=raw|..] Force disk format for -a option\n" - " --help Display brief help\n" - " -i|--inspector Automatically mount filesystems\n" -@@ -119,7 +125,7 @@ main (int argc, char *argv[]) - - enum { HELP_OPTION = CHAR_MAX + 1 }; - -- static const char options[] = "a:c:d:im:rvVwx"; -+ static const char options[] = "a:c:d:e:im:rvVwx"; - static const struct option long_options[] = { - { "add", 1, 0, 'a' }, - { "append", 1, 0, 0 }, -@@ -226,6 +232,12 @@ main (int argc, char *argv[]) - OPTION_d; - break; - -+ case 'e': -+ escape_key = parse_escape_key (optarg); -+ if (escape_key == -1) -+ error (EXIT_FAILURE, 0, _("unrecognized escape key: %s"), optarg); -+ break; -+ - case 'i': - OPTION_i; - break; -@@ -428,6 +440,10 @@ main (int argc, char *argv[]) - signal (SIGTSTP, tstp_handler); - signal (SIGCONT, cont_handler); - -+ /* Print the escape key if set. */ -+ if (escape_key > 0) -+ print_escape_key_help (); -+ - do_rescue (sock); - - restore_tty (); -@@ -478,6 +494,9 @@ do_rescue (int sock) - { - size_t rlen = 0; - size_t wlen = 0; -+ struct escape_state escape_state; -+ -+ init_escape_state (&escape_state); - - while (sock >= 0 || rlen > 0) { - struct pollfd fds[3]; -@@ -534,6 +553,13 @@ do_rescue (int sock) - } - if (n > 0) - wlen += n; -+ -+ /* Process escape sequences in the tty input. If the function -+ * returns true, then we exit the loop causing virt-rescue to -+ * exit. -+ */ -+ if (escape_key > 0 && process_escapes (&escape_state, wbuf, &wlen)) -+ return; - } - - /* Log message from appliance. */ -diff --git a/rescue/rescue.h b/rescue/rescue.h -new file mode 100644 -index 000000000..ccffb5eb3 ---- /dev/null -+++ b/rescue/rescue.h -@@ -0,0 +1,47 @@ -+/* virt-rescue -+ * Copyright (C) 2010-2017 Red Hat Inc. -+ * -+ * 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. -+ */ -+ -+#ifndef RESCUE_H -+#define RESCUE_H -+ -+#include -+ -+#include "guestfs.h" -+ -+extern guestfs_h *g; -+extern int read_only; -+extern int live; -+extern int verbose; -+extern int keys_from_stdin; -+extern int echo_keys; -+extern const char *libvirt_uri; -+extern int inspector; -+extern int in_guestfish; -+extern int in_virt_rescue; -+extern int escape_key; -+ -+/* escape.c */ -+struct escape_state { -+ bool in_escape; -+}; -+extern void init_escape_state (struct escape_state *state); -+extern bool process_escapes (struct escape_state *state, char *buf, size_t *len); -+extern int parse_escape_key (const char *); -+extern void print_escape_key_help (void); -+ -+#endif /* RESCUE_H */ -diff --git a/rescue/virt-rescue.pod b/rescue/virt-rescue.pod -index b651f84e7..bd6f954e9 100644 ---- a/rescue/virt-rescue.pod -+++ b/rescue/virt-rescue.pod -@@ -128,6 +128,29 @@ not used at all. - Add all the disks from the named libvirt guest. Domain UUIDs can be - used instead of names. - -+=item B<-e none> -+ -+Disable the escape key. -+ -+=item B<-e> KEY -+ -+Set the escape key to the given key sequence. The default is C<^]>. -+To specify the escape key you can use: -+ -+=over 4 -+ -+=item C<^x> -+ -+Control key + C key. -+ -+=item C -+ -+I<-e none> means there is no escape key, escapes are disabled. -+ -+=back -+ -+See L below for further information. -+ - =item B<--format=raw|qcow2|..> - - =item B<--format> -@@ -321,6 +344,57 @@ See L for more details. - - =back - -+=head1 ESCAPE KEY -+ -+Virt-rescue supports various keyboard escape sequences which are -+entered by pressing C<^]> (Control key + C<]> key). -+ -+You can change the escape key using the I<-e> option on the command -+line (see above), and you can disable escapes completely using -+I<-e none>. The rest of this section assumes the default escape key. -+ -+The following escapes can be used: -+ -+=over 4 -+ -+=item C<^] ?> -+ -+=item C<^] h> -+ -+Prints a brief help text about escape sequences. -+ -+=item C<^] i> -+ -+Prints brief libguestfs inspection information for the guest. This -+only works if you used I<-i> on the virt-rescue command line. -+ -+=item C<^] q> -+ -+=item C<^] x> -+ -+Quits virt-rescue immediately. -+ -+=item C<^] s> -+ -+Synchronize the filesystems (sync). -+ -+=item C<^] u> -+ -+Unmounts all the filesystems, except for the root (appliance) -+filesystems. -+ -+=item C<^] z> -+ -+Suspend virt-rescue (like pressing C<^Z> except that it affects -+virt-rescue rather than the program inside the rescue shell). -+ -+=item C<^] ^]> -+ -+Sends the literal character C<^]> (ASCII 0x1d) through to the rescue -+shell. -+ -+=back -+ - =head1 CAPTURING CORE DUMPS - - If you are testing a tool inside virt-rescue and the tool (B --- -2.14.3 - diff --git a/SOURCES/0058-v2v-o-libvirt-Don-t-write-only-vendor-without-model-.patch b/SOURCES/0058-v2v-o-libvirt-Don-t-write-only-vendor-without-model-.patch new file mode 100644 index 0000000..c65c754 --- /dev/null +++ b/SOURCES/0058-v2v-o-libvirt-Don-t-write-only-vendor-without-model-.patch @@ -0,0 +1,48 @@ +From 70f1d97ef7b12fddceb3b16618072ad4c142da5c Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 15 Jun 2018 16:17:35 +0100 +Subject: [PATCH] v2v: -o libvirt: Don't write only without + (RHBZ#1591789). + +Avoids the libvirt error: + + error: XML error: CPU vendor specified without CPU model + +(cherry picked from commit e2910eeaf84afe63887afdc62b319bff1549d296) +--- + v2v/create_libvirt_xml.ml | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +diff --git a/v2v/create_libvirt_xml.ml b/v2v/create_libvirt_xml.ml +index 582419f00..fbe90eeaa 100644 +--- a/v2v/create_libvirt_xml.ml ++++ b/v2v/create_libvirt_xml.ml +@@ -51,15 +51,17 @@ let create_libvirt_xml ?pool source target_buses guestcaps + source.s_cpu_topology <> None then ( + let cpu = ref [] in + +- (match source.s_cpu_vendor with +- | None -> () +- | Some vendor -> +- List.push_back cpu (e "vendor" [] [PCData vendor]) +- ); +- (match source.s_cpu_model with +- | None -> () +- | Some model -> ++ (match source.s_cpu_vendor, source.s_cpu_model with ++ | None, None ++ (* Avoid libvirt error: "CPU vendor specified without CPU model" *) ++ | Some _, None -> () ++ | None, Some model -> + List.push_back cpu (e "model" ["fallback", "allow"] [PCData model]) ++ | Some vendor, Some model -> ++ List.push_back_list cpu [ ++ e "vendor" [] [PCData vendor]; ++ e "model" ["fallback", "allow"] [PCData model] ++ ] + ); + (match source.s_cpu_topology with + | None -> () +-- +2.17.1 + diff --git a/SOURCES/0059-rescue-Move-suggest-code-to-separate-file.patch b/SOURCES/0059-rescue-Move-suggest-code-to-separate-file.patch deleted file mode 100644 index 00585e9..0000000 --- a/SOURCES/0059-rescue-Move-suggest-code-to-separate-file.patch +++ /dev/null @@ -1,397 +0,0 @@ -From 0a3e771414378057d0e838c6a45d2f840ff7a8af Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 4 Mar 2017 15:35:09 +0000 -Subject: [PATCH] rescue: Move --suggest code to separate file. - -Just code motion. - -(cherry picked from commit 5ea17e97e4413c3db4449ded72b9677cce09444f) ---- - rescue/Makefile.am | 3 +- - rescue/rescue.c | 144 ------------------------------------------- - rescue/rescue.h | 5 ++ - rescue/suggest.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 182 insertions(+), 145 deletions(-) - create mode 100644 rescue/suggest.c - -diff --git a/rescue/Makefile.am b/rescue/Makefile.am -index eb60bafa4..d478c8e3d 100644 ---- a/rescue/Makefile.am -+++ b/rescue/Makefile.am -@@ -28,7 +28,8 @@ bin_PROGRAMS = virt-rescue - virt_rescue_SOURCES = \ - escape.c \ - rescue.c \ -- rescue.h -+ rescue.h \ -+ suggest.c - - virt_rescue_CPPFLAGS = \ - -DGUESTFS_WARN_DEPRECATED=1 \ -diff --git a/rescue/rescue.c b/rescue/rescue.c -index 5281b1161..a1aac53e4 100644 ---- a/rescue/rescue.c -+++ b/rescue/rescue.c -@@ -55,7 +55,6 @@ static void restore_tty (void); - static void tstp_handler (int sig); - static void cont_handler (int sig); - static void add_scratch_disks (int n, struct drv **drvs); --static void do_suggestion (struct drv *drvs); - - /* Currently open libguestfs handle. */ - guestfs_h *g; -@@ -654,149 +653,6 @@ cont_handler (int sig) - raw_tty (); - } - --static void suggest_filesystems (void); -- --static int --compare_keys_len (const void *p1, const void *p2) --{ -- const char *key1 = * (char * const *) p1; -- const char *key2 = * (char * const *) p2; -- return strlen (key1) - strlen (key2); --} -- --/* virt-rescue --suggest flag does a kind of inspection on the -- * drives and suggests mount commands that you should use. -- */ --static void --do_suggestion (struct drv *drvs) --{ -- CLEANUP_FREE_STRING_LIST char **roots = NULL; -- size_t i; -- -- /* For inspection, force add_drives to add the drives read-only. */ -- read_only = 1; -- -- /* Add drives. */ -- add_drives (drvs); -- -- /* Free up data structures, no longer needed after this point. */ -- free_drives (drvs); -- -- printf (_("Inspecting the virtual machine or disk image ...\n\n")); -- fflush (stdout); -- -- if (guestfs_launch (g) == -1) -- exit (EXIT_FAILURE); -- -- /* Don't use inspect_mount, since for virt-rescue we should allow -- * arbitrary disks and disks with more than one OS on them. Let's -- * do this using the basic API instead. -- */ -- roots = guestfs_inspect_os (g); -- if (roots == NULL) -- exit (EXIT_FAILURE); -- -- if (roots[0] == NULL) { -- suggest_filesystems (); -- return; -- } -- -- printf (_("This disk contains one or more operating systems. You can use these mount\n" -- "commands in virt-rescue (at the > prompt) to mount the filesystems.\n\n")); -- -- for (i = 0; roots[i] != NULL; ++i) { -- CLEANUP_FREE_STRING_LIST char **mps = NULL; -- CLEANUP_FREE char *type = NULL, *distro = NULL, *product_name = NULL; -- int major, minor; -- size_t j; -- -- type = guestfs_inspect_get_type (g, roots[i]); -- distro = guestfs_inspect_get_distro (g, roots[i]); -- product_name = guestfs_inspect_get_product_name (g, roots[i]); -- major = guestfs_inspect_get_major_version (g, roots[i]); -- minor = guestfs_inspect_get_minor_version (g, roots[i]); -- -- printf (_("# %s is the root of a %s operating system\n" -- "# type: %s, distro: %s, version: %d.%d\n" -- "# %s\n\n"), -- roots[i], type ? : "unknown", -- type ? : "unknown", distro ? : "unknown", major, minor, -- product_name ? : ""); -- -- mps = guestfs_inspect_get_mountpoints (g, roots[i]); -- if (mps == NULL) -- exit (EXIT_FAILURE); -- -- /* Sort by key length, shortest key first, so that we end up -- * mounting the filesystems in the correct order. -- */ -- qsort (mps, guestfs_int_count_strings (mps) / 2, 2 * sizeof (char *), -- compare_keys_len); -- -- for (j = 0; mps[j] != NULL; j += 2) -- printf ("mount %s /sysroot%s\n", mps[j+1], mps[j]); -- -- /* If it's Linux, print the bind-mounts and a chroot command. */ -- if (type && STREQ (type, "linux")) { -- printf ("mount --rbind /dev /sysroot/dev\n"); -- printf ("mount --rbind /proc /sysroot/proc\n"); -- printf ("mount --rbind /sys /sysroot/sys\n"); -- printf ("\n"); -- printf ("cd /sysroot\n"); -- printf ("chroot /sysroot\n"); -- } -- -- printf ("\n"); -- } --} -- --/* Inspection failed, so it doesn't contain any OS that we recognise. -- * However there might still be filesystems so print some suggestions -- * for those. -- */ --static void --suggest_filesystems (void) --{ -- size_t i, count; -- -- CLEANUP_FREE_STRING_LIST char **fses = guestfs_list_filesystems (g); -- if (fses == NULL) -- exit (EXIT_FAILURE); -- -- /* Count how many are not swap or unknown. Possibly we should try -- * mounting to see which are mountable, but that has a high -- * probability of breaking. -- */ --#define TEST_MOUNTABLE(fs) STRNEQ ((fs), "swap") && STRNEQ ((fs), "unknown") -- count = 0; -- for (i = 0; fses[i] != NULL; i += 2) { -- if (TEST_MOUNTABLE (fses[i+1])) -- count++; -- } -- -- if (count == 0) { -- printf (_("This disk contains no mountable filesystems that we recognize.\n\n" -- "However you can still use virt-rescue on the disk image, to try to mount\n" -- "filesystems that are not recognized by libguestfs, or to create partitions,\n" -- "logical volumes and filesystems on a blank disk.\n")); -- return; -- } -- -- printf (_("This disk contains one or more filesystems, but we don't recognize any\n" -- "operating system. You can use these mount commands in virt-rescue (at the\n" -- "> prompt) to mount these filesystems.\n\n")); -- -- for (i = 0; fses[i] != NULL; i += 2) { -- printf (_("# %s has type '%s'\n"), fses[i], fses[i+1]); -- -- if (TEST_MOUNTABLE (fses[i+1])) -- printf ("mount %s /sysroot\n", fses[i]); -- -- printf ("\n"); -- } --#undef TEST_MOUNTABLE --} -- - static void add_scratch_disk (struct drv **drvs); - - static void -diff --git a/rescue/rescue.h b/rescue/rescue.h -index ccffb5eb3..4f5a04a71 100644 ---- a/rescue/rescue.h -+++ b/rescue/rescue.h -@@ -23,6 +23,8 @@ - - #include "guestfs.h" - -+#include "options.h" -+ - extern guestfs_h *g; - extern int read_only; - extern int live; -@@ -44,4 +46,7 @@ extern bool process_escapes (struct escape_state *state, char *buf, size_t *len) - extern int parse_escape_key (const char *); - extern void print_escape_key_help (void); - -+/* suggest.c */ -+extern void do_suggestion (struct drv *drvs); -+ - #endif /* RESCUE_H */ -diff --git a/rescue/suggest.c b/rescue/suggest.c -new file mode 100644 -index 000000000..13141ccc2 ---- /dev/null -+++ b/rescue/suggest.c -@@ -0,0 +1,175 @@ -+/* virt-rescue -+ * Copyright (C) 2010-2017 Red Hat Inc. -+ * -+ * 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. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "guestfs.h" -+#include "guestfs-internal-frontend.h" -+ -+#include "options.h" -+ -+#include "rescue.h" -+ -+static void suggest_filesystems (void); -+ -+static int -+compare_keys_len (const void *p1, const void *p2) -+{ -+ const char *key1 = * (char * const *) p1; -+ const char *key2 = * (char * const *) p2; -+ return strlen (key1) - strlen (key2); -+} -+ -+/* virt-rescue --suggest flag does a kind of inspection on the -+ * drives and suggests mount commands that you should use. -+ */ -+void -+do_suggestion (struct drv *drvs) -+{ -+ CLEANUP_FREE_STRING_LIST char **roots = NULL; -+ size_t i; -+ -+ /* For inspection, force add_drives to add the drives read-only. */ -+ read_only = 1; -+ -+ /* Add drives. */ -+ add_drives (drvs); -+ -+ /* Free up data structures, no longer needed after this point. */ -+ free_drives (drvs); -+ -+ printf (_("Inspecting the virtual machine or disk image ...\n\n")); -+ fflush (stdout); -+ -+ if (guestfs_launch (g) == -1) -+ exit (EXIT_FAILURE); -+ -+ /* Don't use inspect_mount, since for virt-rescue we should allow -+ * arbitrary disks and disks with more than one OS on them. Let's -+ * do this using the basic API instead. -+ */ -+ roots = guestfs_inspect_os (g); -+ if (roots == NULL) -+ exit (EXIT_FAILURE); -+ -+ if (roots[0] == NULL) { -+ suggest_filesystems (); -+ return; -+ } -+ -+ printf (_("This disk contains one or more operating systems. You can use these mount\n" -+ "commands in virt-rescue (at the > prompt) to mount the filesystems.\n\n")); -+ -+ for (i = 0; roots[i] != NULL; ++i) { -+ CLEANUP_FREE_STRING_LIST char **mps = NULL; -+ CLEANUP_FREE char *type = NULL, *distro = NULL, *product_name = NULL; -+ int major, minor; -+ size_t j; -+ -+ type = guestfs_inspect_get_type (g, roots[i]); -+ distro = guestfs_inspect_get_distro (g, roots[i]); -+ product_name = guestfs_inspect_get_product_name (g, roots[i]); -+ major = guestfs_inspect_get_major_version (g, roots[i]); -+ minor = guestfs_inspect_get_minor_version (g, roots[i]); -+ -+ printf (_("# %s is the root of a %s operating system\n" -+ "# type: %s, distro: %s, version: %d.%d\n" -+ "# %s\n\n"), -+ roots[i], type ? : "unknown", -+ type ? : "unknown", distro ? : "unknown", major, minor, -+ product_name ? : ""); -+ -+ mps = guestfs_inspect_get_mountpoints (g, roots[i]); -+ if (mps == NULL) -+ exit (EXIT_FAILURE); -+ -+ /* Sort by key length, shortest key first, so that we end up -+ * mounting the filesystems in the correct order. -+ */ -+ qsort (mps, guestfs_int_count_strings (mps) / 2, 2 * sizeof (char *), -+ compare_keys_len); -+ -+ for (j = 0; mps[j] != NULL; j += 2) -+ printf ("mount %s /sysroot%s\n", mps[j+1], mps[j]); -+ -+ /* If it's Linux, print the bind-mounts and a chroot command. */ -+ if (type && STREQ (type, "linux")) { -+ printf ("mount --rbind /dev /sysroot/dev\n"); -+ printf ("mount --rbind /proc /sysroot/proc\n"); -+ printf ("mount --rbind /sys /sysroot/sys\n"); -+ printf ("\n"); -+ printf ("cd /sysroot\n"); -+ printf ("chroot /sysroot\n"); -+ } -+ -+ printf ("\n"); -+ } -+} -+ -+/* Inspection failed, so it doesn't contain any OS that we recognise. -+ * However there might still be filesystems so print some suggestions -+ * for those. -+ */ -+static void -+suggest_filesystems (void) -+{ -+ size_t i, count; -+ -+ CLEANUP_FREE_STRING_LIST char **fses = guestfs_list_filesystems (g); -+ if (fses == NULL) -+ exit (EXIT_FAILURE); -+ -+ /* Count how many are not swap or unknown. Possibly we should try -+ * mounting to see which are mountable, but that has a high -+ * probability of breaking. -+ */ -+#define TEST_MOUNTABLE(fs) STRNEQ ((fs), "swap") && STRNEQ ((fs), "unknown") -+ count = 0; -+ for (i = 0; fses[i] != NULL; i += 2) { -+ if (TEST_MOUNTABLE (fses[i+1])) -+ count++; -+ } -+ -+ if (count == 0) { -+ printf (_("This disk contains no mountable filesystems that we recognize.\n\n" -+ "However you can still use virt-rescue on the disk image, to try to mount\n" -+ "filesystems that are not recognized by libguestfs, or to create partitions,\n" -+ "logical volumes and filesystems on a blank disk.\n")); -+ return; -+ } -+ -+ printf (_("This disk contains one or more filesystems, but we don't recognize any\n" -+ "operating system. You can use these mount commands in virt-rescue (at the\n" -+ "> prompt) to mount these filesystems.\n\n")); -+ -+ for (i = 0; fses[i] != NULL; i += 2) { -+ printf (_("# %s has type '%s'\n"), fses[i], fses[i+1]); -+ -+ if (TEST_MOUNTABLE (fses[i+1])) -+ printf ("mount %s /sysroot\n", fses[i]); -+ -+ printf ("\n"); -+ } -+#undef TEST_MOUNTABLE -+} --- -2.14.3 - diff --git a/SOURCES/0059-v2v-rvh-upload-plugin-Always-read-the-response.patch b/SOURCES/0059-v2v-rvh-upload-plugin-Always-read-the-response.patch new file mode 100644 index 0000000..82cfce9 --- /dev/null +++ b/SOURCES/0059-v2v-rvh-upload-plugin-Always-read-the-response.patch @@ -0,0 +1,112 @@ +From 320ba554d11f75c4c2753968505a1d3308b64dda Mon Sep 17 00:00:00 2001 +From: Nir Soffer +Date: Mon, 25 Jun 2018 19:22:13 +0300 +Subject: [PATCH] v2v: rvh-upload-plugin: Always read the response + +Python manual warns[1]: + + Note that you must have read the whole response before you can send + a new request to the server. + +The reason for this warning is exposed only when the server is using +keep alive connections. When the response is not read, sending a new +request will fail with: + + httplib.ResponseNotReady + +Even if Content-Length was 0 or the request has no content. The failure +looks like this when using --verbose: + +nbdkit: python[1]: debug: zero count=33554432 offset=0 may_trim=1 fua=0 +nbdkit: python[1]: debug: zero count=33554432 offset=33554432 may_trim=1 fua=0 +nbdkit: python[1]: error: /home/nsoffer/src/libguestfs/tmp/rhvupload.Au2B5I/rhv-upload-plugin.py: zero: error: Request-sent +nbdkit: python[1]: debug: sending error reply: Input/output error +qemu-img: error writing zeroes at offset 0: Input/output error + +Change all requests to read the whole response. + +Tested with imageio patch supporting keep alive connections: +https://gerrit.ovirt.org/#/c/92296/ + +[1] https://docs.python.org/3.8/library/http.client.html#http.client.HTTPConnection.getresponse + +(cherry picked from commit f4e0a8342dbeb2c779c76e1807a37b24a0c96feb) +--- + v2v/rhv-upload-plugin.py | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 7c5084efd..2eec375f7 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -197,11 +197,13 @@ def get_options(h): + http.endheaders() + + r = http.getresponse() ++ data = r.read() ++ + if r.status == 200: + # New imageio never needs authentication. + h['needs_auth'] = False + +- j = json.loads(r.read()) ++ j = json.loads(data) + h['can_zero'] = "zero" in j['features'] + h['can_trim'] = "trim" in j['features'] + h['can_flush'] = "flush" in j['features'] +@@ -276,6 +278,7 @@ def pread(h, count, offset): + request_failed(h, r, + "could not read sector offset %d size %d" % + (offset, count)) ++ + return r.read() + + def pwrite(h, buf, offset): +@@ -302,6 +305,8 @@ def pwrite(h, buf, offset): + "could not write sector offset %d size %d" % + (offset, count)) + ++ r.read() ++ + def zero(h, count, offset, may_trim): + http = h['http'] + transfer = h['transfer'] +@@ -330,6 +335,8 @@ def zero(h, count, offset, may_trim): + "could not zero sector offset %d size %d" % + (offset, count)) + ++ r.read() ++ + def emulate_zero(h, count, offset): + # qemu-img convert starts by trying to zero/trim the whole device. + # Since we've just created a new disk it's safe to ignore these +@@ -357,6 +364,8 @@ def emulate_zero(h, count, offset): + "could not write zeroes offset %d size %d" % + (offset, count)) + ++ r.read() ++ + def trim(h, count, offset): + http = h['http'] + transfer = h['transfer'] +@@ -378,6 +387,8 @@ def trim(h, count, offset): + "could not trim sector offset %d size %d" % + (offset, count)) + ++ r.read() ++ + def flush(h): + http = h['http'] + transfer = h['transfer'] +@@ -394,6 +405,8 @@ def flush(h): + if r.status != 200: + request_failed(h, r, "could not flush") + ++ r.read() ++ + def delete_disk_on_failure(h): + disk_service = h['disk_service'] + disk_service.remove() +-- +2.17.1 + diff --git a/SOURCES/0060-rescue-docs-It-is-no-longer-necessary-to-mount-files.patch b/SOURCES/0060-rescue-docs-It-is-no-longer-necessary-to-mount-files.patch deleted file mode 100644 index 34c658e..0000000 --- a/SOURCES/0060-rescue-docs-It-is-no-longer-necessary-to-mount-files.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 71b79b9aa2bdfa9a39fa1d81ab2d59331c386039 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 24 Mar 2017 22:51:06 +0000 -Subject: [PATCH] rescue: docs: It is no longer necessary to mount filesystems - by hand. - -Fix the manual page to reflect the new -i option. - -Fixes commit 33d2ae796119ae5dd38e2afcbf1ba4216bd99846. - -(cherry picked from commit c38b48409e067ba973d02bb10273350aa31b558e) ---- - rescue/virt-rescue.pod | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/rescue/virt-rescue.pod b/rescue/virt-rescue.pod -index bd6f954e9..dfa74e204 100644 ---- a/rescue/virt-rescue.pod -+++ b/rescue/virt-rescue.pod -@@ -35,9 +35,9 @@ For live VMs you I use the I<--ro> option. - When you run virt-rescue on a virtual machine or disk image, you are - placed in an interactive bash shell where you can use many ordinary - Linux commands. What you see in F (F, F etc) is the --rescue appliance. You must mount the virtual machine's filesystems by --hand. There is an empty directory called F where you can --mount filesystems. -+rescue appliance. You must mount the virtual machine's filesystems. -+There is an empty directory called F where you can mount -+filesystems. - - To automatically mount the virtual machine's filesystems under - F use the I<-i> option. This uses libguestfs inspection to --- -2.14.3 - diff --git a/SOURCES/0060-v2v-rhv-upload-plugin-Fix-name-error.patch b/SOURCES/0060-v2v-rhv-upload-plugin-Fix-name-error.patch new file mode 100644 index 0000000..8c0722c --- /dev/null +++ b/SOURCES/0060-v2v-rhv-upload-plugin-Fix-name-error.patch @@ -0,0 +1,35 @@ +From 19d61962acdb3afa377631dc2d6658e8e73ac9ac Mon Sep 17 00:00:00 2001 +From: Nir Soffer +Date: Mon, 25 Jun 2018 20:56:52 +0300 +Subject: [PATCH] v2v: rhv-upload-plugin: Fix name error + +"http" and "transfer" variables were missing in emulate_zero, so the +code would fail with NameError. This can happen only when communicating +with old imageio versions not supporting the "zero" feature. + +Testing with qemu-img 2.12 show that we never send emulated zero request +because of the highestwrite mechanism, but it can break with older +qemu-img-rhev used on RHEL. + +(cherry picked from commit 0ae61ce99c351f9cda598016fb55ccc50313df67) +--- + v2v/rhv-upload-plugin.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 2eec375f7..10887c031 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -338,6 +338,9 @@ def zero(h, count, offset, may_trim): + r.read() + + def emulate_zero(h, count, offset): ++ http = h['http'] ++ transfer = h['transfer'] ++ + # qemu-img convert starts by trying to zero/trim the whole device. + # Since we've just created a new disk it's safe to ignore these + # requests as long as they are smaller than the highest write seen. +-- +2.17.1 + diff --git a/SOURCES/0061-rescue-docs-Note-that-you-can-run-virt-rescue-on-dis.patch b/SOURCES/0061-rescue-docs-Note-that-you-can-run-virt-rescue-on-dis.patch deleted file mode 100644 index bc9eddb..0000000 --- a/SOURCES/0061-rescue-docs-Note-that-you-can-run-virt-rescue-on-dis.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 2bcdb1d5a81d1591e7de4fa6f2333e99c02b3e5b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 24 Mar 2017 22:52:02 +0000 -Subject: [PATCH] rescue: docs: Note that you can run virt-rescue on disks too. - -(cherry picked from commit 267569f7ad22ad14d9ef4fa27b038469ae115c45) ---- - rescue/virt-rescue.pod | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/rescue/virt-rescue.pod b/rescue/virt-rescue.pod -index dfa74e204..5cfbd6e1c 100644 ---- a/rescue/virt-rescue.pod -+++ b/rescue/virt-rescue.pod -@@ -69,7 +69,8 @@ Virt-rescue can be used on I disk image file or device, not just - a virtual machine. For example you can use it on a blank file if you - want to partition that file (although we would recommend using - L instead as it is more suitable for this purpose). You --can even use virt-rescue on things like SD cards. -+can even use virt-rescue on things like USB drives, SD cards and hard -+disks. - - You can get virt-rescue to give you scratch disk(s) to play with. - This is useful for testing out Linux utilities (see I<--scratch>). --- -2.14.3 - diff --git a/SOURCES/0061-v2v-rhv-upload-plugin-Remove-unused-variables.patch b/SOURCES/0061-v2v-rhv-upload-plugin-Remove-unused-variables.patch new file mode 100644 index 0000000..fa8eacc --- /dev/null +++ b/SOURCES/0061-v2v-rhv-upload-plugin-Remove-unused-variables.patch @@ -0,0 +1,52 @@ +From eb3bcf3bcd791c1a9a8732dfb41514f33a1446d0 Mon Sep 17 00:00:00 2001 +From: Nir Soffer +Date: Tue, 26 Jun 2018 01:43:01 +0300 +Subject: [PATCH] v2v: rhv-upload-plugin: Remove unused variables + +Remove some instances of "transfer" and "transfer_service" that are not +used in current code. + +(cherry picked from commit 32ab53cecd78ee5c140f17e5792710698627d265) +--- + v2v/rhv-upload-plugin.py | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 10887c031..5c036c46a 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -263,7 +263,6 @@ def request_failed(h, r, msg): + def pread(h, count, offset): + http = h['http'] + transfer = h['transfer'] +- transfer_service = h['transfer_service'] + + headers = {"Range", "bytes=%d-%d" % (offset, offset+count-1)} + # Authorization is only needed for old imageio. +@@ -309,7 +308,6 @@ def pwrite(h, buf, offset): + + def zero(h, count, offset, may_trim): + http = h['http'] +- transfer = h['transfer'] + + # Unlike the trim and flush calls, there is no 'can_zero' method + # so nbdkit could call this even if the server doesn't support +@@ -371,7 +369,6 @@ def emulate_zero(h, count, offset): + + def trim(h, count, offset): + http = h['http'] +- transfer = h['transfer'] + + # Construct the JSON request for trimming. + buf = json.dumps({'op': "trim", +@@ -394,7 +391,6 @@ def trim(h, count, offset): + + def flush(h): + http = h['http'] +- transfer = h['transfer'] + + # Construct the JSON request for flushing. + buf = json.dumps({'op': "flush"}).encode() +-- +2.17.1 + diff --git a/SOURCES/0062-rescue-Don-t-document-suggest-option-in-help-output.patch b/SOURCES/0062-rescue-Don-t-document-suggest-option-in-help-output.patch deleted file mode 100644 index 099b02e..0000000 --- a/SOURCES/0062-rescue-Don-t-document-suggest-option-in-help-output.patch +++ /dev/null @@ -1,41 +0,0 @@ -From b8e5d0c7c03f7b96d6a60c505d227d9de3ba582d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 25 Mar 2017 23:34:09 +0000 -Subject: [PATCH] rescue: Don't document --suggest option in --help output. - -Also fix the docs test to ignore it. - -Updates/fixes commit 33d2ae796119ae5dd38e2afcbf1ba4216bd99846. - -(cherry picked from commit aa7b7e26c3aa434f2b299055df63c52fb3a2f93f) ---- - rescue/rescue.c | 1 - - rescue/test-virt-rescue-docs.sh | 3 ++- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/rescue/rescue.c b/rescue/rescue.c -index a1aac53e4..6f9dcd733 100644 ---- a/rescue/rescue.c -+++ b/rescue/rescue.c -@@ -101,7 +101,6 @@ usage (int status) - " --scratch[=N] Add scratch disk(s)\n" - " --selinux For backwards compat only, does nothing\n" - " --smp N Enable SMP with N >= 2 virtual CPUs\n" -- " --suggest Suggest mount commands for this guest\n" - " -v|--verbose Verbose messages\n" - " -V|--version Display version and exit\n" - " -w|--rw Mount read-write\n" -diff --git a/rescue/test-virt-rescue-docs.sh b/rescue/test-virt-rescue-docs.sh -index 25f8f6095..e5fbf26f4 100755 ---- a/rescue/test-virt-rescue-docs.sh -+++ b/rescue/test-virt-rescue-docs.sh -@@ -21,4 +21,5 @@ set -e - $TEST_FUNCTIONS - skip_if_skipped - --$top_srcdir/podcheck.pl virt-rescue.pod virt-rescue -+$top_srcdir/podcheck.pl virt-rescue.pod virt-rescue \ -+ --ignore=--suggest --- -2.14.3 - diff --git a/SOURCES/0062-v2v-o-rhv-upload-Always-fetch-server-options-when-op.patch b/SOURCES/0062-v2v-o-rhv-upload-Always-fetch-server-options-when-op.patch new file mode 100644 index 0000000..25ff19a --- /dev/null +++ b/SOURCES/0062-v2v-o-rhv-upload-Always-fetch-server-options-when-op.patch @@ -0,0 +1,122 @@ +From 376064fc32f0ccfea5c32ff5cd2fd844fc399ca6 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 19 Jun 2018 18:02:21 +0100 +Subject: [PATCH] v2v: -o rhv-upload: Always fetch server options when opening + the connection. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Previously we lazily requested the server options in the can_* +callbacks. The can_* callbacks are always called by nbdkit straight +after open, so this just adds complexity for no benefit. This change +simply makes the code always fetch the server options during the open +callback. + +This is — functionally at least — mostly just refactoring. However I +also added a useful debug message so we can see what features the +imageio server is offering. + +(cherry picked from commit a1e1f6ec887c2a7973612d2edf7066fd3194ba0b) +--- + v2v/rhv-upload-plugin.py | 63 +++++++++++++++++++--------------------- + 1 file changed, 30 insertions(+), 33 deletions(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 5c036c46a..f215eaecf 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -165,34 +165,13 @@ def open(readonly): + context = context + ) + +- # Save everything we need to make requests in the handle. +- return { +- 'can_flush': False, +- 'can_trim': False, +- 'can_zero': False, +- 'connection': connection, +- 'disk': disk, +- 'disk_service': disk_service, +- 'failed': False, +- 'got_options': False, +- 'highestwrite': 0, +- 'http': http, +- 'needs_auth': not params['rhv_direct'], +- 'path': destination_url.path, +- 'transfer': transfer, +- 'transfer_service': transfer_service, +- } ++ # The first request is to fetch the features of the server. ++ needs_auth = not params['rhv_direct'] ++ can_flush = False ++ can_trim = False ++ can_zero = False + +-# Can we issue zero, trim or flush requests? +-def get_options(h): +- if h['got_options']: +- return +- h['got_options'] = True +- +- http = h['http'] +- transfer = h['transfer'] +- +- http.putrequest("OPTIONS", h['path']) ++ http.putrequest("OPTIONS", destination_url.path) + http.putheader("Authorization", transfer.signed_ticket) + http.endheaders() + +@@ -201,12 +180,12 @@ def get_options(h): + + if r.status == 200: + # New imageio never needs authentication. +- h['needs_auth'] = False ++ needs_auth = False + + j = json.loads(data) +- h['can_zero'] = "zero" in j['features'] +- h['can_trim'] = "trim" in j['features'] +- h['can_flush'] = "flush" in j['features'] ++ can_flush = "flush" in j['features'] ++ can_trim = "trim" in j['features'] ++ can_zero = "zero" in j['features'] + + # Old imageio servers returned either 405 Method Not Allowed or + # 204 No Content (with an empty body). If we see that we leave +@@ -218,12 +197,30 @@ def get_options(h): + raise RuntimeError("could not use OPTIONS request: %d: %s" % + (r.status, r.reason)) + ++ debug("imageio features: flush=%r trim=%r zero=%r" % ++ (can_flush, can_trim, can_zero)) ++ ++ # Save everything we need to make requests in the handle. ++ return { ++ 'can_flush': can_flush, ++ 'can_trim': can_trim, ++ 'can_zero': can_zero, ++ 'connection': connection, ++ 'disk': disk, ++ 'disk_service': disk_service, ++ 'failed': False, ++ 'highestwrite': 0, ++ 'http': http, ++ 'needs_auth': needs_auth, ++ 'path': destination_url.path, ++ 'transfer': transfer, ++ 'transfer_service': transfer_service, ++ } ++ + def can_trim(h): +- get_options(h) + return h['can_trim'] + + def can_flush(h): +- get_options(h) + return h['can_flush'] + + def get_size(h): +-- +2.17.1 + diff --git a/SOURCES/0063-v2v-bootloaders-search-grub-config-for-all-distribut.patch b/SOURCES/0063-v2v-bootloaders-search-grub-config-for-all-distribut.patch deleted file mode 100644 index 22dfee6..0000000 --- a/SOURCES/0063-v2v-bootloaders-search-grub-config-for-all-distribut.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 54c42d18d82ae4c5c0562600b47a7710a583ea07 Mon Sep 17 00:00:00 2001 -From: Pavel Butsykin -Date: Tue, 2 May 2017 15:35:06 +0300 -Subject: [PATCH] v2v: bootloaders: search grub config for all distributions - -This patch improves the search of grub config on EFI partition. This -means that the config will be found not only for rhel but also for -many other distributions. Tests were performed on the following -distributions: centos, fedora, ubuntu, suse. In all cases, the config -path was /boot/efi/EFI/*distname*/grub.cfg - -The main purpose of the patch is to improve support for converting of -vm with UEFI for most distributions. Unfortunately this patch does not -solve the problem for all distributions, for example Debian does not -store grub config on the EFI partition, therefore for such -distributions another solution is necessary. - -Signed-off-by: Pavel Butsykin -(cherry picked from commit a76e9040b20f97eb5c9accbefcbf55999554dc48) ---- - v2v/linux_bootloaders.ml | 76 ++++++++++++++++++++++++++++++------------------ - 1 file changed, 48 insertions(+), 28 deletions(-) - -diff --git a/v2v/linux_bootloaders.ml b/v2v/linux_bootloaders.ml -index c3fd09ca8..25dab02fe 100644 ---- a/v2v/linux_bootloaders.ml -+++ b/v2v/linux_bootloaders.ml -@@ -49,6 +49,13 @@ let remove_hd_prefix path = - - (* Grub1 (AKA grub-legacy) representation. *) - class bootloader_grub1 (g : G.guestfs) inspect grub_config = -+ let () = -+ (* Apply the "grub" lens if it is not handling the file -+ * already -- Augeas < 1.7.0 will error out otherwise. -+ *) -+ if g#aug_ls ("/files" ^ grub_config) = [||] then -+ g#aug_transform "grub" grub_config in -+ - (* Grub prefix? Usually "/boot". *) - let grub_prefix = - let mounts = g#inspect_get_mountpoints inspect.i_root in -@@ -345,33 +352,46 @@ object (self) - end - - let detect_bootloader (g : G.guestfs) inspect = -- let config_file, typ = -- let locations = [ -- "/boot/grub2/grub.cfg", Grub2; -- "/boot/grub/grub.cfg", Grub2; -- "/boot/grub/menu.lst", Grub1; -- "/boot/grub/grub.conf", Grub1; -- ] in -- let locations = -- match inspect.i_firmware with -- | I_UEFI _ -> -- [ -- "/boot/efi/EFI/redhat/grub.cfg", Grub2; -- "/boot/efi/EFI/redhat/grub.conf", Grub1; -- ] @ locations -- | I_BIOS -> locations in -- try -- List.find ( -- fun (config_file, _) -> g#is_file ~followsymlinks:true config_file -- ) locations -- with -- Not_found -> -- error (f_"no bootloader detected") in -+ (* Where to start searching for bootloaders. *) -+ let mp = -+ match inspect.i_firmware with -+ | I_BIOS -> "/boot" -+ | I_UEFI _ -> "/boot/efi/EFI" in - -- match typ with -- | Grub1 -> -- if config_file = "/boot/efi/EFI/redhat/grub.conf" then -- g#aug_transform "grub" "/boot/efi/EFI/redhat/grub.conf"; -+ (* Find all paths below the mountpoint, then filter them to find -+ * the grub config file. -+ *) -+ let paths = -+ try List.map ((^) mp) (Array.to_list (g#find mp)) -+ with G.Error msg -> -+ error (f_"could not find bootloader mount point (%s): %s") mp msg in - -- new bootloader_grub1 g inspect config_file -- | Grub2 -> new bootloader_grub2 g config_file -+ (* We can determine if the bootloader config file is grub 1 or -+ * grub 2 just by looking at the filename. -+ *) -+ let bootloader_type_of_filename path = -+ match last_part_of path '/' with -+ | Some "grub.cfg" -> Some Grub2 -+ | Some ("grub.conf" | "menu.lst") -> Some Grub1 -+ | Some _ -+ | None -> None -+ in -+ -+ let grub_config, typ = -+ let rec loop = function -+ | [] -> error (f_"no bootloader detected") -+ | path :: paths -> -+ match bootloader_type_of_filename path with -+ | None -> loop paths -+ | Some typ -> -+ if not (g#is_file ~followsymlinks:true path) then loop paths -+ else path, typ -+ in -+ loop paths in -+ -+ let bl = -+ (match typ with -+ | Grub1 -> new bootloader_grub1 g inspect grub_config -+ | Grub2 -> new bootloader_grub2 g grub_config) in -+ debug "detected bootloader %s at %s" bl#name grub_config; -+ bl --- -2.14.3 - diff --git a/SOURCES/0063-v2v-o-rhv-upload-Use-Unix-domain-socket-to-access-im.patch b/SOURCES/0063-v2v-o-rhv-upload-Use-Unix-domain-socket-to-access-im.patch new file mode 100644 index 0000000..d2e083c --- /dev/null +++ b/SOURCES/0063-v2v-o-rhv-upload-Use-Unix-domain-socket-to-access-im.patch @@ -0,0 +1,141 @@ +From c9f230d57b10e776c490b2cc92212c2a3304bd4e Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 18 Jun 2018 15:34:37 +0100 +Subject: [PATCH] v2v: -o rhv-upload: Use Unix domain socket to access imageio + (RHBZ#1588088). + +In the case where virt-v2v runs on the same server as the imageio +daemon that we are talking to, it may be possible to optimize access +using a Unix domain socket. + +This is only an optimization. If it fails or if we're not running on +the same server it will fall back to the usual HTTPS over TCP +connection. + +Thanks: Nir Soffer, Daniel Erez. +(cherry picked from commit b7a2e6270d53200d2df471c36a1fb2b46db8bbac) +--- + v2v/rhv-upload-plugin.py | 61 ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 58 insertions(+), 3 deletions(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index f215eaecf..8805e3552 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -19,11 +19,12 @@ + import builtins + import json + import logging ++import socket + import ssl + import sys + import time + +-from http.client import HTTPSConnection ++from http.client import HTTPSConnection, HTTPConnection + from urllib.parse import urlparse + + import ovirtsdk4 as sdk +@@ -56,6 +57,28 @@ def debug(s): + print(s, file=sys.stderr) + sys.stderr.flush() + ++def find_host(connection): ++ """Return the current host object or None.""" ++ try: ++ with builtins.open("/etc/vdsm/vdsm.id") as f: ++ vdsm_id = f.readline().strip() ++ except Exception as e: ++ return None ++ debug("hw_id = %r" % vdsm_id) ++ ++ hosts_service = connection.system_service().hosts_service() ++ hosts = hosts_service.list( ++ search="hw_id=%s" % vdsm_id, ++ case_sensitive=False, ++ ) ++ if len(hosts) == 0: ++ return None ++ ++ host = hosts[0] ++ debug("host.id = %r" % host.id) ++ ++ return types.Host(id = host.id) ++ + def open(readonly): + # Parse out the username from the output_conn URL. + parsed = urlparse(params['output_conn']) +@@ -121,9 +144,11 @@ def open(readonly): + transfers_service = system_service.image_transfers_service() + + # Create a new image transfer. ++ host = find_host(connection) + transfer = transfers_service.add( + types.ImageTransfer( + disk = types.Disk(id = disk.id), ++ host = host, + inactivity_timeout = 3600, + ) + ) +@@ -170,6 +195,7 @@ def open(readonly): + can_flush = False + can_trim = False + can_zero = False ++ unix_socket = None + + http.putrequest("OPTIONS", destination_url.path) + http.putheader("Authorization", transfer.signed_ticket) +@@ -186,6 +212,7 @@ def open(readonly): + can_flush = "flush" in j['features'] + can_trim = "trim" in j['features'] + can_zero = "zero" in j['features'] ++ unix_socket = j.get('unix_socket') + + # Old imageio servers returned either 405 Method Not Allowed or + # 204 No Content (with an empty body). If we see that we leave +@@ -197,8 +224,17 @@ def open(readonly): + raise RuntimeError("could not use OPTIONS request: %d: %s" % + (r.status, r.reason)) + +- debug("imageio features: flush=%r trim=%r zero=%r" % +- (can_flush, can_trim, can_zero)) ++ debug("imageio features: flush=%r trim=%r zero=%r unix_socket=%r" % ++ (can_flush, can_trim, can_zero, unix_socket)) ++ ++ # If we are connected to imageio on the local host and the ++ # transfer features a unix_socket then we can reconnect to that. ++ if host is not None and unix_socket is not None: ++ try: ++ http = UnixHTTPConnection(unix_socket) ++ debug("optimizing connection using unix socket %r" % unix_socket) ++ except: ++ pass + + # Save everything we need to make requests in the handle. + return { +@@ -463,3 +499,22 @@ def close(h): + raise + + connection.close() ++ ++# Modify http.client.HTTPConnection to work over a Unix domain socket. ++# Derived from uhttplib written by Erik van Zijst under an MIT license. ++# (https://pypi.org/project/uhttplib/) ++# Ported to Python 3 by Irit Goihman. ++ ++class UnsupportedError(Exception): ++ pass ++ ++class UnixHTTPConnection(HTTPConnection): ++ def __init__(self, path, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): ++ self.path = path ++ HTTPConnection.__init__(self, "localhost", timeout=timeout) ++ ++ def connect(self): ++ self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) ++ if self.timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: ++ self.sock.settimeout(timeout) ++ self.sock.connect(self.path) +-- +2.17.1 + diff --git a/SOURCES/0064-rescue-fix-size-check.patch b/SOURCES/0064-rescue-fix-size-check.patch deleted file mode 100644 index 94e3233..0000000 --- a/SOURCES/0064-rescue-fix-size-check.patch +++ /dev/null @@ -1,30 +0,0 @@ -From ab6cefa227e23008eda69f8e7390d2eaed376d5c Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Mon, 23 Oct 2017 17:42:03 +0200 -Subject: [PATCH] rescue: fix size check - -Compare it to the right variable, not to the pointer itself. - -Fixes commit 3637c42f4e521eb647d7dfae7f48eb1689d0af54. - -(cherry picked from commit 0998e3f1cdf9eb441ea1f45e45860feac47fccd8) ---- - rescue/escape.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/rescue/escape.c b/rescue/escape.c -index f7f7d84c4..d6dc9d329 100644 ---- a/rescue/escape.c -+++ b/rescue/escape.c -@@ -49,7 +49,7 @@ parse_escape_key (const char *arg) - return 0; - - len = strlen (arg); -- if (arg == 0) -+ if (len == 0) - return -1; - - switch (arg[0]) { --- -2.14.3 - diff --git a/SOURCES/0064-v2v-improve-os-documentation-for-rhv-upload.patch b/SOURCES/0064-v2v-improve-os-documentation-for-rhv-upload.patch new file mode 100644 index 0000000..a2d4fc3 --- /dev/null +++ b/SOURCES/0064-v2v-improve-os-documentation-for-rhv-upload.patch @@ -0,0 +1,29 @@ +From 6c8bf7005f36665c018d9fa9b17aeea4c09397c0 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 29 Jun 2018 12:58:33 +0200 +Subject: [PATCH] v2v: improve -os documentation for rhv-upload + +Thanks to: Ming Xie + +(cherry picked from commit 8d33ff8ba415180dee8f1f91f3b4d16d72ec094e) +--- + v2v/virt-v2v.pod | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 806225be0..90443373f 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -631,6 +631,9 @@ For I<-o libvirt>, this is a libvirt directory pool + For I<-o local> and I<-o qemu>, this is a directory name. The + directory must exist. + ++For I<-o rhv-upload>, this is the name of the destination Storage ++Domain. ++ + For I<-o rhv>, this can be an NFS path of the Export Storage Domain + of the form ChostE:EpathE>, eg: + +-- +2.17.1 + diff --git a/SOURCES/0065-rescue-initialize-CLEANUP-pointer-variable.patch b/SOURCES/0065-rescue-initialize-CLEANUP-pointer-variable.patch deleted file mode 100644 index 2d24a3e..0000000 --- a/SOURCES/0065-rescue-initialize-CLEANUP-pointer-variable.patch +++ /dev/null @@ -1,31 +0,0 @@ -From d4d3e90ad9c9e144171ece825f60cb804449f835 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Mon, 23 Oct 2017 17:44:23 +0200 -Subject: [PATCH] rescue: initialize CLEANUP pointer variable - -This way it will not try to free uninitialized memory when going out of -scope, and the inspector mode is not enabled. - -Fixes commit 3637c42f4e521eb647d7dfae7f48eb1689d0af54. - -(cherry picked from commit 0942241395b7faf02fd651a0d7b99628458febe4) ---- - rescue/escape.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/rescue/escape.c b/rescue/escape.c -index d6dc9d329..ae4919f69 100644 ---- a/rescue/escape.c -+++ b/rescue/escape.c -@@ -236,7 +236,7 @@ print_help (void) - static void - print_inspector (void) - { -- CLEANUP_FREE_STRING_LIST char **roots; -+ CLEANUP_FREE_STRING_LIST char **roots = NULL; - size_t i; - const char *root; - char *str; --- -2.14.3 - diff --git a/SOURCES/0065-v2v-rhv-upload-plugin-Remove-unneeded-auth.patch b/SOURCES/0065-v2v-rhv-upload-plugin-Remove-unneeded-auth.patch new file mode 100644 index 0000000..d8a7631 --- /dev/null +++ b/SOURCES/0065-v2v-rhv-upload-plugin-Remove-unneeded-auth.patch @@ -0,0 +1,69 @@ +From 2b4bacf2efa04c18a6ab576e30594a8742e45bf7 Mon Sep 17 00:00:00 2001 +From: Nir Soffer +Date: Fri, 29 Jun 2018 17:41:10 +0300 +Subject: [PATCH] v2v: rhv-upload-plugin: Remove unneeded auth + +Old imageio proxy was using Authorization header for GET and PUT +requests. Remove unneeded authorization when sending OPTIONS request. + +Remove unneeded duplicated comments about authorization for old +imageio, and replace them with a comment when we set needs_auth. + +(cherry picked from commit d5f36bacf9bb6d4d244184551792989906f60896) +--- + v2v/rhv-upload-plugin.py | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 8805e3552..f404bd758 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -191,16 +191,17 @@ def open(readonly): + ) + + # The first request is to fetch the features of the server. ++ ++ # Authentication was needed only for GET and PUT requests when ++ # communicating with old imageio-proxy. + needs_auth = not params['rhv_direct'] ++ + can_flush = False + can_trim = False + can_zero = False + unix_socket = None + +- http.putrequest("OPTIONS", destination_url.path) +- http.putheader("Authorization", transfer.signed_ticket) +- http.endheaders() +- ++ http.request("OPTIONS", destination_url.path) + r = http.getresponse() + data = r.read() + +@@ -298,7 +299,6 @@ def pread(h, count, offset): + transfer = h['transfer'] + + headers = {"Range", "bytes=%d-%d" % (offset, offset+count-1)} +- # Authorization is only needed for old imageio. + if h['needs_auth']: + headers["Authorization"] = transfer.signed_ticket + +@@ -321,7 +321,6 @@ def pwrite(h, buf, offset): + h['highestwrite'] = max(h['highestwrite'], offset+count) + + http.putrequest("PUT", h['path'] + "?flush=n") +- # Authorization is only needed for old imageio. + if h['needs_auth']: + http.putheader("Authorization", transfer.signed_ticket) + # The oVirt server only uses the first part of the range, and the +@@ -378,7 +377,6 @@ def emulate_zero(h, count, offset): + # After that we must emulate them with writes. + if offset+count < h['highestwrite']: + http.putrequest("PUT", h['path']) +- # Authorization is only needed for old imageio. + if h['needs_auth']: + http.putheader("Authorization", transfer.signed_ticket) + http.putheader("Content-Range", +-- +2.17.1 + diff --git a/SOURCES/0066-v2v-i-ova-parse-MAC-address-from-rasd-Address-RHBZ-1.patch b/SOURCES/0066-v2v-i-ova-parse-MAC-address-from-rasd-Address-RHBZ-1.patch deleted file mode 100644 index d1dc45f..0000000 --- a/SOURCES/0066-v2v-i-ova-parse-MAC-address-from-rasd-Address-RHBZ-1.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0ce5239605cf455e4891224b6594f33f24b7bd9a Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Thu, 2 Nov 2017 11:13:42 +0100 -Subject: [PATCH] v2v: -i ova: parse MAC address from - (RHBZ#1506572) - -Read the MAC address of the network interfaces from the -tag of the OVF. This seems to be one of the possible ways used in OVFs. - -(cherry picked from commit a1b008e2d138a90cbf2147d69d5d2d4d745b03cd) ---- - v2v/parse_ovf_from_ova.ml | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/v2v/parse_ovf_from_ova.ml b/v2v/parse_ovf_from_ova.ml -index 989483e2e..dba0ce585 100644 ---- a/v2v/parse_ovf_from_ova.ml -+++ b/v2v/parse_ovf_from_ova.ml -@@ -211,8 +211,9 @@ let parse_ovf_from_ova ovf_filename = - Xml.xpathctx_set_current_context xpathctx n; - let vnet = - xpath_string_default "rasd:ElementName/text()" (sprintf"eth%d" i) in -+ let mac = xpath_string "rasd:Address/text()" in - let nic = { -- s_mac = None; -+ s_mac = mac; - s_nic_model = None; - s_vnet = vnet; - s_vnet_orig = vnet; --- -2.14.3 - diff --git a/SOURCES/0066-v2v-rhv-upload-plugin-Improve-error-handling.patch b/SOURCES/0066-v2v-rhv-upload-plugin-Improve-error-handling.patch new file mode 100644 index 0000000..4bfbf37 --- /dev/null +++ b/SOURCES/0066-v2v-rhv-upload-plugin-Improve-error-handling.patch @@ -0,0 +1,66 @@ +From 7ed4c98bd7ee8148ce48b0fbc2af3a64de1aaae9 Mon Sep 17 00:00:00 2001 +From: Nir Soffer +Date: Sat, 30 Jun 2018 01:21:50 +0300 +Subject: [PATCH] v2v: rhv-upload-plugin: Improve error handling + +When optimizing the connection using unix socket, we handle these cases: + +- The local host is not an oVirt host (no /etc/vdsm/vdsm.id). +- The local host is an oVirt host, but is not registered with engine. +- Creating UnixHTTPConnection() fails. Unlikely and probably a bug in + the plugin, but we can recover by using the https connection. + +The current code handle these cases silently, making it harder to +understand why the unix socket optimization did no happen. Add debug +message to make this clear. + +Also comment in the error handler why we take this path instead of +failing the operation. + +(cherry picked from commit f5442d2f044b398efc992fb4d56c8d3096c781e6) +--- + v2v/rhv-upload-plugin.py | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index f404bd758..8e4052048 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -63,7 +63,10 @@ def find_host(connection): + with builtins.open("/etc/vdsm/vdsm.id") as f: + vdsm_id = f.readline().strip() + except Exception as e: ++ # This is most likely not an oVirt host. ++ debug("cannot read /etc/vdsm/vdsm.id, using any host: %s" % e) + return None ++ + debug("hw_id = %r" % vdsm_id) + + hosts_service = connection.system_service().hosts_service() +@@ -72,6 +75,8 @@ def find_host(connection): + case_sensitive=False, + ) + if len(hosts) == 0: ++ # This oVirt host is not registered with engine. ++ debug("cannot find host with hw_id=%r, using any host" % vdsm_id) + return None + + host = hosts[0] +@@ -233,9 +238,12 @@ def open(readonly): + if host is not None and unix_socket is not None: + try: + http = UnixHTTPConnection(unix_socket) ++ except Exception as e: ++ # Very unlikely failure, but we can recover by using the https ++ # connection. ++ debug("cannot create unix socket connection, using https: %s" % e) ++ else: + debug("optimizing connection using unix socket %r" % unix_socket) +- except: +- pass + + # Save everything we need to make requests in the handle. + return { +-- +2.17.1 + diff --git a/SOURCES/0067-v2v-Fix-RPM-file-owned-test-RHBZ-1503958.patch b/SOURCES/0067-v2v-Fix-RPM-file-owned-test-RHBZ-1503958.patch deleted file mode 100644 index 7a63e5e..0000000 --- a/SOURCES/0067-v2v-Fix-RPM-file-owned-test-RHBZ-1503958.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 35372c4b210bc49969bf96e7a17897ec29ba4625 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 19 Oct 2017 12:05:43 +0100 -Subject: [PATCH] v2v: Fix RPM file owned test (RHBZ#1503958). - -Linux.file_owner is not used by any other function, so remove it. - -Linux.is_file_owned is only used when removing kmod-xenpv on old RHEL -releases, and so is only required to work for RPM. - -The old file_owner/is_file_owned functions were completely broken for -the RPM case. This replaces them with a simpler, working -implementation of is_file_owned only. - -Thanks: Ming Xie for finding and reporting the original bug. -(cherry picked from commit e6bc59a7d46707f5037afc8a73206d2773c3fccd) ---- - v2v/linux.ml | 61 ++++++++++++++++++++++++++--------------------------------- - v2v/linux.mli | 3 --- - 2 files changed, 27 insertions(+), 37 deletions(-) - -diff --git a/v2v/linux.ml b/v2v/linux.ml -index fad9b0c61..11b0e2cbf 100644 ---- a/v2v/linux.ml -+++ b/v2v/linux.ml -@@ -98,7 +98,7 @@ let file_list_of_package (g : Guestfs.guestfs) inspect app = - error (f_"don't know how to get list of files from package using %s") - format - --let rec file_owner (g : G.guestfs) { i_package_format = package_format } path = -+let is_file_owned (g : G.guestfs) { i_package_format = package_format } path = - match package_format with - | "deb" -> - (* With dpkg usually the directories are owned by all the packages -@@ -108,48 +108,41 @@ let rec file_owner (g : G.guestfs) { i_package_format = package_format } path = - *) - let cmd = [| "dpkg"; "-S"; path |] in - debug "%s" (String.concat " " (Array.to_list cmd)); -- let lines = -- try g#command_lines cmd -- with Guestfs.Error msg as exn -> -- if String.find msg "no path found matching pattern" >= 0 then -- raise Not_found -- else -- raise exn in -- if Array.length lines = 0 then -- error (f_"internal error: file_owner: dpkg command returned no output"); -- let line = lines.(0) in -- let line = -- try String.sub line 0 (String.rindex line ':') -- with Invalid_argument _ -> -- error (f_"internal error: file_owner: invalid dpkg output: '%s'") -- line in -- fst (String.split "," line) -- -- | "rpm" -> -- (* Although it is possible in RPM for multiple packages to own -- * a file, this deliberately only returns one package. -- *) -- let cmd = [| "rpm"; "-qf"; "--qf"; "%{NAME}\\n"; path |] in -- debug "%s" (String.concat " " (Array.to_list cmd)); - (try -- let pkgs = g#command_lines cmd in -- pkgs.(0) -+ let lines = g#command_lines cmd in -+ if Array.length lines = 0 then -+ error (f_"internal error: is_file_owned: dpkg command returned no output"); -+ (* Just check the output looks something like "pkg: filename". *) -+ if String.find lines.(0) ": " >= 0 then -+ true -+ else -+ error (f_"internal error: is_file_owned: unexpected output from dpkg command: %s") -+ lines.(0) - with Guestfs.Error msg as exn -> -- if String.find msg "is not owned" >= 0 then -- raise Not_found -+ if String.find msg "no path found matching pattern" >= 0 then -+ false - else - raise exn -- | Invalid_argument _ (* pkgs.(0) raises index out of bounds *) -> -- error (f_"internal error: file_owner: rpm command returned no output") - ) - -+ | "rpm" -> -+ (* Run rpm -qf and print a magic string if the file is owned. -+ * If not owned, rpm will print "... is not owned by any package" -+ * and exit with an error. Unfortunately the string is sent to -+ * stdout, so here we ignore the exit status of rpm and just -+ * look for one of the two strings. -+ *) -+ let magic = "FILE_OWNED_TEST" in -+ let cmd = sprintf "rpm -qf --qf %s %s 2>&1 ||:" -+ (quote (magic ^ "\n")) (quote path) in -+ let r = g#sh cmd in -+ if String.find r magic >= 0 then true -+ else if String.find r "is not owned" >= 0 then false -+ else failwithf "RPM file owned test failed: %s" r -+ - | format -> - error (f_"don't know how to find file owner using %s") format - --and is_file_owned g inspect path = -- try ignore (file_owner g inspect path); true -- with Not_found -> false -- - let is_package_manager_save_file filename = - (* Recognized suffixes of package managers. *) - let suffixes = [ ".dpkg-old"; ".dpkg-new"; ".rpmsave"; ".rpmnew"; ] in -diff --git a/v2v/linux.mli b/v2v/linux.mli -index 705073644..08146a460 100644 ---- a/v2v/linux.mli -+++ b/v2v/linux.mli -@@ -29,9 +29,6 @@ val remove : Guestfs.guestfs -> Types.inspect -> string list -> unit - val file_list_of_package : Guestfs.guestfs -> Types.inspect -> Guestfs.application2 -> string list - (** Return list of files owned by package. *) - --val file_owner : Guestfs.guestfs -> Types.inspect -> string -> string --(** Return the name of the package that owns a file. *) -- - val is_file_owned : Guestfs.guestfs -> Types.inspect -> string -> bool - (** Returns true if the file is owned by an installed package. *) - --- -2.14.3 - diff --git a/SOURCES/0067-v2v-rhv-upload-plugin-Optimize-only-direct-upload.patch b/SOURCES/0067-v2v-rhv-upload-plugin-Optimize-only-direct-upload.patch new file mode 100644 index 0000000..ba88395 --- /dev/null +++ b/SOURCES/0067-v2v-rhv-upload-plugin-Optimize-only-direct-upload.patch @@ -0,0 +1,32 @@ +From f1e11ab12c7e51f648a5efe056cf4ba9be4d9afa Mon Sep 17 00:00:00 2001 +From: Nir Soffer +Date: Sat, 30 Jun 2018 01:39:03 +0300 +Subject: [PATCH] v2v: rhv-upload-plugin: Optimize only direct upload + +The optimization to start the transfer on the local host makes sense +only when using the rhv-direct=true option. When using a proxy, let the +engine choose a host. + +(cherry picked from commit 891b5a0ec0f320acec0f06b64159eaf3dfbbfeaf) +--- + v2v/rhv-upload-plugin.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 8e4052048..da309e288 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -148,8 +148,8 @@ def open(readonly): + # Get a reference to the transfer service. + transfers_service = system_service.image_transfers_service() + +- # Create a new image transfer. +- host = find_host(connection) ++ # Create a new image transfer, using the local host is possible. ++ host = find_host(connection) if params['rhv_direct'] else None + transfer = transfers_service.add( + types.ImageTransfer( + disk = types.Disk(id = disk.id), +-- +2.17.1 + diff --git a/SOURCES/0068-v2v-bootloaders-handle-no-default-grubby-kernel-RHBZ.patch b/SOURCES/0068-v2v-bootloaders-handle-no-default-grubby-kernel-RHBZ.patch deleted file mode 100644 index 28de6f3..0000000 --- a/SOURCES/0068-v2v-bootloaders-handle-no-default-grubby-kernel-RHBZ.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 67b740a77543bc0f0c6b4d0f52c8855b8705822b Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Fri, 1 Dec 2017 14:46:13 +0100 -Subject: [PATCH] v2v: bootloaders: handle no default grubby kernel - (RHBZ#1519204) - -When using grubby to get the default kernel of a guest, do not fail -with a bogus error like: - -virt-v2v: error: libguestfs error: statns: statns_stub: path must start -with a / character - -in case there is no default kernel that can be determined (e.g. because -of a bogus configuration). ---- - v2v/linux_bootloaders.ml | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/v2v/linux_bootloaders.ml b/v2v/linux_bootloaders.ml -index 25dab02fe..e241d93c2 100644 ---- a/v2v/linux_bootloaders.ml -+++ b/v2v/linux_bootloaders.ml -@@ -281,7 +281,10 @@ object (self) - let res = - match get_default_method with - | MethodGrubby -> -- Some (g#command [| "grubby"; "--default-kernel" |]) -+ let res = g#command [| "grubby"; "--default-kernel" |] in -+ (match res with -+ | "" -> None -+ | _ -> Some res) - | MethodPerlBootloader -> - let cmd = - [| "/usr/bin/perl"; "-MBootloader::Tools"; "-e"; " --- -2.14.3 - diff --git a/SOURCES/0068-v2v-rhv-plugin-find-suitable-host-RHBZ-1596810-RHBZ-.patch b/SOURCES/0068-v2v-rhv-plugin-find-suitable-host-RHBZ-1596810-RHBZ-.patch new file mode 100644 index 0000000..23aeab2 --- /dev/null +++ b/SOURCES/0068-v2v-rhv-plugin-find-suitable-host-RHBZ-1596810-RHBZ-.patch @@ -0,0 +1,61 @@ +From 39b3bdb8f3a430ac585ed75fa85f51bacebdf22e Mon Sep 17 00:00:00 2001 +From: Daniel Erez +Date: Thu, 5 Jul 2018 20:23:35 +0300 +Subject: [PATCH] v2v: rhv plugin - find suitable host (RHBZ#1596810) + (RHBZ#1596851) + +For direct upload, a suitable host must be in status 'Up' +and belong to the same datacenter as the created disk. +Added these criteria to the host search query. + +(cherry picked from commit 4ed1bc5a79a77ad3a620b339f9ac2ecc8df6fd03) +--- + v2v/rhv-upload-plugin.py | 28 ++++++++++++++++++++++++---- + 1 file changed, 24 insertions(+), 4 deletions(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index da309e288..931fcfaa2 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -69,14 +69,34 @@ def find_host(connection): + + debug("hw_id = %r" % vdsm_id) + +- hosts_service = connection.system_service().hosts_service() ++ system_service = connection.system_service() ++ storage_name = params['output_storage'] ++ data_centers = system_service.data_centers_service().list( ++ search='storage=%s' % storage_name, ++ case_sensitive=False, ++ ) ++ if len(data_centers) == 0: ++ # The storage domain is not attached to a datacenter ++ # (shouldn't happen, would fail on disk creation). ++ debug("storange domain (%s) is not attached to a DC" % storage_name) ++ return None ++ ++ datacenter = data_centers[0] ++ debug("datacenter = %s" % datacenter.name) ++ ++ hosts_service = system_service.hosts_service() + hosts = hosts_service.list( +- search="hw_id=%s" % vdsm_id, ++ search="hw_id=%s and datacenter=%s and status=Up" % (vdsm_id, datacenter.name), + case_sensitive=False, + ) + if len(hosts) == 0: +- # This oVirt host is not registered with engine. +- debug("cannot find host with hw_id=%r, using any host" % vdsm_id) ++ # Couldn't find a host that's fulfilling the following criteria: ++ # - 'hw_id' equals to 'vdsm_id' ++ # - Its status is 'Up' ++ # - Belongs to the storage domain's datacenter ++ debug("cannot find a running host with hw_id=%r, " \ ++ "that belongs to datacenter '%s', " \ ++ "using any host" % (vdsm_id, datacenter.name)) + return None + + host = hosts[0] +-- +2.17.1 + diff --git a/SOURCES/0069-lib-libvirt-stop-using-shareable-for-appliance-disk-.patch b/SOURCES/0069-lib-libvirt-stop-using-shareable-for-appliance-disk-.patch deleted file mode 100644 index b39b9fe..0000000 --- a/SOURCES/0069-lib-libvirt-stop-using-shareable-for-appliance-disk-.patch +++ /dev/null @@ -1,47 +0,0 @@ -From db196dc098d213638d7513bb98a72d1778658299 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Tue, 5 Dec 2017 15:36:34 +0100 -Subject: [PATCH] lib: libvirt: stop using for appliance disk - (RHBZ#1518517) - -Commit aa9e0057b19e29f76c9a81f9aebeeb1cb5bf1fdb made the libvirt backend -use for the disk of the appliance, since at that time all -the instances were using the disk directly. -OTOH, commit 3ad44c866042919374e2d840502e53da2ed8aef0 switched to -overlays for read-only disks, including the appliance, so effectively -protecting the appliance. - -Because of this, the libvirt backend does not need anymore. - -Thanks to: Daniel Berrange, Richard W.M. Jones, Peter Krempa. ---- - lib/launch-libvirt.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c -index d10c7cb40..05c398ba0 100644 ---- a/lib/launch-libvirt.c -+++ b/lib/launch-libvirt.c -@@ -969,10 +969,6 @@ static int construct_libvirt_xml_appliance (guestfs_h *g, const struct libvirt_x - } \ - } while (0) - --/* */ --#define empty_element(element) \ -- do { start_element(element) {} end_element (); } while (0) -- - /* key=value attribute of the current element. */ - #define attribute(key,value) \ - if (xmlTextWriterWriteAttribute (xo, BAD_CAST (key), BAD_CAST (value)) == -1){ \ -@@ -1758,8 +1754,6 @@ construct_libvirt_xml_appliance (guestfs_h *g, - == -1) - return -1; - -- empty_element ("shareable"); -- - } end_element (); - - return 0; --- -2.14.3 - diff --git a/SOURCES/0069-v2v-change-QXL-ResourceType-in-OVirt-flavour-RHBZ-15.patch b/SOURCES/0069-v2v-change-QXL-ResourceType-in-OVirt-flavour-RHBZ-15.patch new file mode 100644 index 0000000..e451aa2 --- /dev/null +++ b/SOURCES/0069-v2v-change-QXL-ResourceType-in-OVirt-flavour-RHBZ-15.patch @@ -0,0 +1,41 @@ +From 21e2f8ea59a87da9daee239cea26873b51ad2f79 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 13 Jul 2018 13:24:07 +0200 +Subject: [PATCH] v2v: change QXL ResourceType in OVirt flavour (RHBZ#1598715) + +Due to a conflict with the IDs of the OVF standard, and the existing +implementation in ovirt-engine, the ID of QXL devices changed to a +different value. + +As a consequence, change the ResourceType of QXL devices, but only in +OVirt flavour to avoid breaking vdsm mode. + +See: https://bugzilla.redhat.com/show_bug.cgi?id=1598715#c5 +(cherry picked from commit aa9e18f6d1fd503822dfd2124b92a2c67704c4c1) +--- + v2v/create_ovf.ml | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml +index 9e0c772fd..5db239d66 100644 +--- a/v2v/create_ovf.ml ++++ b/v2v/create_ovf.ml +@@ -643,10 +643,14 @@ let rec create_ovf source targets guestcaps inspect + * See RHBZ#1213701 and RHBZ#1211231 for the reasoning + * behind that. + *) ++ let qxl_resourcetype = ++ match ovf_flavour with ++ | OVirt -> 32768 (* RHBZ#1598715 *) ++ | RHVExportStorageDomain -> 20 in + e "Item" [] [ + e "rasd:Caption" [] [PCData "Graphical Controller"]; + e "rasd:InstanceId" [] [PCData (uuidgen ())]; +- e "rasd:ResourceType" [] [PCData "20"]; ++ e "rasd:ResourceType" [] [PCData (string_of_int qxl_resourcetype)]; + e "Type" [] [PCData "video"]; + e "rasd:VirtualQuantity" [] [PCData "1"]; + e "rasd:Device" [] [PCData "qxl"]; +-- +2.17.1 + diff --git a/SOURCES/0070-v2v-o-rhv-upload-check-for-ovirtsdk4-RHBZ-1601943.patch b/SOURCES/0070-v2v-o-rhv-upload-check-for-ovirtsdk4-RHBZ-1601943.patch new file mode 100644 index 0000000..fac79b2 --- /dev/null +++ b/SOURCES/0070-v2v-o-rhv-upload-check-for-ovirtsdk4-RHBZ-1601943.patch @@ -0,0 +1,40 @@ +From ab8aa6d4b208130ecf290698e2285055df8f5190 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Tue, 17 Jul 2018 17:12:38 +0200 +Subject: [PATCH] v2v: -o rhv-upload: check for ovirtsdk4 (RHBZ#1601943) + +Check earlier whether the ovirtsdk4 Python can be imported correctly, +to avoid errors later on during the migration. +--- + v2v/output_rhv_upload.ml | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml +index 0152b8d5a..63fa2411a 100644 +--- a/v2v/output_rhv_upload.ml ++++ b/v2v/output_rhv_upload.ml +@@ -126,6 +126,13 @@ class output_rhv_upload output_alloc output_conn + python3 + in + ++ (* Check that the 'ovirtsdk4' Python module is available. *) ++ let error_unless_ovirtsdk4_module_available () = ++ let res = run_command [ python3; "-c"; "import ovirtsdk4" ] in ++ if res <> 0 then ++ error (f_"the Python module ‘ovirtsdk4’ could not be loaded, is it installed? See previous messages for problems.") ++ in ++ + (* Check that nbdkit is available and new enough. *) + let error_unless_nbdkit_working () = + if 0 <> Sys.command "nbdkit --version >/dev/null" then +@@ -231,6 +238,7 @@ object + + method precheck () = + error_unless_python_binary_on_path (); ++ error_unless_ovirtsdk4_module_available (); + error_unless_nbdkit_working (); + error_unless_nbdkit_python3_working (); + error_unless_output_alloc_sparse (); +-- +2.17.1 + diff --git a/SOURCES/0070-v2v-vddk-Make-it-clearer-that-you-should-not-run-nbd.patch b/SOURCES/0070-v2v-vddk-Make-it-clearer-that-you-should-not-run-nbd.patch deleted file mode 100644 index edc2498..0000000 --- a/SOURCES/0070-v2v-vddk-Make-it-clearer-that-you-should-not-run-nbd.patch +++ /dev/null @@ -1,35 +0,0 @@ -From be3d03e538592cff01d3e3693ada6e973df55abd Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 16 Oct 2017 10:06:54 +0100 -Subject: [PATCH] v2v: vddk: Make it clearer that you should not run nbdkit - 'make install'. - -(cherry picked from commit d81a2ee185599c23a128ab65be9d48b415abf461) ---- - v2v/virt-v2v.pod | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 92ed147d7..4f7ea8da6 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -1322,11 +1322,12 @@ L - - =item 3. - --You can run nbdkit from its source directory without needing to --install it. Set C<$PATH> to include the nbdkit top build directory --(the directory containing a shell script called F): -+You do B need to run C. You can run nbdkit from -+its source directory. Set C<$PATH> to point to the nbdkit top build -+directory (that is, the directory containing a shell script called -+F), eg: - -- export PATH=/path/to/nbdkit:$PATH -+ export PATH=/path/to/nbdkit-1.1.x:$PATH - - =item 4. - --- -2.14.3 - diff --git a/SOURCES/0071-podwrapper-nbdkit-man-pages-are-libguestfs-man-pages.patch b/SOURCES/0071-podwrapper-nbdkit-man-pages-are-libguestfs-man-pages.patch deleted file mode 100644 index dac42e3..0000000 --- a/SOURCES/0071-podwrapper-nbdkit-man-pages-are-libguestfs-man-pages.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 6b6ab3bf31cbca8e4920315bbd46badf6d532529 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 7 Nov 2017 10:03:54 +0000 -Subject: [PATCH] podwrapper: nbdkit-* man pages are libguestfs man pages. - -Don't use the external link for these. - -Thanks: Ming Xie. -(cherry picked from commit 441fa82ee0d878ed63b1c213d8197c1f0ffde2a0) ---- - podwrapper.pl.in | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/podwrapper.pl.in b/podwrapper.pl.in -index 619d3af2b..9b90d0faa 100755 ---- a/podwrapper.pl.in -+++ b/podwrapper.pl.in -@@ -552,6 +552,7 @@ SUBHTML: { - return 1 if /^guestunmount/; - return 1 if /^hivex/; - return 1 if /^supermin/; -+ return 1 if /^nbdkit/; - return 0; - } - --- -2.14.3 - diff --git a/SOURCES/0071-v2v-rhv-plugin-fix-DC-search-string.patch b/SOURCES/0071-v2v-rhv-plugin-fix-DC-search-string.patch new file mode 100644 index 0000000..e4dda6c --- /dev/null +++ b/SOURCES/0071-v2v-rhv-plugin-fix-DC-search-string.patch @@ -0,0 +1,29 @@ +From f28a96fadc0997687deaa01652ad80b37b08d657 Mon Sep 17 00:00:00 2001 +From: Daniel Erez +Date: Tue, 24 Jul 2018 19:16:10 +0300 +Subject: [PATCH] v2v: rhv plugin - fix DC search string + +Search for DC by 'storage.name=' to make it explicit. +I.e. "storage=" uses regex, so similar names can be +found in the search query. For example, searching for +a domain named FCSD, will find FCSD1 as well. +--- + v2v/rhv-upload-plugin.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 931fcfaa2..8274f1ee1 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -72,7 +72,7 @@ def find_host(connection): + system_service = connection.system_service() + storage_name = params['output_storage'] + data_centers = system_service.data_centers_service().list( +- search='storage=%s' % storage_name, ++ search='storage.name=%s' % storage_name, + case_sensitive=False, + ) + if len(data_centers) == 0: +-- +2.17.1 + diff --git a/SOURCES/0072-v2v-rhv-plugin-case-sensitive-search-queries.patch b/SOURCES/0072-v2v-rhv-plugin-case-sensitive-search-queries.patch new file mode 100644 index 0000000..e13c586 --- /dev/null +++ b/SOURCES/0072-v2v-rhv-plugin-case-sensitive-search-queries.patch @@ -0,0 +1,35 @@ +From d3c135201889d1e66208126b56cc5317295f3093 Mon Sep 17 00:00:00 2001 +From: Daniel Erez +Date: Wed, 25 Jul 2018 11:24:33 +0300 +Subject: [PATCH] v2v: rhv plugin - case-sensitive search queries + +Changed both search queries to case-sensitive (to ensure an exact match). +--- + v2v/rhv-upload-plugin.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 8274f1ee1..4fad27fb8 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -73,7 +73,7 @@ def find_host(connection): + storage_name = params['output_storage'] + data_centers = system_service.data_centers_service().list( + search='storage.name=%s' % storage_name, +- case_sensitive=False, ++ case_sensitive=True, + ) + if len(data_centers) == 0: + # The storage domain is not attached to a datacenter +@@ -87,7 +87,7 @@ def find_host(connection): + hosts_service = system_service.hosts_service() + hosts = hosts_service.list( + search="hw_id=%s and datacenter=%s and status=Up" % (vdsm_id, datacenter.name), +- case_sensitive=False, ++ case_sensitive=True, + ) + if len(hosts) == 0: + # Couldn't find a host that's fulfilling the following criteria: +-- +2.17.1 + diff --git a/SOURCES/0072-v2v-vddk-Update-minimum-version-of-nbdkit-to-1.1.16.patch b/SOURCES/0072-v2v-vddk-Update-minimum-version-of-nbdkit-to-1.1.16.patch deleted file mode 100644 index dbeaedb..0000000 --- a/SOURCES/0072-v2v-vddk-Update-minimum-version-of-nbdkit-to-1.1.16.patch +++ /dev/null @@ -1,56 +0,0 @@ -From f49162600c5ed54341ebeba9bc773fefc6b8153d Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 7 Nov 2017 10:07:03 +0000 -Subject: [PATCH] v2v: vddk: Update minimum version of nbdkit to 1.1.16. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -While 1.1.14 will technically still work, 1.1.16 adds the -‘selinux=yes|no’ flag to ‘--dump-config’ output. It's also the more -widely available and tested version at the time of writing. - -Thanks: Ming Xie. -(cherry picked from commit 415e9d82e901647438f68e4748720d88153778aa) ---- - v2v/input_libvirt_vddk.ml | 5 +++-- - v2v/virt-v2v.pod | 2 +- - 2 files changed, 4 insertions(+), 3 deletions(-) - -diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml -index 33b34bd2e..d1f2ae360 100644 ---- a/v2v/input_libvirt_vddk.ml -+++ b/v2v/input_libvirt_vddk.ml -@@ -61,13 +61,14 @@ class input_libvirt_vddk vddk_options password libvirt_uri parsed_uri guest = - - (* Check it's a new enough version. The latest features we - * require are ‘--exit-with-parent’ and ‘--selinux-label’, both -- * added in 1.1.14. -+ * added in 1.1.14. (We use 1.1.16 as the minimum here because -+ * it also adds the selinux=yes|no flag in --dump-config). - *) - let lines = external_command "nbdkit --help" in - let lines = String.concat " " lines in - if String.find lines "exit-with-parent" == -1 || - String.find lines "selinux-label" == -1 then -- error (f_"nbdkit is not new enough, you need to upgrade to nbdkit ≥ 1.1.14") -+ error (f_"nbdkit is not new enough, you need to upgrade to nbdkit ≥ 1.1.16") - in - - (* Check that the VDDK plugin is installed and working *) -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 4f7ea8da6..48a20cccc 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -1305,7 +1305,7 @@ library is permitted by the license. - =item 2. - - You must also compile nbdkit, enabling the VDDK plugin. At least --nbdkit E 1.1.14 is required, but it is usually best to compile -+nbdkit E 1.1.16 is required, but it is usually best to compile - from the git tree. - - =over 4 --- -2.14.3 - diff --git a/SOURCES/0073-Revert-lvm-do-not-pass-cache-to-vgscan.patch b/SOURCES/0073-Revert-lvm-do-not-pass-cache-to-vgscan.patch new file mode 100644 index 0000000..d9d6024 --- /dev/null +++ b/SOURCES/0073-Revert-lvm-do-not-pass-cache-to-vgscan.patch @@ -0,0 +1,40 @@ +From d30cda40ffce15c28e316ec86c342a60881ae30f Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 25 Jul 2018 12:39:02 +0100 +Subject: [PATCH] Revert "lvm: do not pass --cache to vgscan" + +This reverts commit 19b0ae6c6502c4833c73e1b1bfa47b43a40f21e9. +--- + daemon/lvm-filter.c | 2 +- + daemon/lvm.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/daemon/lvm-filter.c b/daemon/lvm-filter.c +index 9d877c104..c6dd35156 100644 +--- a/daemon/lvm-filter.c ++++ b/daemon/lvm-filter.c +@@ -147,7 +147,7 @@ rescan (void) + unlink (lvm_cache); + + CLEANUP_FREE char *err = NULL; +- int r = command (NULL, &err, "lvm", "vgscan", NULL); ++ int r = command (NULL, &err, "lvm", "vgscan", "--cache", NULL); + if (r == -1) { + reply_with_error ("vgscan: %s", err); + return -1; +diff --git a/daemon/lvm.c b/daemon/lvm.c +index 877bc5f6c..709a1e73b 100644 +--- a/daemon/lvm.c ++++ b/daemon/lvm.c +@@ -642,7 +642,7 @@ do_vgscan (void) + int r; + + r = command (NULL, &err, +- "lvm", "vgscan", NULL); ++ "lvm", "vgscan", "--cache", NULL); + if (r == -1) { + reply_with_error ("%s", err); + return -1; +-- +2.17.1 + diff --git a/SOURCES/0073-v2v-vddk-Further-rework-documentation.patch b/SOURCES/0073-v2v-vddk-Further-rework-documentation.patch deleted file mode 100644 index 731cdb8..0000000 --- a/SOURCES/0073-v2v-vddk-Further-rework-documentation.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 9e64238a389264b34af20b49da929d5bf6ccd436 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 7 Nov 2017 11:32:16 +0000 -Subject: [PATCH] v2v: vddk: Further rework documentation. - -Thanks for suggestions from Ming Xie. - -(cherry picked from commit 12d87361a4623587c53196e70157448158c02c7f) ---- - v2v/virt-v2v.pod | 18 ++++++++++++------ - 1 file changed, 12 insertions(+), 6 deletions(-) - -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 48a20cccc..417c25331 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -1304,6 +1304,10 @@ library is permitted by the license. - - =item 2. - -+VDDK E 6.5 is required. -+ -+=item 3. -+ - You must also compile nbdkit, enabling the VDDK plugin. At least - nbdkit E 1.1.16 is required, but it is usually best to compile - from the git tree. -@@ -1320,12 +1324,14 @@ L - - =back - --=item 3. -+Compile nbdkit as described in the sources (see link above). - --You do B need to run C. You can run nbdkit from --its source directory. Set C<$PATH> to point to the nbdkit top build --directory (that is, the directory containing a shell script called --F), eg: -+You do B need to run C because you can run nbdkit -+from its source directory. The source directory has a shell script -+called F which runs the locally built copy of nbdkit and its -+plugins. So set C<$PATH> to point to the nbdkit top build directory -+(that is, the directory containing the shell script called F), -+eg: - - export PATH=/path/to/nbdkit-1.1.x:$PATH - -@@ -1333,7 +1339,7 @@ F), eg: - - You must find the SSL "thumbprint" of your VMware server. How to do - this is explained in L, also available at the --link given in item 2 above. -+link above. - - =item 5. - --- -2.14.3 - diff --git a/SOURCES/0074-daemon-inspect-ignore-fstab-devs-that-cannot-be-reso.patch b/SOURCES/0074-daemon-inspect-ignore-fstab-devs-that-cannot-be-reso.patch new file mode 100644 index 0000000..e6143bd --- /dev/null +++ b/SOURCES/0074-daemon-inspect-ignore-fstab-devs-that-cannot-be-reso.patch @@ -0,0 +1,46 @@ +From adae4d57b007b99cb246c3a3e8b02189b19ce2c4 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Fri, 27 Jul 2018 12:10:38 +0200 +Subject: [PATCH] daemon: inspect: ignore fstab devs that cannot be resolved + (RHBZ#1608131) + +If the /etc/fstab of a guest contains devices specified with UUID or +LABEL, then the new OCaml inspection code will report the findfs failure +as general failure of the inspection. OTOH, the old C inspection code +simply ignored all the devices that cannot be resolved. + +Hence, restore the old behaviour by ignoring unresolvable devices. +--- + daemon/inspect_fs_unix_fstab.ml | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/daemon/inspect_fs_unix_fstab.ml b/daemon/inspect_fs_unix_fstab.ml +index edb797e3f..170440d2c 100644 +--- a/daemon/inspect_fs_unix_fstab.ml ++++ b/daemon/inspect_fs_unix_fstab.ml +@@ -115,12 +115,20 @@ and check_fstab_entry md_map root_mountable os_type aug entry = + if String.is_prefix spec "UUID=" then ( + let uuid = String.sub spec 5 (String.length spec - 5) in + let uuid = shell_unquote uuid in +- Mountable.of_device (Findfs.findfs_uuid uuid) ++ (* Just ignore the device if the UUID cannot be resolved. *) ++ try ++ Mountable.of_device (Findfs.findfs_uuid uuid) ++ with ++ Failure _ -> return None + ) + else if String.is_prefix spec "LABEL=" then ( + let label = String.sub spec 6 (String.length spec - 6) in + let label = shell_unquote label in +- Mountable.of_device (Findfs.findfs_label label) ++ (* Just ignore the device if the label cannot be resolved. *) ++ try ++ Mountable.of_device (Findfs.findfs_label label) ++ with ++ Failure _ -> return None + ) + (* Resolve /dev/root to the current device. + * Do the same for the / partition of the *BSD +-- +2.17.1 + diff --git a/SOURCES/0074-v2v-docs-Remove-min-version-of-VDDK-recommend-nbdkit.patch b/SOURCES/0074-v2v-docs-Remove-min-version-of-VDDK-recommend-nbdkit.patch deleted file mode 100644 index 1fae654..0000000 --- a/SOURCES/0074-v2v-docs-Remove-min-version-of-VDDK-recommend-nbdkit.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 5b64c3085942856f520823c12c871a4d96b75e35 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 6 Dec 2017 15:48:50 +0000 -Subject: [PATCH] v2v: docs: Remove min version of VDDK, recommend nbdkit >= - 1.1.25 (RHBZ#1513884). - -Requires -> recommends because older versions of nbdkit will likely -work also. - -See also: -https://bugzilla.redhat.com/show_bug.cgi?id=1513884#c3 - -(cherry picked from commit 5ac24b490ebcf2e16e4ee2284a7f59bcc47cc808) ---- - v2v/virt-v2v.pod | 14 +++++--------- - 1 file changed, 5 insertions(+), 9 deletions(-) - -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 417c25331..13f021c6d 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -1304,13 +1304,9 @@ library is permitted by the license. - - =item 2. - --VDDK E 6.5 is required. -- --=item 3. -- --You must also compile nbdkit, enabling the VDDK plugin. At least --nbdkit E 1.1.16 is required, but it is usually best to compile --from the git tree. -+You must also compile nbdkit, enabling the VDDK plugin. nbdkit E -+1.1.25 is recommended, but it is usually best to compile from the git -+tree. - - =over 4 - -@@ -1335,13 +1331,13 @@ eg: - - export PATH=/path/to/nbdkit-1.1.x:$PATH - --=item 4. -+=item 3. - - You must find the SSL "thumbprint" of your VMware server. How to do - this is explained in L, also available at the - link above. - --=item 5. -+=item 4. - - VDDK imports require a feature added in libvirt E 3.7. - --- -2.14.3 - diff --git a/SOURCES/0075-v2v-docs-State-that-vddk-thumbprint-is-only-required.patch b/SOURCES/0075-v2v-docs-State-that-vddk-thumbprint-is-only-required.patch deleted file mode 100644 index 3cd9e53..0000000 --- a/SOURCES/0075-v2v-docs-State-that-vddk-thumbprint-is-only-required.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 8e556500316c8e53993f50fe9ecb56d9524f5cab Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 6 Dec 2017 15:53:41 +0000 -Subject: [PATCH] v2v: docs: State that --vddk-thumbprint is only required if - --vddk present (RHBZ#1513884). - -Thanks: Ming Xie, Pino Toscano. - -See also: -https://bugzilla.redhat.com/show_bug.cgi?id=1513884#c2 - -(cherry picked from commit 4b43697f9bc9b0fa33e26fbc2fce136ebaa89005) ---- - v2v/virt-v2v.pod | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 13f021c6d..e798ad1e7 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -528,7 +528,8 @@ See L below for details. - - When using VDDK mode, these options are passed unmodified to the - L VDDK plugin. Please refer to L. --Only I<--vddk-thumbprint> is required, the others are optional. -+If I<--vddk> is present, I<--vddk-thumbprint> is also required, -+the rest are optional. - - =item B<--vdsm-compat=0.10> - --- -2.14.3 - diff --git a/SOURCES/0075-v2v-parse_libvirt_xml-handle-srN-CDROM-devices-RHBZ-.patch b/SOURCES/0075-v2v-parse_libvirt_xml-handle-srN-CDROM-devices-RHBZ-.patch new file mode 100644 index 0000000..6786acc --- /dev/null +++ b/SOURCES/0075-v2v-parse_libvirt_xml-handle-srN-CDROM-devices-RHBZ-.patch @@ -0,0 +1,36 @@ +From 0b6ae16f01aaa1a6d5ba9f240e131c688c7224ca Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Thu, 9 Aug 2018 15:01:37 +0200 +Subject: [PATCH] v2v: parse_libvirt_xml: handle srN CDROM devices + (RHBZ#1612785) + +This device naming is mostly written by virt-p2v, so get the slot from +it directly without using the drive_index "decoding" function. +--- + v2v/parse_libvirt_xml.ml | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/v2v/parse_libvirt_xml.ml b/v2v/parse_libvirt_xml.ml +index 57e741574..4912f1cc0 100644 +--- a/v2v/parse_libvirt_xml.ml ++++ b/v2v/parse_libvirt_xml.ml +@@ -385,6 +385,16 @@ let parse_libvirt_xml ?conn xml = + let target_dev = xpath_string "target/@dev" in + match target_dev with + | None -> None ++ | Some dev when String.is_prefix dev "sr" -> ++ (* "srN" devices are found mostly in the physical XML written by ++ * virt-p2v. ++ *) ++ let name = String.sub dev 2 (String.length dev - 2) in ++ (try Some (int_of_string name) ++ with Failure _ -> ++ warning (f_"could not parse device name ‘%s’ from the source libvirt XML") dev; ++ None ++ ) + | Some dev -> + let rec loop = function + | [] -> +-- +2.17.1 + diff --git a/SOURCES/0076-v2v-o-rhv-upload-Fix-error-message-disk-numbering-RH.patch b/SOURCES/0076-v2v-o-rhv-upload-Fix-error-message-disk-numbering-RH.patch new file mode 100644 index 0000000..0a9c2e0 --- /dev/null +++ b/SOURCES/0076-v2v-o-rhv-upload-Fix-error-message-disk-numbering-RH.patch @@ -0,0 +1,42 @@ +From 21a58c8f5f0d4386b5a3c444883d87ccf92b15b5 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 14 Aug 2018 12:50:07 +0100 +Subject: [PATCH] v2v: -o rhv-upload: Fix error message disk numbering + (RHBZ#1615885). + +The output method used the s_disk_id field assuming it was a unique, +monotonically increasing number counting from 0. However this is not +the case, the input method simply has to set s_disk_id to be unique +for each disk. + +Fixes commit cc04573927cca97de60d544d37467e67c25867a7. + +Thanks: Xiaodai Wang +--- + v2v/output_rhv_upload.ml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml +index 63fa2411a..7dbd98a0d 100644 +--- a/v2v/output_rhv_upload.ml ++++ b/v2v/output_rhv_upload.ml +@@ -383,13 +383,13 @@ If the messages above are not sufficient to diagnose the problem then add the + *) + let nr_disks = List.length targets in + let image_uuids = +- List.map ( +- fun t -> ++ List.mapi ( ++ fun i t -> + let id = t.target_overlay.ov_source.s_disk_id in + let diskid_file = diskid_file_of_id id in + if not (wait_for_file diskid_file finalization_timeout) then + error (f_"transfer of disk %d/%d failed, see earlier error messages") +- (id+1) nr_disks; ++ (i+1) nr_disks; + let diskid = read_whole_file diskid_file in + diskid + ) targets in +-- +2.17.1 + diff --git a/SOURCES/0076-v2v-vddk-Switch-to-using-it-vddk-to-specify-VDDK-as-.patch b/SOURCES/0076-v2v-vddk-Switch-to-using-it-vddk-to-specify-VDDK-as-.patch deleted file mode 100644 index a437475..0000000 --- a/SOURCES/0076-v2v-vddk-Switch-to-using-it-vddk-to-specify-VDDK-as-.patch +++ /dev/null @@ -1,518 +0,0 @@ -From f8209cc000c28648efd4d73eeeec7bac3dd7c1dd Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 7 Dec 2017 14:41:32 +0000 -Subject: [PATCH] =?UTF-8?q?v2v:=20vddk:=20Switch=20to=20using=20=E2=80=98-?= - =?UTF-8?q?it=20vddk=E2=80=99=20to=20specify=20VDDK=20as=20input=20transpo?= - =?UTF-8?q?rt.?= -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Previously the presence of the ‘--vddk ’ option magically -enabled VDDK mode. However we want to introduce other transports for -VMware conversions so this wasn't a very clean choice. - -With this commit you must use ‘-it vddk’ to specify that you want VDDK -as a disk transport. The previous ‘--vddk ’ option has been -renamed to ‘--vddk-libdir ’ to be consistent with the other -passthrough options, and it is no longer required. - -A new command line looks like: - - $ export PATH=/path/to/nbdkit:$PATH - $ virt-v2v \ - -ic 'vpx://root@vcenter.example.com/Datacenter/esxi?no_verify=1' \ -| -it vddk \ -| --vddk-libdir /path/to/vmware-vix-disklib-distrib \ - --vddk-thumbprint xx:xx:xx:... \ - "Windows 2003" \ - -o local -os /var/tmp - -where only the two lines marked with ‘|’ have changed. - -(cherry picked from commit 6f347b4f802717d4557fdae90c90afa030b8a414) ---- - v2v/cmdline.ml | 69 +++++++++++++++++++++++++++++------------------ - v2v/input_libvirt.ml | 37 ++++++++++++------------- - v2v/input_libvirt.mli | 8 +++--- - v2v/input_libvirt_vddk.ml | 61 ++++++++++++++++++++++++++++------------- - v2v/test-v2v-docs.sh | 2 +- - v2v/types.ml | 2 +- - v2v/types.mli | 2 +- - v2v/virt-v2v.pod | 30 +++++++++++++++------ - 8 files changed, 131 insertions(+), 80 deletions(-) - -diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml -index dfbb776ab..81562d1f5 100644 ---- a/v2v/cmdline.ml -+++ b/v2v/cmdline.ml -@@ -56,15 +56,16 @@ let parse_cmdline () = - - let input_conn = ref None in - let input_format = ref None in -+ let input_transport = ref None in - let in_place = ref false in - let output_conn = ref None in - let output_format = ref None in - let output_name = ref None in - let output_storage = ref None in - let password_file = ref None in -- let vddk = ref None in - let vddk_config = ref None in - let vddk_cookie = ref None in -+ let vddk_libdir = ref None in - let vddk_nfchostport = ref None in - let vddk_port = ref None in - let vddk_snapshot = ref None in -@@ -186,6 +187,8 @@ let parse_cmdline () = - s_"Libvirt URI"; - [ M"if" ], Getopt.String ("format", set_string_option_once "-if" input_format), - s_"Input format (for -i disk)"; -+ [ M"it" ], Getopt.String ("transport", set_string_option_once "-it" input_transport), -+ s_"Input transport"; - [ L"in-place" ], Getopt.Set in_place, ""; - [ L"machine-readable" ], Getopt.Set machine_readable, s_"Make output machine readable"; - [ S 'n'; L"network" ], Getopt.String ("in:out", add_network), s_"Map network 'in' to 'out'"; -@@ -207,12 +210,12 @@ let parse_cmdline () = - s_"Use password from file"; - [ L"print-source" ], Getopt.Set print_source, s_"Print source and stop"; - [ L"root" ], Getopt.String ("ask|... ", set_root_choice), s_"How to choose root filesystem"; -- [ L"vddk" ], Getopt.String ("libpath", set_string_option_once "--vddk" vddk), -- s_"Use nbdkit VDDK plugin"; - [ L"vddk-config" ], Getopt.String ("filename", set_string_option_once "--vddk-config" vddk_config), - s_"Set VDDK config file"; - [ L"vddk-cookie" ], Getopt.String ("cookie", set_string_option_once "--vddk-cookie" vddk_cookie), - s_"Set VDDK cookie"; -+ [ L"vddk-libdir" ], Getopt.String ("libdir", set_string_option_once "--vddk-libdir" vddk_libdir), -+ s_"Set VDDK library parent directory"; - [ L"vddk-nfchostport" ], Getopt.String ("nfchostport", set_string_option_once "--vddk-nfchostport" vddk_nfchostport), - s_"Set VDDK nfchostport"; - [ L"vddk-port" ], Getopt.String ("port", set_string_option_once "--vddk-port" vddk_port), -@@ -270,6 +273,12 @@ read the man page virt-v2v(1). - let input_conn = !input_conn in - let input_format = !input_format in - let input_mode = !input_mode in -+ let input_transport = -+ match !input_transport with -+ | None -> None -+ | Some "vddk" -> Some `VDDK -+ | Some transport -> -+ error (f_"unknown input transport ‘-it %s’") transport in - let in_place = !in_place in - let machine_readable = !machine_readable in - let network_map = !network_map in -@@ -287,28 +296,15 @@ read the man page virt-v2v(1). - let qemu_boot = !qemu_boot in - let root_choice = !root_choice in - let vddk_options = -- match !vddk with -- | Some libdir -> -- Some { vddk_libdir = libdir; -- vddk_config = !vddk_config; -- vddk_cookie = !vddk_cookie; -- vddk_nfchostport = !vddk_nfchostport; -- vddk_port = !vddk_port; -- vddk_snapshot = !vddk_snapshot; -- vddk_thumbprint = !vddk_thumbprint; -- vddk_transports = !vddk_transports; -- vddk_vimapiver = !vddk_vimapiver } -- | None -> -- if !vddk_config <> None || -- !vddk_cookie <> None || -- !vddk_nfchostport <> None || -- !vddk_port <> None || -- !vddk_snapshot <> None || -- !vddk_thumbprint <> None || -- !vddk_transports <> None || -- !vddk_vimapiver <> None then -- error (f_"‘--vddk-*’ options should only be used when conversion via the nbdkit VDDK plugin has been enabled, ie. using ‘--vddk’."); -- None in -+ { vddk_config = !vddk_config; -+ vddk_cookie = !vddk_cookie; -+ vddk_libdir = !vddk_libdir; -+ vddk_nfchostport = !vddk_nfchostport; -+ vddk_port = !vddk_port; -+ vddk_snapshot = !vddk_snapshot; -+ vddk_thumbprint = !vddk_thumbprint; -+ vddk_transports = !vddk_transports; -+ vddk_vimapiver = !vddk_vimapiver } in - let vdsm_compat = !vdsm_compat in - let vdsm_image_uuids = List.rev !vdsm_image_uuids in - let vdsm_vol_uuids = List.rev !vdsm_vol_uuids in -@@ -341,6 +337,26 @@ read the man page virt-v2v(1). - let password = read_first_line_from_file filename in - Some password in - -+ (* Input transport affects whether some parameters should or -+ * should not be used. -+ *) -+ (match input_transport with -+ | None -> -+ if !vddk_config <> None || -+ !vddk_cookie <> None || -+ !vddk_libdir <> None || -+ !vddk_nfchostport <> None || -+ !vddk_port <> None || -+ !vddk_snapshot <> None || -+ !vddk_thumbprint <> None || -+ !vddk_transports <> None || -+ !vddk_vimapiver <> None then -+ error (f_"‘--vddk-*’ options should only be used when conversion via the nbdkit VDDK plugin has been enabled, ie. using ‘-it vddk’.") -+ | Some `VDDK -> -+ if !vddk_thumbprint = None then -+ error (f_"‘--vddk-thumbprint’ is required when using ‘-it vddk’.") -+ ); -+ - (* Parsing of the argument(s) depends on the input mode. *) - let input = - match input_mode with -@@ -363,7 +379,8 @@ read the man page virt-v2v(1). - | [guest] -> guest - | _ -> - error (f_"expecting a libvirt guest name on the command line") in -- Input_libvirt.input_libvirt vddk_options password input_conn guest -+ Input_libvirt.input_libvirt vddk_options password -+ input_conn input_transport guest - - | `LibvirtXML -> - (* -i libvirtxml: Expecting a filename (XML file). *) -diff --git a/v2v/input_libvirt.ml b/v2v/input_libvirt.ml -index f4a8114f0..16006dc0c 100644 ---- a/v2v/input_libvirt.ml -+++ b/v2v/input_libvirt.ml -@@ -27,7 +27,7 @@ open Types - open Utils - - (* Choose the right subclass based on the URI. *) --let input_libvirt vddk_options password libvirt_uri guest = -+let input_libvirt vddk_options password libvirt_uri input_transport guest = - match libvirt_uri with - | None -> - Input_libvirt_other.input_libvirt_other password libvirt_uri guest -@@ -39,29 +39,26 @@ let input_libvirt vddk_options password libvirt_uri guest = - error (f_"could not parse '-ic %s'. Original error message was: %s") - orig_uri msg in - -- match server, scheme with -- | None, _ -- | Some "", _ (* Not a remote URI. *) -+ match server, scheme, input_transport with -+ | None, _, _ -+ | Some "", _, _ (* Not a remote URI. *) - -- | Some _, None (* No scheme? *) -- | Some _, Some "" -> -+ | Some _, None, _ (* No scheme? *) -+ | Some _, Some "", _ -> - Input_libvirt_other.input_libvirt_other password libvirt_uri guest - -- (* vCenter over https, or -- * vCenter or ESXi using nbdkit vddk plugin -- *) -- | Some server, Some ("esx"|"gsx"|"vpx" as scheme) -> -- (match vddk_options with -- | None -> -- Input_libvirt_vcenter_https.input_libvirt_vcenter_https -- password libvirt_uri parsed_uri scheme server guest -- | Some vddk_options -> -- Input_libvirt_vddk.input_libvirt_vddk vddk_options password -- libvirt_uri parsed_uri guest -- ) -+ (* vCenter over https. *) -+ | Some server, Some ("esx"|"gsx"|"vpx" as scheme), None -> -+ Input_libvirt_vcenter_https.input_libvirt_vcenter_https -+ password libvirt_uri parsed_uri scheme server guest -+ -+ (* vCenter or ESXi using nbdkit vddk plugin *) -+ | Some server, Some ("esx"|"gsx"|"vpx"), Some `VDDK -> -+ Input_libvirt_vddk.input_libvirt_vddk vddk_options password -+ libvirt_uri parsed_uri guest - - (* Xen over SSH *) -- | Some server, Some ("xen+ssh" as scheme) -> -+ | Some server, Some ("xen+ssh" as scheme), _ -> - Input_libvirt_xen_ssh.input_libvirt_xen_ssh - password libvirt_uri parsed_uri scheme server guest - -@@ -71,7 +68,7 @@ let input_libvirt vddk_options password libvirt_uri guest = - *) - - (* Unknown remote scheme. *) -- | Some _, Some _ -> -+ | 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 password libvirt_uri guest -diff --git a/v2v/input_libvirt.mli b/v2v/input_libvirt.mli -index acf2ca417..eb3e48397 100644 ---- a/v2v/input_libvirt.mli -+++ b/v2v/input_libvirt.mli -@@ -18,7 +18,7 @@ - - (** [-i libvirt] source. *) - --val input_libvirt : Types.vddk_options option -> string option -> string option -> string -> Types.input --(** [input_libvirt vddk_options password libvirt_uri guest] creates -- and returns a new {!Types.input} object specialized for reading input -- from libvirt sources. *) -+val input_libvirt : Types.vddk_options -> string option -> string option -> [`VDDK] option -> string -> Types.input -+(** [input_libvirt vddk_options password libvirt_uri input_transport guest] -+ creates and returns a new {!Types.input} object specialized for reading -+ input from libvirt sources. *) -diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml -index d1f2ae360..2f2ac4214 100644 ---- a/v2v/input_libvirt_vddk.ml -+++ b/v2v/input_libvirt_vddk.ml -@@ -34,11 +34,19 @@ open Printf - - (* Subclass specialized for handling VMware via nbdkit vddk plugin. *) - class input_libvirt_vddk vddk_options password libvirt_uri parsed_uri guest = -- - (* The VDDK path. *) - let libdir = vddk_options.vddk_libdir in -- (* Compute the LD_LIBRARY_PATH that we must pass to nbdkit. *) -- let library_path = libdir // sprintf "lib%d" Sys.word_size in -+ -+ (* VDDK libraries are located under lib32/ or lib64/ relative to the -+ * libdir. Note this is unrelated to Linux multilib or multiarch. -+ *) -+ let libNN = sprintf "lib%d" Sys.word_size in -+ -+ (* Compute the LD_LIBRARY_PATH that we may have to pass to nbdkit. *) -+ let library_path = -+ match libdir with -+ | None -> None -+ | Some libdir -> Some (libdir // libNN) in - - (* Is SELinux enabled and enforcing on the host? *) - let have_selinux = -@@ -46,18 +54,25 @@ class input_libvirt_vddk vddk_options password libvirt_uri parsed_uri guest = - - (* Check that the VDDK path looks reasonable. *) - let error_unless_vddk_libdir () = -- if not (is_directory libdir) then -- error (f_"‘--vddk %s’ does not point to a directory. See \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") libdir; -+ (match libdir with -+ | None -> () -+ | Some libdir -> -+ if not (is_directory libdir) then -+ error (f_"‘--vddk-libdir %s’ does not point to a directory. See \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") libdir -+ ); - -- if not (is_directory library_path) then -- error (f_"VDDK library path %s not found or not a directory. See \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") -- library_path -+ (match library_path with -+ | None -> () -+ | Some library_path -> -+ if not (is_directory library_path) then -+ error (f_"VDDK library path %s not found or not a directory. See \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") library_path -+ ) - in - - (* Check that nbdkit is available and new enough. *) - let error_unless_nbdkit_working () = - if 0 <> Sys.command "nbdkit --version >/dev/null" then -- error (f_"nbdkit is not installed or not working. It is required to use ‘--vddk’. See \"INPUT FROM VDDK\" in the virt-v2v(1) manual."); -+ error (f_"nbdkit is not installed or not working. It is required to use ‘-it vddk’. See \"INPUT FROM VDDK\" in the virt-v2v(1) manual."); - - (* Check it's a new enough version. The latest features we - * require are ‘--exit-with-parent’ and ‘--selinux-label’, both -@@ -73,14 +88,20 @@ class input_libvirt_vddk vddk_options password libvirt_uri parsed_uri guest = - - (* Check that the VDDK plugin is installed and working *) - let error_unless_nbdkit_vddk_working () = -+ let set_ld_library_path = -+ match library_path with -+ | None -> "" -+ | Some library_path -> -+ sprintf "LD_LIBRARY_PATH=%s " (quote library_path) in -+ - let cmd = -- sprintf "LD_LIBRARY_PATH=%s nbdkit vddk --dump-plugin >/dev/null" -- (quote library_path) in -+ sprintf "%snbdkit vddk --dump-plugin >/dev/null" -+ set_ld_library_path in - if Sys.command cmd <> 0 then ( - (* See if we can diagnose why ... *) - let cmd = -- sprintf "LD_LIBRARY_PATH=%s LANG=C nbdkit vddk --dump-plugin 2>&1 | grep -sq libvixDiskLib.so" -- (quote library_path) in -+ sprintf "LANG=C %snbdkit vddk --dump-plugin 2>&1 | grep -sq libvixDiskLib.so" -+ set_ld_library_path in - let needs_library = Sys.command cmd = 0 in - if not needs_library then - error (f_"nbdkit VDDK plugin is not installed or not working. It is required if you want to use VDDK. -@@ -91,9 +112,9 @@ See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") - else - error (f_"nbdkit VDDK plugin is not installed or not working. It is required if you want to use VDDK. - --It looks like you did not set the right path in the ‘--vddk’ option, or your copy of the VDDK directory is incomplete. There should be a library called ’%s/libvixDiskLib.so.?’. -+It looks like you did not set the right path in the ‘--vddk-libdir’ option, or your copy of the VDDK directory is incomplete. There should be a library called ’/%s/libvixDiskLib.so.?’. - --See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") library_path -+See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") libNN - ) - in - -@@ -120,6 +141,7 @@ See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") library_path - let vddk_passthrus = - [ "config", (fun { vddk_config } -> vddk_config); - "cookie", (fun { vddk_cookie } -> vddk_cookie); -+ "libdir", (fun { vddk_libdir } -> vddk_libdir); - "nfchostport", (fun { vddk_nfchostport } -> vddk_nfchostport); - "port", (fun { vddk_port } -> vddk_port); - "snapshot", (fun { vddk_snapshot } -> vddk_snapshot); -@@ -140,9 +162,8 @@ object - | Some field -> sprintf " --vddk-%s %s" name field - ) vddk_passthrus - ) in -- sprintf "%s --vddk %s%s" -+ sprintf "%s -it vddk %s" - super#as_options (* superclass prints "-i libvirt etc" *) -- vddk_options.vddk_libdir - pt_options - - method source () = -@@ -249,7 +270,6 @@ object - add_arg (sprintf "user=%s" user); - add_arg password_param; - add_arg (sprintf "vm=moref=%s" moref); -- add_arg (sprintf "libdir=%s" libdir); - - (* The passthrough parameters. *) - List.iter ( -@@ -299,7 +319,10 @@ object - let pid = fork () in - if pid = 0 then ( - (* Child process (nbdkit). *) -- putenv "LD_LIBRARY_PATH" library_path; -+ (match library_path with -+ | None -> () -+ | Some x -> putenv "LD_LIBRARY_PATH" x -+ ); - execvp "nbdkit" args - ); - -diff --git a/v2v/test-v2v-docs.sh b/v2v/test-v2v-docs.sh -index 5e49d5240..c8ca193eb 100755 ---- a/v2v/test-v2v-docs.sh -+++ b/v2v/test-v2v-docs.sh -@@ -22,4 +22,4 @@ $TEST_FUNCTIONS - skip_if_skipped - - $top_srcdir/podcheck.pl virt-v2v.pod virt-v2v \ -- --ignore=--debug-overlay,--ic,--if,--in-place,--no-trim,--oa,--oc,--of,--on,--os,--vmtype -+ --ignore=--debug-overlay,--ic,--if,--in-place,--it,--no-trim,--oa,--oc,--of,--on,--os,--vmtype -diff --git a/v2v/types.ml b/v2v/types.ml -index 4f9205aa0..43bd28804 100644 ---- a/v2v/types.ml -+++ b/v2v/types.ml -@@ -473,9 +473,9 @@ type root_choice = AskRoot | SingleRoot | FirstRoot | RootDev of string - type output_allocation = Sparse | Preallocated - - type vddk_options = { -- vddk_libdir : string; - vddk_config : string option; - vddk_cookie : string option; -+ vddk_libdir : string option; - vddk_nfchostport : string option; - vddk_port : string option; - vddk_snapshot : string option; -diff --git a/v2v/types.mli b/v2v/types.mli -index 087a03702..fd944bebf 100644 ---- a/v2v/types.mli -+++ b/v2v/types.mli -@@ -329,9 +329,9 @@ type output_allocation = Sparse | Preallocated - (** Type of [-oa] (output allocation) option. *) - - type vddk_options = { -- vddk_libdir : string; - vddk_config : string option; - vddk_cookie : string option; -+ vddk_libdir : string option; - vddk_nfchostport : string option; - vddk_port : string option; - vddk_snapshot : string option; -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index e798ad1e7..7aca22b3c 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -255,6 +255,13 @@ 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<-it> B -+ -+Use VMware VDDK as a transport to copy the input disks. See -+L below. If you use this parameter then you may -+need to use other I<--vddk*> options to specify how to connect through -+VDDK. -+ - =item B<--keys-from-stdin> - - Read key or passphrase parameters from stdin. The default is -@@ -501,13 +508,20 @@ boot an operating system from the first VirtIO disk. Specifically, - F must be on the first VirtIO disk, and it cannot chainload an - OS which is not in the first VirtIO disk. - --=item B<--vddk> LIBDIR -+=item B<--vddk-libdir> LIBDIR - --Enable VDDK input from VMware vCenter or ESXi. C is the top --directory of the VDDK library. This directory should I -+Set the VDDK library directory. This directory should I - subdirectories called F, F etc., but do not include - F actually in the parameter. - -+In most cases this parameter is required when using the I<-it vddk> -+(VDDK) transport. See L below for details. -+ -+=item B<--vddk-thumbprint> xx:xx:xx:... -+ -+Set the thumbprint of the remote VMware server. -+ -+This parameter is required when using the I<-it vddk> (VDDK) transport. - See L below for details. - - =item B<--vddk-config> FILENAME -@@ -520,16 +534,13 @@ See L below for details. - - =item B<--vddk-snapshot> SNAPSHOT-MOREF - --=item B<--vddk-thumbprint> xx:xx:xx:... -- - =item B<--vddk-transports> MODE:MODE:... - - =item B<--vddk-vimapiver> APIVER - - When using VDDK mode, these options are passed unmodified to the - L VDDK plugin. Please refer to L. --If I<--vddk> is present, I<--vddk-thumbprint> is also required, --the rest are optional. -+These are all optional. - - =item B<--vdsm-compat=0.10> - -@@ -1390,6 +1401,8 @@ continuing. - - =head2 VDDK: IMPORTING A GUEST - -+The I<-it vddk> parameter selects VDDK as the input transport for disks. -+ - To import a particular guest from vCenter server or ESXi hypervisor, - use a command like the following, substituting the URI, guest name and - SSL thumbprint: -@@ -1397,7 +1410,8 @@ SSL thumbprint: - $ export PATH=/path/to/nbdkit:$PATH - $ virt-v2v \ - -ic 'vpx://root@vcenter.example.com/Datacenter/esxi?no_verify=1' \ -- --vddk /path/to/vmware-vix-disklib-distrib \ -+ -it vddk \ -+ --vddk-libdir /path/to/vmware-vix-disklib-distrib \ - --vddk-thumbprint xx:xx:xx:... \ - "Windows 2003" \ - -o local -os /var/tmp --- -2.14.3 - diff --git a/SOURCES/0077-v2v-i-vmx-Enhance-VMX-support-with-ability-to-use-it.patch b/SOURCES/0077-v2v-i-vmx-Enhance-VMX-support-with-ability-to-use-it.patch deleted file mode 100644 index 77752e4..0000000 --- a/SOURCES/0077-v2v-i-vmx-Enhance-VMX-support-with-ability-to-use-it.patch +++ /dev/null @@ -1,619 +0,0 @@ -From d45c983b7181946323ebd93cccf1100b45b55470 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 8 Dec 2017 10:43:45 +0000 -Subject: [PATCH] =?UTF-8?q?v2v:=20-i=20vmx:=20Enhance=20VMX=20support=20wi?= - =?UTF-8?q?th=20ability=20to=20use=20=E2=80=98-it=20ssh=E2=80=99=20transpo?= - =?UTF-8?q?rt.?= -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This enhances the existing VMX input support allowing it to be -used over SSH to the ESXi server. - -The original command (for local .vmx files) was: - - $ virt-v2v -i vmx guest.vmx -o local -os /var/tmp - -Adding ‘-it ssh’ and using an SSH remote path gives the new syntax: - - $ virt-v2v \ - -i vmx -it ssh \ - "ssh://root@esxi.example.com/vmfs/volumes/datastore1/guest/guest.vmx" \ - -o local -os /var/tmp - -I anticipate that this input method will be widely used enough that it -deserves its own example at the top of the man page. - -(cherry picked from commit 1d38216d20141cef9ce83ca4ddbe9c79f5da4f39) ---- - v2v/cmdline.ml | 26 ++++-- - v2v/input_libvirt_other.ml | 9 --- - v2v/input_libvirt_other.mli | 1 - - v2v/input_vmx.ml | 193 +++++++++++++++++++++++++++++++++++++------- - v2v/input_vmx.mli | 5 +- - v2v/utils.ml | 9 +++ - v2v/utils.mli | 2 + - v2v/virt-v2v.pod | 106 ++++++++++++++++++++---- - 8 files changed, 290 insertions(+), 61 deletions(-) - -diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml -index 81562d1f5..dfcc77ecd 100644 ---- a/v2v/cmdline.ml -+++ b/v2v/cmdline.ml -@@ -276,6 +276,7 @@ read the man page virt-v2v(1). - let input_transport = - match !input_transport with - | None -> None -+ | Some "ssh" -> Some `SSH - | Some "vddk" -> Some `VDDK - | Some transport -> - error (f_"unknown input transport ‘-it %s’") transport in -@@ -341,7 +342,8 @@ read the man page virt-v2v(1). - * should not be used. - *) - (match input_transport with -- | None -> -+ | None -+ | Some `SSH -> - if !vddk_config <> None || - !vddk_cookie <> None || - !vddk_libdir <> None || -@@ -379,6 +381,12 @@ read the man page virt-v2v(1). - | [guest] -> guest - | _ -> - error (f_"expecting a libvirt guest name on the command line") in -+ let input_transport = -+ match input_transport with -+ | None -> None -+ | Some `VDDK -> Some `VDDK -+ | Some `SSH -> -+ error (f_"only ‘-it vddk’ can be used here") in - Input_libvirt.input_libvirt vddk_options password - input_conn input_transport guest - -@@ -401,13 +409,19 @@ read the man page virt-v2v(1). - Input_ova.input_ova filename - - | `VMX -> -- (* -i vmx: Expecting an vmx filename. *) -- let filename = -+ (* -i vmx: Expecting a vmx filename or SSH remote path. *) -+ let arg = - match args with -- | [filename] -> filename -+ | [arg] -> arg - | _ -> -- error (f_"expecting a VMX file name on the command line") in -- Input_vmx.input_vmx filename in -+ error (f_"expecting a single VMX file name or SSH remote path on the command line") in -+ let input_transport = -+ match input_transport with -+ | None -> None -+ | Some `SSH -> Some `SSH -+ | Some `VDDK -> -+ error (f_"only ‘-it ssh’ can be used here") in -+ Input_vmx.input_vmx input_transport arg in - - (* Prevent use of --in-place option in RHEL. *) - if in_place then -diff --git a/v2v/input_libvirt_other.ml b/v2v/input_libvirt_other.ml -index dc16cb11b..a487a2b76 100644 ---- a/v2v/input_libvirt_other.ml -+++ b/v2v/input_libvirt_other.ml -@@ -39,15 +39,6 @@ let error_if_libvirt_does_not_support_json_backingfile () = - Libvirt_utils.libvirt_get_version () < (2, 1, 0) then - 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.") - --(* xen+ssh URLs use the SSH driver in CURL. Currently this requires -- * ssh-agent authentication. Give a clear error if this hasn't been -- * set up (RHBZ#1139973). -- *) --let error_if_no_ssh_agent () = -- try ignore (Sys.getenv "SSH_AUTH_SOCK") -- with Not_found -> -- error (f_"ssh-agent authentication has not been set up ($SSH_AUTH_SOCK is not set). Please read \"INPUT FROM RHEL 5 XEN\" in the virt-v2v(1) man page.") -- - (* Superclass. *) - class virtual input_libvirt (password : string option) libvirt_uri guest = - object -diff --git a/v2v/input_libvirt_other.mli b/v2v/input_libvirt_other.mli -index 494ca908a..8b1e8aa1d 100644 ---- a/v2v/input_libvirt_other.mli -+++ b/v2v/input_libvirt_other.mli -@@ -19,7 +19,6 @@ - (** [-i libvirt] source. *) - - val error_if_libvirt_does_not_support_json_backingfile : unit -> unit --val error_if_no_ssh_agent : unit -> unit - - class virtual input_libvirt : string option -> string option -> string -> object - method precheck : unit -> unit -diff --git a/v2v/input_vmx.ml b/v2v/input_vmx.ml -index a4f77c2ab..092a7b70c 100644 ---- a/v2v/input_vmx.ml -+++ b/v2v/input_vmx.ml -@@ -19,6 +19,7 @@ - open Printf - open Scanf - -+open Unix_utils - open Common_gettext.Gettext - open Common_utils - -@@ -26,10 +27,86 @@ open Types - open Utils - open Name_from_disk - --external identity : 'a -> 'a = "%identity" -+type vmx_source = -+ | File of string (* local file or NFS *) -+ | SSH of Xml.uri (* SSH URI *) - --let rec find_disks vmx vmx_filename = -- find_scsi_disks vmx vmx_filename @ find_ide_disks vmx vmx_filename -+(* The single filename on the command line is intepreted either as -+ * a local file or a remote SSH URI (only if ‘-it ssh’). -+ *) -+let vmx_source_of_arg input_transport arg = -+ match input_transport, arg with -+ | None, arg -> File arg -+ | Some `SSH, arg -> -+ let uri = -+ try Xml.parse_uri arg -+ with Invalid_argument _ -> -+ error (f_"remote vmx ‘%s’ could not be parsed as a URI") arg in -+ if uri.Xml.uri_scheme <> None && uri.Xml.uri_scheme <> Some "ssh" then -+ error (f_"vmx URI start with ‘ssh://...’"); -+ if uri.Xml.uri_server = None then -+ error (f_"vmx URI remote server name omitted"); -+ if uri.Xml.uri_path = None || uri.Xml.uri_path = Some "/" then -+ error (f_"vmx URI path component looks incorrect"); -+ SSH uri -+ -+(* Return various fields from the URI. The checks in vmx_source_of_arg -+ * should ensure that none of these assertions fail. -+ *) -+let port_of_uri { Xml.uri_port } = -+ match uri_port with i when i <= 0 -> None | i -> Some i -+let server_of_uri { Xml.uri_server } = -+ match uri_server with None -> assert false | Some s -> s -+let path_of_uri { Xml.uri_path } = -+ match uri_path with None -> assert false | Some p -> p -+ -+(* 'scp' a remote file into a temporary local file, returning the path -+ * of the temporary local file. -+ *) -+let scp_from_remote_to_temporary uri tmpdir filename = -+ let localfile = tmpdir // filename in -+ -+ let cmd = -+ sprintf "scp%s%s %s%s:%s %s" -+ (if verbose () then "" else " -q") -+ (match port_of_uri uri with -+ | None -> "" -+ | Some port -> sprintf " -P %d" port) -+ (match uri.Xml.uri_user with -+ | None -> "" -+ | Some user -> quote user ^ "@") -+ (quote (server_of_uri uri)) -+ (* The double quoting of the path is counter-intuitive -+ * but correct, see: -+ * https://stackoverflow.com/questions/19858176/how-to-escape-spaces-in-path-during-scp-copy-in-linux -+ *) -+ (quote (quote (path_of_uri uri))) -+ (quote localfile) in -+ if verbose () then -+ eprintf "%s\n%!" cmd; -+ if Sys.command cmd <> 0 then -+ error (f_"could not copy the VMX file from the remote server, see earlier error messages"); -+ localfile -+ -+(* Test if [path] exists on the remote server. *) -+let remote_file_exists uri path = -+ let cmd = -+ sprintf "ssh%s %s%s test -f %s" -+ (match port_of_uri uri with -+ | None -> "" -+ | Some port -> sprintf " -p %d" port) -+ (match uri.Xml.uri_user with -+ | None -> "" -+ | Some user -> quote user ^ "@") -+ (quote (server_of_uri uri)) -+ (* Double quoting is necessary here, see above. *) -+ (quote (quote path)) in -+ if verbose () then -+ eprintf "%s\n%!" cmd; -+ Sys.command cmd = 0 -+ -+let rec find_disks vmx vmx_source = -+ find_scsi_disks vmx vmx_source @ find_ide_disks vmx vmx_source - - (* Find all SCSI hard disks. - * -@@ -39,7 +116,7 @@ let rec find_disks vmx vmx_filename = - * | omitted - * scsi0:0.fileName = "guest.vmdk" - *) --and find_scsi_disks vmx vmx_filename = -+and find_scsi_disks vmx vmx_source = - let get_scsi_controller_target ns = - sscanf ns "scsi%d:%d" (fun c t -> c, t) - in -@@ -51,7 +128,7 @@ and find_scsi_disks vmx vmx_filename = - Some "scsi-harddisk"; None ] in - let scsi_controller = Source_SCSI in - -- find_hdds vmx vmx_filename -+ find_hdds vmx vmx_source - get_scsi_controller_target is_scsi_controller_target - scsi_device_types scsi_controller - -@@ -61,7 +138,7 @@ and find_scsi_disks vmx vmx_filename = - * ide0:0.deviceType = "ata-hardDisk" - * ide0:0.fileName = "guest.vmdk" - *) --and find_ide_disks vmx vmx_filename = -+and find_ide_disks vmx vmx_source = - let get_ide_controller_target ns = - sscanf ns "ide%d:%d" (fun c t -> c, t) - in -@@ -72,11 +149,11 @@ and find_ide_disks vmx vmx_filename = - let ide_device_types = [ Some "ata-harddisk" ] in - let ide_controller = Source_IDE in - -- find_hdds vmx vmx_filename -+ find_hdds vmx vmx_source - get_ide_controller_target is_ide_controller_target - ide_device_types ide_controller - --and find_hdds vmx vmx_filename -+and find_hdds vmx vmx_source - get_controller_target is_controller_target - device_types controller = - (* Find namespaces matching '(ide|scsi)X:Y' with suitable deviceType. *) -@@ -105,9 +182,9 @@ and find_hdds vmx vmx_filename - match path, v with - | [ns; "filename"], Some filename -> - let c, t = get_controller_target ns in -+ let uri, format = qemu_uri_of_filename vmx_source filename in - let s = { s_disk_id = (-1); -- s_qemu_uri = qemu_uri_of_filename vmx_filename filename; -- s_format = Some "vmdk"; -+ s_qemu_uri = uri; s_format = Some format; - s_controller = Some controller } in - Some (c, t, s) - | _ -> None -@@ -129,17 +206,54 @@ and find_hdds vmx vmx_filename - (* The filename can be an absolute path, but is more often a - * path relative to the location of the vmx file. - * -- * Note that we always end up with an absolute path, which is -- * also useful because it means we won't have any paths that -- * could be misinterpreted by qemu. -+ * This constructs a QEMU URI of the filename relative to the -+ * vmx file (which might be remote over SSH). - *) --and qemu_uri_of_filename vmx_filename filename = -- if not (Filename.is_relative filename) then -- filename -- else ( -- let dir = Filename.dirname (absolute_path vmx_filename) in -- dir // filename -- ) -+and qemu_uri_of_filename vmx_source filename = -+ match vmx_source with -+ | File vmx_filename -> -+ (* Always ensure this returns an absolute path to avoid -+ * any confusion with filenames containing colons. -+ *) -+ absolute_path_from_other_file vmx_filename filename, "vmdk" -+ -+ | SSH uri -> -+ let vmx_path = path_of_uri uri in -+ let abs_path = absolute_path_from_other_file vmx_path filename in -+ let format = "vmdk" in -+ -+ (* XXX This is a hack to work around qemu / VMDK limitation -+ * "Cannot use relative extent paths with VMDK descriptor file" -+ * We can remove this if the above is fixed. -+ *) -+ let abs_path, format = -+ let flat_vmdk = -+ Str.replace_first (Str.regexp "\\.vmdk$") "-flat.vmdk" abs_path in -+ if remote_file_exists uri flat_vmdk then (flat_vmdk, "raw") -+ else (abs_path, format) in -+ -+ let json_params = [ -+ "file.driver", JSON.String "ssh"; -+ "file.path", JSON.String abs_path; -+ "file.host", JSON.String (server_of_uri uri); -+ "file.host_key_check", JSON.String "no"; -+ ] in -+ let json_params = -+ match uri.Xml.uri_user with -+ | None -> json_params -+ | Some user -> -+ ("file.user", JSON.String user) :: json_params in -+ let json_params = -+ match port_of_uri uri with -+ | None -> json_params -+ | Some port -> -+ ("file.port", JSON.Int port) :: json_params in -+ -+ "json:" ^ JSON.string_of_doc json_params, format -+ -+and absolute_path_from_other_file other_filename filename = -+ if not (Filename.is_relative filename) then filename -+ else (Filename.dirname (absolute_path other_filename)) // filename - - (* Find all removable disks. - * -@@ -272,21 +386,46 @@ and find_nics vmx = - let nics = List.map (fun (_, source) -> source) nics in - nics - --class input_vmx vmx_filename = object -+class input_vmx input_transport arg = -+ let tmpdir = -+ let base_dir = (open_guestfs ())#get_cachedir () in -+ let t = Mkdtemp.temp_dir ~base_dir "vmx." in -+ rmdir_on_exit t; -+ t in -+object - inherit input - -- method as_options = "-i vmx " ^ vmx_filename -+ method as_options = "-i vmx " ^ arg -+ -+ method precheck () = -+ match input_transport with -+ | None -> () -+ | Some `SSH -> -+ if backend_is_libvirt () then -+ error (f_"because libvirtd doesn't pass the SSH_AUTH_SOCK environment variable to qemu you must set this environment variable:\n\nexport LIBGUESTFS_BACKEND=direct\n\nand then rerun the virt-v2v command."); -+ error_if_no_ssh_agent () - - method source () = -- (* Parse the VMX file. *) -- let vmx = Parse_vmx.parse_file vmx_filename in -+ let vmx_source = vmx_source_of_arg input_transport arg in -+ -+ (* If the transport is SSH, fetch the file from remote, else -+ * parse it from local. -+ *) -+ let vmx = -+ match vmx_source with -+ | File filename -> Parse_vmx.parse_file filename -+ | SSH uri -> -+ let filename = scp_from_remote_to_temporary uri tmpdir "source.vmx" in -+ Parse_vmx.parse_file filename in - - let name = - match Parse_vmx.get_string vmx ["displayName"] with -+ | Some s -> s - | None -> - warning (f_"no displayName key found in VMX file"); -- name_from_disk vmx_filename -- | Some s -> s in -+ match vmx_source with -+ | File filename -> name_from_disk filename -+ | SSH uri -> name_from_disk (path_of_uri uri) in - - let memory_mb = - match Parse_vmx.get_int64 vmx ["memSize"] with -@@ -325,7 +464,7 @@ class input_vmx vmx_filename = object - None - | None -> None in - -- let disks = find_disks vmx vmx_filename in -+ let disks = find_disks vmx vmx_source in - let removables = find_removables vmx in - let nics = find_nics vmx in - -diff --git a/v2v/input_vmx.mli b/v2v/input_vmx.mli -index f236f8716..34ec2a5c6 100644 ---- a/v2v/input_vmx.mli -+++ b/v2v/input_vmx.mli -@@ -18,5 +18,6 @@ - - (** [-i vmx] source. *) - --val input_vmx : string -> Types.input --(** [input_vmx filename] sets up an input from vmware vmx file. *) -+val input_vmx : [`SSH] option -> string -> Types.input -+(** [input_vmx input_transport arg] sets up an input -+ from vmware vmx file. *) -diff --git a/v2v/utils.ml b/v2v/utils.ml -index 2061eea61..158077bf6 100644 ---- a/v2v/utils.ml -+++ b/v2v/utils.ml -@@ -127,6 +127,15 @@ let backend_is_libvirt () = - let backend = fst (String.split ":" backend) in - backend = "libvirt" - -+(* When using the SSH driver in qemu (currently) this requires -+ * ssh-agent authentication. Give a clear error if this hasn't been -+ * set up (RHBZ#1139973). This might improve if we switch to libssh1. -+ *) -+let error_if_no_ssh_agent () = -+ try ignore (Sys.getenv "SSH_AUTH_SOCK") -+ with Not_found -> -+ error (f_"ssh-agent authentication has not been set up ($SSH_AUTH_SOCK is not set). This is required by qemu to do passwordless ssh access. See the virt-v2v(1) man page for more information.") -+ - let find_file_in_tar tar filename = - let lines = external_command (sprintf "tar tRvf %s" (Filename.quote tar)) in - let rec loop lines = -diff --git a/v2v/utils.mli b/v2v/utils.mli -index b2fd0be1b..042454565 100644 ---- a/v2v/utils.mli -+++ b/v2v/utils.mli -@@ -61,6 +61,8 @@ val qemu_img_supports_offset_and_size : unit -> bool - val backend_is_libvirt : unit -> bool - (** Return true iff the current backend is libvirt. *) - -+val error_if_no_ssh_agent : unit -> unit -+ - val find_file_in_tar : string -> string -> int64 * int64 - (** [find_file_in_tar tar filename] looks up file in [tar] archive and returns - a tuple containing at which byte it starts and how long the file is. -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index 7aca22b3c..d0387734a 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -113,6 +113,23 @@ Note that after conversion, the guest will appear in the RHV-M Export - Storage Domain, from where you will need to import it using the RHV-M - user interface. (See L). - -+=head2 Convert from ESXi hypervisor over SSH to local libvirt -+ -+You have an ESXi hypervisor called C with SSH access -+enabled. You want to convert from VMFS storage on that server to -+a local file. -+ -+ virt-v2v \ -+ -i vmx -it ssh \ -+ "root@esxi.example.com/vmfs/volumes/datastore1/guest/guest.vmx" \ -+ -o local -os /var/tmp -+ -+The guest must not be running. Virt-v2v would I need to be run -+as root in this case. -+ -+For more information about converting from VMX files see -+L below. -+ - =head2 Convert disk image to OpenStack glance - - Given a disk image from another hypervisor that you want to convert to -@@ -233,9 +250,10 @@ L below - - Set the input method to I. - --In this mode you can read a VMware vmx file directly. This is useful --when VMware VMs are stored on an NFS server which you can mount --directly. See L below -+In this mode you can read a VMware vmx file directly or over SSH. -+This is useful when VMware VMs are stored on an NFS server which you -+can mount directly, or where you have access by SSH to an ESXi -+hypervisor. See L below - - =item B<-ic> libvirtURI - -@@ -255,6 +273,11 @@ 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<-it> B -+ -+When using I<-i vmx>, this enables the ssh transport. -+See L below. -+ - =item B<-it> B - - Use VMware VDDK as a transport to copy the input disks. See -@@ -1194,9 +1217,23 @@ directory containing the files: - - =head1 INPUT FROM VMWARE VMX - --Virt-v2v is able to import guests from VMware’s vmx files. This is --useful where VMware virtual machines are stored on a separate NFS --server and you are able to mount the NFS storage directly. -+Virt-v2v is able to import guests from VMware’s vmx files. -+ -+This is useful in two cases: -+ -+=over 4 -+ -+=item 1. -+ -+VMware virtual machines are stored on a separate NFS server and you -+are able to mount the NFS storage directly. -+ -+=item 2. -+ -+You have enabled SSH access to the VMware ESXi hypervisor and there is -+a C folder containing the virtual machines. -+ -+=back - - If you find a folder of files called F.vmx>, - F.vmxf>, F.nvram> and one or more F<.vmdk> disk -@@ -1222,28 +1259,65 @@ With other methods, virt-v2v tries to prevent concurrent access, but - because the I<-i vmx> method works directly against the storage, - checking for concurrent access is not possible. - --=head2 VMX: MOUNT THE NFS STORAGE ON THE CONVERSION SERVER -+=head2 VMX: ACCESS TO THE STORAGE CONTAINING THE VMX AND VMDK FILES - --Virt-v2v must be able to access the F<.vmx> file and any local --F<.vmdk> disks. Normally this means you must mount the NFS storage --containing these files. -+If the vmx and vmdk files aren't available locally then you must -+I mount the NFS storage on the conversion server I enable -+passwordless SSH on the ESXi hypervisor. -+ -+=head3 VMX: Passwordless SSH using ssh-agent -+ -+You must also use ssh-agent, and add your ssh public key to -+F (on the ESXi hypervisor). -+ -+After doing this, you should check that passwordless access works from -+the virt-v2v server to the ESXi hypervisor. For example: -+ -+ $ ssh root@esxi.example.com -+ [ logs straight into the shell, no password is requested ] -+ -+Note that password-interactive and Kerberos access are B -+supported. You B to set up ssh access using ssh-agent and -+authorized_keys. -+ -+=head3 VMX: Construct the SSH URI -+ -+When using the SSH input transport you must specify a remote -+C URI pointing to the VMX file. A typical URI looks like: -+ -+ ssh://root@esxi.example.com/vmfs/volumes/datastore1/my%20guest/my%20guest.vmx -+ -+Any space must be escaped with C<%20> and other non-ASCII characters -+may also need to be URI-escaped. -+ -+The username is not required if it is the same as your local username. -+ -+You may optionally supply a port number after the hostname if the SSH -+server is not listening on the default port (22). - - =head2 VMX: IMPORTING A GUEST - --To import a vmx file, do: -+To import a vmx file from a local file or NFS, do: - - $ virt-v2v -i vmx guest.vmx -o local -os /var/tmp - -+To import a vmx file over SSH, add I<-it ssh> to select the SSH -+transport and supply a remote SSH URI: -+ -+ $ virt-v2v \ -+ -i vmx -it ssh \ -+ "ssh://root@esxi.example.com/vmfs/volumes/datastore1/guest/guest.vmx" \ -+ -o local -os /var/tmp -+ - Virt-v2v processes the vmx file and uses it to find the location of - any vmdk disks. - - =head1 INPUT FROM VMWARE ESXi HYPERVISOR - --Virt-v2v cannot access an ESXi hypervisor directly. You should use --the OVA or VMX methods above (see L and/or --L) if possible, as it is much faster and --requires much less disk space than the method described in this --section. -+You should use the OVA or VMX methods above (see L and/or L) if possible, as it is much -+faster and requires much less disk space than the method described in -+this section. - - You can use the L tool to copy the guest - off the hypervisor into a local file, and then convert it. --- -2.14.3 - diff --git a/SOURCES/0077-v2v-o-rhv-upload-Properly-replace-SD_UUID-in-OVF-RHB.patch b/SOURCES/0077-v2v-o-rhv-upload-Properly-replace-SD_UUID-in-OVF-RHB.patch new file mode 100644 index 0000000..bdcb336 --- /dev/null +++ b/SOURCES/0077-v2v-o-rhv-upload-Properly-replace-SD_UUID-in-OVF-RHB.patch @@ -0,0 +1,29 @@ +From ff223abca41eb5c491dc05a1c4e006ad65f34148 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 7 Aug 2018 09:06:46 +0100 +Subject: [PATCH] v2v: -o rhv-upload: Properly replace SD_UUID in OVF + (RHBZ#1612653). + +The @SD_UUID@ pattern was not being replaced correctly. + +Thanks: Daniel Erez. +--- + v2v/rhv-upload-createvm.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v2v/rhv-upload-createvm.py b/v2v/rhv-upload-createvm.py +index a34627ec8..1d0e8c95d 100644 +--- a/v2v/rhv-upload-createvm.py ++++ b/v2v/rhv-upload-createvm.py +@@ -70,7 +70,7 @@ sds_service = system_service.storage_domains_service() + sd = sds_service.list(search=("name=%s" % params['output_storage']))[0] + sd_uuid = sd.id + +-ovf.replace("@SD_UUID@", sd_uuid) ++ovf = ovf.replace("@SD_UUID@", sd_uuid) + + vms_service = system_service.vms_service() + vm = vms_service.add( +-- +2.17.1 + diff --git a/SOURCES/0078-builder-use-the-template-arch-when-caching-all-templ.patch b/SOURCES/0078-builder-use-the-template-arch-when-caching-all-templ.patch deleted file mode 100644 index 7349fbb..0000000 --- a/SOURCES/0078-builder-use-the-template-arch-when-caching-all-templ.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 244157fcea33dad2c99ca4b740b5483ed36e4238 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Wed, 29 Nov 2017 15:29:57 +0100 -Subject: [PATCH] builder: use the template arch when caching all templates - -When caching all the templates, use the architecture of each template, -instead of the architecture passed as --arch (or the host architecture, -as default). This way, the right destination filename will be used. - -Fixes commit b1cf6246f3c80762cf27dbdb24168589a34daf00. - -Thanks to: Erik Skultety. - -(cherry picked from commit b34f457cf2dd66626abf743c90881bfe6532ec9b) ---- - builder/Makefile.am | 2 + - builder/builder.ml | 4 +- - builder/test-virt-builder-cacheall.sh | 88 +++++++++++++++++++++++++++++++++++ - 3 files changed, 92 insertions(+), 2 deletions(-) - create mode 100755 builder/test-virt-builder-cacheall.sh - -diff --git a/builder/Makefile.am b/builder/Makefile.am -index 2bbf1247a..c260a327f 100644 ---- a/builder/Makefile.am -+++ b/builder/Makefile.am -@@ -28,6 +28,7 @@ EXTRA_DIST = \ - test-simplestreams/streams/v1/index.json \ - test-simplestreams/streams/v1/net.cirros-cloud_released_download.json \ - test-virt-builder.sh \ -+ test-virt-builder-cacheall.sh \ - test-virt-builder-docs.sh \ - test-virt-builder-list.sh \ - test-virt-builder-list-simplestreams.sh \ -@@ -236,6 +237,7 @@ yajl_tests_LINK = \ - $(yajl_tests_THEOBJECTS) -o $@ - - TESTS = \ -+ test-virt-builder-cacheall.sh \ - test-virt-builder-docs.sh \ - test-virt-builder-list.sh \ - test-virt-index-validate.sh \ -diff --git a/builder/builder.ml b/builder/builder.ml -index 213fd56a1..ce99e0339 100644 ---- a/builder/builder.ml -+++ b/builder/builder.ml -@@ -251,8 +251,8 @@ let main () = - List.iter ( - fun (name, - { Index.revision = revision; file_uri = file_uri; -- proxy = proxy }) -> -- let template = name, cmdline.arch, revision in -+ proxy = proxy; arch = arch }) -> -+ let template = name, arch, revision in - message (f_"Downloading: %s") file_uri; - let progress_bar = not (quiet ()) in - ignore (Downloader.download downloader ~template ~progress_bar -diff --git a/builder/test-virt-builder-cacheall.sh b/builder/test-virt-builder-cacheall.sh -new file mode 100755 -index 000000000..c80d9ecd2 ---- /dev/null -+++ b/builder/test-virt-builder-cacheall.sh -@@ -0,0 +1,88 @@ -+#!/bin/bash - -+# libguestfs virt-builder test script -+# Copyright (C) 2017 Red Hat Inc. -+# -+# 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. -+ -+set -e -+ -+$TEST_FUNCTIONS -+skip_if_skipped -+ -+tmpdir="$(mktemp -d)" -+echo "tmpdir= $tmpdir" -+reposdir="$tmpdir/virt-builder/repos.d" -+repodir="$tmpdir/repo" -+indexfile="$repodir/index" -+cachedir="$tmpdir/cache" -+ -+mkdir -p "$reposdir" -+mkdir -p "$repodir" -+ -+# Create some fake images. -+img1_path="$repodir/img1.raw" -+img1_size=10485760 # 10G -+qemu-img create -f raw "$img1_path" $img1_size -+img1_csum=`do_sha256 "$img1_path"` -+ -+img2_path="$repodir/img2.qcow2" -+img2_size=5242880 # 5G -+qemu-img create -f qcow2 "$img2_path" $img2_size -+img2_csum=`do_sha256 "$img2_path"` -+ -+# Create an index for the images. -+cat > "$indexfile" < "$reposdir/repo1.conf" < +Date: Tue, 28 Aug 2018 12:59:06 +0100 +Subject: [PATCH] ppc64le: Don't use -cpu parameter under any circumstances + (RHBZ#1605071). + +--- + lib/appliance-cpu.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/lib/appliance-cpu.c b/lib/appliance-cpu.c +index a6c1b0faf..fa1bae3f9 100644 +--- a/lib/appliance-cpu.c ++++ b/lib/appliance-cpu.c +@@ -76,6 +76,9 @@ guestfs_int_get_cpu_model (int kvm) + return "host"; + else + return "cortex-a57"; ++#elif defined(__powerpc64__) ++ /* See discussion in https://bugzilla.redhat.com/show_bug.cgi?id=1605071 */ ++ return NULL; + #else + /* On most architectures, it is faster to pass the CPU host model to + * the appliance, allowing maximum speed for things like checksums +-- +2.17.1 + diff --git a/SOURCES/0079-RHEL-7-v2v-rhv-upload-Remove-restriction-on-oa-spars.patch b/SOURCES/0079-RHEL-7-v2v-rhv-upload-Remove-restriction-on-oa-spars.patch new file mode 100644 index 0000000..0230fff --- /dev/null +++ b/SOURCES/0079-RHEL-7-v2v-rhv-upload-Remove-restriction-on-oa-spars.patch @@ -0,0 +1,82 @@ +From aa5608a922bd35db28f555e53aea2308361991dd Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 14 May 2018 10:16:58 +0100 +Subject: [PATCH] RHEL 7: 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?" +--- + v2v/output_rhv_upload.ml | 11 +---------- + v2v/rhv-upload-plugin.py | 4 +--- + v2v/virt-v2v.pod | 6 ------ + 3 files changed, 2 insertions(+), 19 deletions(-) + +diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml +index 7dbd98a0d..32c2f8f64 100644 +--- a/v2v/output_rhv_upload.ml ++++ b/v2v/output_rhv_upload.ml +@@ -176,19 +176,11 @@ See also \"OUTPUT TO RHV\" in the virt-v2v(1) manual.") + 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.") + in + +- (* Output format/sparse must be raw/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 + in + +- let error_unless_output_alloc_sparse () = +- if output_alloc <> Sparse then +- error_current_limitation "-oa sparse" +- in +- + (* JSON parameters which are invariant between disks. *) + let json_params = [ + "verbose", JSON.Bool (verbose ()); +@@ -241,7 +233,6 @@ object + error_unless_ovirtsdk4_module_available (); + error_unless_nbdkit_working (); + error_unless_nbdkit_python3_working (); +- error_unless_output_alloc_sparse (); + if have_selinux then + error_unless_nbdkit_compiled_with_selinux () + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 4fad27fb8..41cb29992 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -139,10 +139,8 @@ def open(readonly): + format = disk_format, + 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'], +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index 90443373f..91f575617 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -1813,12 +1813,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 +-- +2.17.1 + diff --git a/SOURCES/0079-v2v-docs-Match-the-two-instances-of-path-to-nbdkit-i.patch b/SOURCES/0079-v2v-docs-Match-the-two-instances-of-path-to-nbdkit-i.patch deleted file mode 100644 index d39e580..0000000 --- a/SOURCES/0079-v2v-docs-Match-the-two-instances-of-path-to-nbdkit-i.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 91971da7f4b7d4a0b6a77160e30f7f12b65e2927 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 18 Dec 2017 10:29:11 +0000 -Subject: [PATCH] v2v: docs: Match the two instances of /path/to/nbdkit in the - documentation. - -Fixes commit d81a2ee185599c23a128ab65be9d48b415abf461. -See also: -https://bugzilla.redhat.com/show_bug.cgi?id=1513884#c5 - -(cherry picked from commit dab065a8eed6c6d8d9c53956393566812cfe6a2e) ---- - v2v/virt-v2v.pod | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod -index d0387734a..7d3923bda 100644 ---- a/v2v/virt-v2v.pod -+++ b/v2v/virt-v2v.pod -@@ -1481,7 +1481,7 @@ To import a particular guest from vCenter server or ESXi hypervisor, - use a command like the following, substituting the URI, guest name and - SSL thumbprint: - -- $ export PATH=/path/to/nbdkit:$PATH -+ $ export PATH=/path/to/nbdkit-1.1.x:$PATH - $ virt-v2v \ - -ic 'vpx://root@vcenter.example.com/Datacenter/esxi?no_verify=1' \ - -it vddk \ --- -2.14.3 - diff --git a/SOURCES/0080-RHEL-7-o-rhv-upload-Use-Python-2-instead-of-Python-3.patch b/SOURCES/0080-RHEL-7-o-rhv-upload-Use-Python-2-instead-of-Python-3.patch new file mode 100644 index 0000000..75ed899 --- /dev/null +++ b/SOURCES/0080-RHEL-7-o-rhv-upload-Use-Python-2-instead-of-Python-3.patch @@ -0,0 +1,316 @@ +From 587edb5852a7fafffa468f952ef13efd5958bcb8 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 9 Mar 2018 12:15:44 +0000 +Subject: [PATCH] RHEL 7: -o rhv-upload: Use Python 2 instead of Python 3. + +--- + v2v/output_rhv_upload.ml | 23 +++++++++++------------ + v2v/rhv-upload-createvm.py | 20 ++++++++++++++++---- + v2v/rhv-upload-plugin.py | 35 ++++++++++++++++++++++++----------- + v2v/rhv-upload-precheck.py | 22 +++++++++++++++++----- + v2v/test-v2v-python-syntax.sh | 2 +- + 5 files changed, 69 insertions(+), 33 deletions(-) + +diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml +index 32c2f8f64..9f87244ae 100644 +--- a/v2v/output_rhv_upload.ml ++++ b/v2v/output_rhv_upload.ml +@@ -78,7 +78,6 @@ let parse_output_options options = + + { rhv_cafile; rhv_cluster; rhv_direct; rhv_verifypeer } + +-let python3 = "python3" (* Defined by PEP 394 *) + let pidfile_timeout = 30 + let finalization_timeout = 5*60 + +@@ -120,15 +119,15 @@ class output_rhv_upload output_alloc output_conn + + (* Check that the Python binary is available. *) + let error_unless_python_binary_on_path () = +- try ignore (which python3) ++ try ignore (which "python") + with Executable_not_found _ -> + error (f_"no python binary called ‘%s’ can be found on the $PATH") +- python3 ++ "python" + in + + (* Check that the 'ovirtsdk4' Python module is available. *) + let error_unless_ovirtsdk4_module_available () = +- let res = run_command [ python3; "-c"; "import ovirtsdk4" ] in ++ let res = run_command [ "python"; "-c"; "import ovirtsdk4" ] in + if res <> 0 then + error (f_"the Python module ‘ovirtsdk4’ could not be loaded, is it installed? See previous messages for problems.") + in +@@ -150,14 +149,14 @@ class output_rhv_upload output_alloc output_conn + error (f_"nbdkit is not new enough, you need to upgrade to nbdkit ≥ 1.1.16") + in + +- (* Check that the python3 plugin is installed and working ++ (* Check that the python plugin is installed and working + * and can load the plugin script. + *) +- let error_unless_nbdkit_python3_working () = ++ let error_unless_nbdkit_python_working () = + let cmd = sprintf "nbdkit %s %s --dump-plugin >/dev/null" +- python3 (quote plugin) in ++ "python" (quote plugin) in + if Sys.command cmd <> 0 then +- error (f_"nbdkit Python 3 plugin is not installed or not working. It is required if you want to use ‘-o rhv-upload’. ++ error (f_"nbdkit Python plugin is not installed or not working. It is required if you want to use ‘-o rhv-upload’. + + See also \"OUTPUT TO RHV\" in the virt-v2v(1) manual.") + in +@@ -214,7 +213,7 @@ See also \"OUTPUT TO RHV\" in the virt-v2v(1) manual.") + "--newstyle"; (* use newstyle NBD protocol *) + "--exportname"; "/"; + +- "python3"; (* use the nbdkit Python 3 plugin *) ++ "python"; (* use the nbdkit Python plugin *) + plugin; (* Python plugin script *) + ] in + let args = if verbose () then args @ ["--verbose"] else args in +@@ -232,7 +231,7 @@ object + error_unless_python_binary_on_path (); + error_unless_ovirtsdk4_module_available (); + error_unless_nbdkit_working (); +- error_unless_nbdkit_python3_working (); ++ error_unless_nbdkit_python_working (); + if have_selinux then + error_unless_nbdkit_compiled_with_selinux () + +@@ -261,7 +260,7 @@ object + with_open_out + json_param_file + (fun chan -> output_string chan (JSON.string_of_doc json_params)); +- if run_command [ python3; precheck; json_param_file ] <> 0 then ++ if run_command [ "python"; precheck; json_param_file ] <> 0 then + error (f_"failed server prechecks, see earlier errors"); + + (* Create an nbdkit instance for each disk and set the +@@ -410,7 +409,7 @@ If the messages above are not sufficient to diagnose the problem then add the + + let ovf_file = tmpdir // "vm.ovf" in + with_open_out ovf_file (fun chan -> output_string chan ovf); +- if run_command [ python3; createvm; json_param_file; ovf_file ] <> 0 then ++ if run_command [ "python"; createvm; json_param_file; ovf_file ] <> 0 then + error (f_"failed to create virtual machine, see earlier errors") + + end +diff --git a/v2v/rhv-upload-createvm.py b/v2v/rhv-upload-createvm.py +index 1d0e8c95d..3f2fae4c6 100644 +--- a/v2v/rhv-upload-createvm.py ++++ b/v2v/rhv-upload-createvm.py +@@ -1,5 +1,6 @@ + # -*- python -*- +-# oVirt or RHV upload create VM used by ‘virt-v2v -o rhv-upload’ ++# coding: utf-8 ++# oVirt or RHV upload create VM used by 'virt-v2v -o rhv-upload' + # Copyright (C) 2018 Red Hat Inc. + # + # This program is free software; you can redistribute it and/or modify +@@ -21,8 +22,8 @@ import logging + import sys + import time + +-from http.client import HTTPSConnection +-from urllib.parse import urlparse ++from httplib import HTTPSConnection ++from urlparse import urlparse + + import ovirtsdk4 as sdk + import ovirtsdk4.types as types +@@ -37,8 +38,19 @@ if len(sys.argv) != 3: + raise RuntimeError("incorrect number of parameters") + + # Parameters are passed in via a JSON document. ++# https://stackoverflow.com/a/13105359 ++def byteify(input): ++ if isinstance(input, dict): ++ return {byteify(key): byteify(value) ++ for key, value in input.iteritems()} ++ elif isinstance(input, list): ++ return [byteify(element) for element in input] ++ elif isinstance(input, unicode): ++ return input.encode('utf-8') ++ else: ++ return input + with open(sys.argv[1], 'r') as fp: +- params = json.load(fp) ++ params = byteify(json.load(fp)) + + # What is passed in is a password file, read the actual password. + with open(params['output_password'], 'r') as fp: +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 41cb29992..3d4ed1270 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -1,5 +1,6 @@ + # -*- python -*- +-# oVirt or RHV upload nbdkit plugin used by ‘virt-v2v -o rhv-upload’ ++# coding: utf-8 ++# oVirt or RHV upload nbdkit plugin used by 'virt-v2v -o rhv-upload' + # Copyright (C) 2018 Red Hat Inc. + # + # This program is free software; you can redistribute it and/or modify +@@ -16,7 +17,7 @@ + # with this program; if not, write to the Free Software Foundation, Inc., + # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +-import builtins ++from __builtin__ import open as builtin_open + import json + import logging + import socket +@@ -24,8 +25,8 @@ import ssl + import sys + import time + +-from http.client import HTTPSConnection, HTTPConnection +-from urllib.parse import urlparse ++from httplib import HTTPSConnection, HTTPConnection ++from urlparse import urlparse + + import ovirtsdk4 as sdk + import ovirtsdk4.types as types +@@ -37,14 +38,25 @@ timeout = 5*60 + # Parameters are passed in via a JSON doc from the OCaml code. + # Because this Python code ships embedded inside virt-v2v there + # is no formal API here. ++# https://stackoverflow.com/a/13105359 ++def byteify(input): ++ if isinstance(input, dict): ++ return {byteify(key): byteify(value) ++ for key, value in input.iteritems()} ++ elif isinstance(input, list): ++ return [byteify(element) for element in input] ++ elif isinstance(input, unicode): ++ return input.encode('utf-8') ++ else: ++ return input + params = None + + def config(key, value): + global params + + if key == "params": +- with builtins.open(value, 'r') as fp: +- params = json.load(fp) ++ with builtin_open(value, 'r') as fp: ++ params = byteify(json.load(fp)) + else: + raise RuntimeError("unknown configuration key '%s'" % key) + +@@ -54,13 +66,14 @@ def config_complete(): + + def debug(s): + if params['verbose']: +- print(s, file=sys.stderr) ++ sys.stderr.write(s) ++ sys.stderr.write("\n") + sys.stderr.flush() + + def find_host(connection): + """Return the current host object or None.""" + try: +- with builtins.open("/etc/vdsm/vdsm.id") as f: ++ with builtin_open("/etc/vdsm/vdsm.id") as f: + vdsm_id = f.readline().strip() + except Exception as e: + # This is most likely not an oVirt host. +@@ -110,7 +123,7 @@ def open(readonly): + username = parsed.username or "admin@internal" + + # Read the password from file. +- with builtins.open(params['output_password'], 'r') as fp: ++ with builtin_open(params['output_password'], 'r') as fp: + password = fp.read() + password = password.rstrip() + +@@ -232,7 +245,7 @@ def open(readonly): + # New imageio never needs authentication. + needs_auth = False + +- j = json.loads(data) ++ j = byteify(json.loads(data)) + can_flush = "flush" in j['features'] + can_trim = "trim" in j['features'] + can_zero = "zero" in j['features'] +@@ -514,7 +527,7 @@ def close(h): + pass + + # Write the disk ID file. Only do this on successful completion. +- with builtins.open(params['diskid_file'], 'w') as fp: ++ with builtin_open(params['diskid_file'], 'w') as fp: + fp.write(disk.id) + + except: +diff --git a/v2v/rhv-upload-precheck.py b/v2v/rhv-upload-precheck.py +index 2798a29dd..5b650899f 100644 +--- a/v2v/rhv-upload-precheck.py ++++ b/v2v/rhv-upload-precheck.py +@@ -1,5 +1,6 @@ + # -*- python -*- +-# oVirt or RHV pre-upload checks used by ‘virt-v2v -o rhv-upload’ ++# coding: utf-8 ++# oVirt or RHV pre-upload checks used by 'virt-v2v -o rhv-upload' + # Copyright (C) 2018 Red Hat Inc. + # + # This program is free software; you can redistribute it and/or modify +@@ -21,8 +22,8 @@ import logging + import sys + import time + +-from http.client import HTTPSConnection +-from urllib.parse import urlparse ++from httplib import HTTPSConnection ++from urlparse import urlparse + + import ovirtsdk4 as sdk + import ovirtsdk4.types as types +@@ -36,8 +37,19 @@ if len(sys.argv) != 2: + raise RuntimeError("incorrect number of parameters") + + # Parameters are passed in via a JSON document. ++# https://stackoverflow.com/a/13105359 ++def byteify(input): ++ if isinstance(input, dict): ++ return {byteify(key): byteify(value) ++ for key, value in input.iteritems()} ++ elif isinstance(input, list): ++ return [byteify(element) for element in input] ++ elif isinstance(input, unicode): ++ return input.encode('utf-8') ++ else: ++ return input + with open(sys.argv[1], 'r') as fp: +- params = json.load(fp) ++ params = byteify(json.load(fp)) + + # What is passed in is a password file, read the actual password. + with open(params['output_password'], 'r') as fp: +@@ -67,7 +79,7 @@ vms = vms_service.list( + ) + if len(vms) > 0: + vm = vms[0] +- raise RuntimeError("VM already exists with name ‘%s’, id ‘%s’" % ++ raise RuntimeError("VM already exists with name '%s', id '%s'" % + (params['output_name'], vm.id)) + + # Otherwise everything is OK, exit with no error. +diff --git a/v2v/test-v2v-python-syntax.sh b/v2v/test-v2v-python-syntax.sh +index b167f4610..8d5924e3c 100755 +--- a/v2v/test-v2v-python-syntax.sh ++++ b/v2v/test-v2v-python-syntax.sh +@@ -25,7 +25,7 @@ skip_if_skipped + files="rhv-upload-createvm.py rhv-upload-plugin.py rhv-upload-precheck.py" + + # Base version of Python. +-python=python3 ++python=python + + # Checks the files are syntactically correct, but not very much else. + for f in $files; do +-- +2.17.1 + diff --git a/SOURCES/0080-launch-direct-Omit-locking-option-for-non-file-disks.patch b/SOURCES/0080-launch-direct-Omit-locking-option-for-non-file-disks.patch deleted file mode 100644 index a350111..0000000 --- a/SOURCES/0080-launch-direct-Omit-locking-option-for-non-file-disks.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 05095797e4adf7c5afa807972c25dbe0998f5bcf Mon Sep 17 00:00:00 2001 -From: Lars Seipel -Date: Thu, 23 Nov 2017 06:15:28 +0100 -Subject: [PATCH] launch: direct: Omit locking option for non-file disks - (RHBZ#1516094) - -QEMU does not accept options unrecognized by the block driver -in use. Disable locking only for read-only disks that are -file-backed, as that's the only block driver it is supported -with. - -Signed-off-by: Lars Seipel -(cherry picked from commit 35320dd0edb94d09d231bcded57aa883a5e7c784) ---- - lib/launch-direct.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/launch-direct.c b/lib/launch-direct.c -index 0fef05927..4f31ac231 100644 ---- a/lib/launch-direct.c -+++ b/lib/launch-direct.c -@@ -534,7 +534,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - escaped_file, - drv->disk_label ? ",serial=" : "", - drv->disk_label ? drv->disk_label : "", -- data->qemu_mandatory_locking ? ",file.backing.file.locking=off" : "", -+ data->qemu_mandatory_locking && drv->src.protocol == drive_protocol_file ? ",file.backing.file.locking=off" : "", - i); - } - --- -2.14.3 - diff --git a/SOURCES/0081-RHEL-7-v2v-rhv-upload-Disable-Nagle-algorithm.patch b/SOURCES/0081-RHEL-7-v2v-rhv-upload-Disable-Nagle-algorithm.patch new file mode 100644 index 0000000..61b826c --- /dev/null +++ b/SOURCES/0081-RHEL-7-v2v-rhv-upload-Disable-Nagle-algorithm.patch @@ -0,0 +1,75 @@ +From 61ae7a5e6deaac5cb9d9776829ea92ac0ebcc5f8 Mon Sep 17 00:00:00 2001 +From: Nir Soffer +Date: Fri, 15 Jun 2018 22:57:32 +0300 +Subject: [PATCH] RHEL 7: v2v: rhv-upload: Disable Nagle algorithm + +When sending a PUT request, the http header may be sent in the first +packet when calling con.endheaders(). When we send the first chunk, the +kernel may delay the send because the header packet was not acked yet. + +We have seen PUT requests delayed by 40 milliseconds on the server side +during virt-v2v upload to ovirt. Here is example log from current RHEL +virt-v2v version, uploading to RHV 4.2.3: + +2018-06-12 17:04:01,750 INFO (Thread-2) [images] Writing 52736 bytes +at offset 0 flush False to /path/to/image for ticket +374bec27-930d-4097-8e41-e4bc23324eb0 + +2018-06-12 17:04:01,790 INFO (Thread-2) [directio] Operation stats: + + +The server spent 40 milliseconds reading 52736 bytes form +rhv_upload_plugin running on the same host. + +This issue was fixed in python 3.5 by using the TCP_NO_DELAY option +after connecting[1]. I backported this change from python 3.5. + +I tested the same change using imageio example upload script. With this +change and with optimized PATCH requests, upload time of 4G sparse image +was reduced from 7 minutes to 1 minute. + +See this ovirt patch for more details: +https://gerrit.ovirt.org/#/c/92276/ + +This change is needed only for python 2. + +[1] https://bugs.python.org/issue23302 +--- + v2v/rhv-upload-plugin.py | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py +index 3d4ed1270..b262fb3d6 100644 +--- a/v2v/rhv-upload-plugin.py ++++ b/v2v/rhv-upload-plugin.py +@@ -25,7 +25,7 @@ import ssl + import sys + import time + +-from httplib import HTTPSConnection, HTTPConnection ++from httplib import HTTPSConnection as _HTTPSConnection, HTTPConnection + from urlparse import urlparse + + import ovirtsdk4 as sdk +@@ -51,6 +51,18 @@ def byteify(input): + return input + params = None + ++class HTTPSConnection(_HTTPSConnection): ++ def connect(self): ++ """ ++ Using TCP_NO_DELAY avoids delays when sending small payload, such as ++ ovirt PATCH requests. ++ ++ This issue was fixed in python 3.5, see: ++ https://bugs.python.org/issue23302 ++ """ ++ _HTTPSConnection.connect(self) ++ self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) ++ + def config(key, value): + global params + +-- +2.17.1 + diff --git a/SOURCES/0081-launch-direct-Use-old-style-file-and-format-paramete.patch b/SOURCES/0081-launch-direct-Use-old-style-file-and-format-paramete.patch deleted file mode 100644 index 6f809ef..0000000 --- a/SOURCES/0081-launch-direct-Use-old-style-file-and-format-paramete.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 6db3412d15981d7624817d06999cb2ef4a03eed7 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 17 Jan 2018 10:11:53 +0000 -Subject: [PATCH] launch: direct: Use old-style file= and format= parameters - when not disabling locking (RHBZ#1503497). -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Ancient qemu 1.5 (in RHEL 7) does not understand the -file.file.filename= and file.driver= parameters. Go back to using the -old-style file= and format= parameters when we're not trying to set -the file.backing.file.locking=off parameter. - -Fixes commit 9fe592808ccfd9ed184b88ca9c6cad2e1798dee3. - -Thanks: Yongkui Guo, Václav Kadlčík. -(cherry picked from commit a30b51747fc6605f50a9d5d8095fd2b6d1473b1c) ---- - lib/launch-direct.c | 32 +++++++++++++++++++++++++------- - 1 file changed, 25 insertions(+), 7 deletions(-) - -diff --git a/lib/launch-direct.c b/lib/launch-direct.c -index 4f31ac231..3d6e72e78 100644 ---- a/lib/launch-direct.c -+++ b/lib/launch-direct.c -@@ -529,13 +529,31 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) - else { - /* Writable qcow2 overlay on top of read-only drive. */ - escaped_file = guestfs_int_qemu_escape_param (g, drv->overlay); -- param = safe_asprintf -- (g, "file.file.filename=%s,cache=unsafe,file.driver=qcow2%s%s%s,id=hd%zu", -- escaped_file, -- drv->disk_label ? ",serial=" : "", -- drv->disk_label ? drv->disk_label : "", -- data->qemu_mandatory_locking && drv->src.protocol == drive_protocol_file ? ",file.backing.file.locking=off" : "", -- i); -+ if (data->qemu_mandatory_locking && -+ /* Add the file-specific locking option only for files, as -+ * qemu won't accept options unknown to the block driver in -+ * use. -+ */ -+ drv->src.protocol == drive_protocol_file) { -+ param = safe_asprintf -+ (g, "file.file.filename=%s,file.driver=qcow2,file.backing.file.locking=off,cache=unsafe%s%s,id=hd%zu", -+ escaped_file, -+ drv->disk_label ? ",serial=" : "", -+ drv->disk_label ? drv->disk_label : "", -+ i); -+ } else { -+ /* Ancient qemu (esp. qemu 1.5 in RHEL 7) didn't understand the -+ * file.file.filename= parameter, so use the safer old-style -+ * form of parameters unless we actually want to specify the -+ * locking flag above. -+ */ -+ param = safe_asprintf -+ (g, "file=%s,format=qcow2,cache=unsafe%s%s,id=hd%zu", -+ escaped_file, -+ drv->disk_label ? ",serial=" : "", -+ drv->disk_label ? drv->disk_label : "", -+ i); -+ } - } - - /* If there's an explicit 'iface', use it. Otherwise default to --- -2.14.3 - diff --git a/SOURCES/0082-RHEL-7-p2v-ignore-rhv-upload-driver-RHBZ-1590220.patch b/SOURCES/0082-RHEL-7-p2v-ignore-rhv-upload-driver-RHBZ-1590220.patch new file mode 100644 index 0000000..218f291 --- /dev/null +++ b/SOURCES/0082-RHEL-7-p2v-ignore-rhv-upload-driver-RHBZ-1590220.patch @@ -0,0 +1,33 @@ +From 66fa28613d7574cb2883478c541ed05e0f452058 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Thu, 19 Jul 2018 13:30:17 +0200 +Subject: [PATCH] RHEL 7: p2v: ignore 'rhv-upload' driver (RHBZ#1590220) + +The 'rhv-upload' output mode requires few options, and virt-p2v does not +have the GUI bits for specifying them. +--- + p2v/ssh.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/p2v/ssh.c b/p2v/ssh.c +index 15f53b692..654121a22 100644 +--- a/p2v/ssh.c ++++ b/p2v/ssh.c +@@ -1021,8 +1021,12 @@ add_input_driver (const char *name, size_t len) + static void + add_output_driver (const char *name, size_t len) + { +- /* Ignore the 'vdsm' driver, since that should only be used by VDSM. */ +- if (len != 4 || memcmp (name, "vdsm", 4) != 0) ++ /* Ignore the 'vdsm' driver, since that should only be used by VDSM. ++ * Ignore the 'rhv-upload' driver, since we do not support passing all the ++ * options for it. ++ */ ++ if ((len != 4 || memcmp (name, "vdsm", 4) != 0) && ++ (len != 10 || memcmp (name, "rhv-upload", 10) != 0)) + add_option ("output", &output_drivers, name, len); + } + +-- +2.17.1 + diff --git a/SOURCES/0082-customize-allow-missing-SELINUXTYPE-in-SELinux-confi.patch b/SOURCES/0082-customize-allow-missing-SELINUXTYPE-in-SELinux-confi.patch deleted file mode 100644 index 16a65ba..0000000 --- a/SOURCES/0082-customize-allow-missing-SELINUXTYPE-in-SELinux-confi.patch +++ /dev/null @@ -1,123 +0,0 @@ -From bd75249646ed03f4db3c5d0268db95ab8a0f39c8 Mon Sep 17 00:00:00 2001 -From: Pino Toscano -Date: Wed, 31 Jan 2018 12:29:15 +0100 -Subject: [PATCH] customize: allow missing SELINUXTYPE in SELinux config - -libselinux defaults to "targeted" when no SELINUXTYPE is specified in -/etc/config/selinux. Hence do the same here, instead of failing because -of the missing key. - -Add a slow test for checking SELinux relabeling on a Fedora 27 guest, -both with no changes, and with a modified configuration. - -(cherry picked from commit 719d68fa247cc3885ecf7ec1c010faf83267d786) ---- - customize/Makefile.am | 2 ++ - customize/SELinux_relabel.ml | 14 ++++++++++-- - customize/test-selinuxrelabel.sh | 49 ++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 63 insertions(+), 2 deletions(-) - create mode 100755 customize/test-selinuxrelabel.sh - -diff --git a/customize/Makefile.am b/customize/Makefile.am -index 07398b2e8..077194a1a 100644 ---- a/customize/Makefile.am -+++ b/customize/Makefile.am -@@ -23,6 +23,7 @@ EXTRA_DIST = \ - customize_main.ml \ - test-firstboot.sh \ - test-password.pl \ -+ test-selinuxrelabel.sh \ - test-settings.sh \ - test-virt-customize.sh \ - test-virt-customize-docs.sh \ -@@ -210,6 +211,7 @@ check-valgrind: - SLOW_TESTS = \ - $(firstboot_test_scripts) \ - $(password_test_scripts) \ -+ test-selinuxrelabel.sh \ - $(settings_test_scripts) - - check-slow: -diff --git a/customize/SELinux_relabel.ml b/customize/SELinux_relabel.ml -index 11999299b..b6f394ac2 100644 ---- a/customize/SELinux_relabel.ml -+++ b/customize/SELinux_relabel.ml -@@ -36,8 +36,18 @@ let relabel (g : G.guestfs) = - g#aug_load (); - debug_augeas_errors g; - -- (* Get the SELinux policy name, eg. "targeted", "minimum". *) -- let policy = g#aug_get "/files/etc/selinux/config/SELINUXTYPE" in -+ (* Get the SELinux policy name, eg. "targeted", "minimum". -+ * Use "targeted" if not specified, just like libselinux does. -+ *) -+ let policy = -+ let config_path = "/files/etc/selinux/config" in -+ let selinuxtype_path = config_path ^ "/SELINUXTYPE" in -+ let keys = g#aug_ls config_path in -+ if Array.mem selinuxtype_path keys then -+ g#aug_get selinuxtype_path -+ else -+ "targeted" in -+ - g#aug_close (); - - (* Get the spec file name. *) -diff --git a/customize/test-selinuxrelabel.sh b/customize/test-selinuxrelabel.sh -new file mode 100755 -index 000000000..d13c0356c ---- /dev/null -+++ b/customize/test-selinuxrelabel.sh -@@ -0,0 +1,49 @@ -+#!/bin/bash - -+# Test SELinux relabel functionality. -+# Copyright (C) 2018 Red Hat Inc. -+# -+# 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. -+ -+# This slow test checks that SELinux relabel works. -+ -+set -e -+ -+$TEST_FUNCTIONS -+slow_test -+ -+guestname="fedora-27" -+ -+disk="selinuxrelabel.img" -+disk_overlay="selinuxrelabel-overlay.qcow2" -+rm -f "$disk" -+ -+skip_unless_virt_builder_guest "$guestname" -+ -+# Build a guest (using virt-builder). -+virt-builder "$guestname" --quiet -o "$disk" -+ -+# Test #1: relabel with the default configuration works. -+rm -f "$disk_overlay" -+guestfish -- disk-create "$disk_overlay" qcow2 -1 backingfile:"$disk" -+virt-customize -a "$disk" --selinux-relabel -+ -+# Test #2: relabel with no SELINUXTYPE in the configuration. -+rm -f "$disk_overlay" -+guestfish -- disk-create "$disk_overlay" qcow2 -1 backingfile:"$disk" -+virt-customize -a "$disk" \ -+ --edit /etc/selinux/config:"s,^SELINUXTYPE=,#&,g" \ -+ --selinux-relabel -+ -+rm "$disk" "$disk_overlay" --- -2.14.3 - diff --git a/SOURCES/copy-patches.sh b/SOURCES/copy-patches.sh index 55eeb97..320561d 100755 --- a/SOURCES/copy-patches.sh +++ b/SOURCES/copy-patches.sh @@ -6,7 +6,7 @@ set -e # directory. Use it like this: # ./copy-patches.sh -rhel_version=7.5 +rhel_version=7.6 # Check we're in the right directory. if [ ! -f libguestfs.spec ]; then diff --git a/SOURCES/libguestfs-1.36.10.tar.gz.sig b/SOURCES/libguestfs-1.36.10.tar.gz.sig deleted file mode 100644 index 844b0b5..0000000 --- a/SOURCES/libguestfs-1.36.10.tar.gz.sig +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIcBAABAgAGBQJZ6IBGAAoJEJFzj3Pht2igIyoQAKMmpv4f5kICU7LHte5uj7vi -HY26QAPwlHe1YLDgfd8rPp3EIClqOP+F75mDdL2OBE8wmd8GSD2zWZF7RXtS90x3 -Q5DsBWfDrKrJPGZ/UfjrlKhbFSUui1yK/V6fMfw2RyLZmNgh3ykwxwsx7RmdcqYz -/8ejIveqDHazvRdGHkCIXF8eAec+oYPMpmjufmoEMrkMTTcLQSUxZ0MvMC14L0z7 -K8lMp7UOa0P72GY3RYawgqIDKF1IbgTuNEeHb+7GXWjFELgqgRIyT/AQBduEdZEi -dDPWTJgsX1px7HLiTG43FsdDDs0hIpI3l89BrgPX6IB1JlqGig4fg4HovlpS9B3U -QMLSQORIjZUcViq2qHe2978ZaY1cV9R4oB0MYZxOVS/v7h8ED8aS5BmJTp+VBK8Y -D9uhyebmGaDeIkRvxeqdDwsQcQb+kS8ivdw9keWguEYozG+G67p9LYg8jl/8bHek -lktoJvIhrWdW0PrSIGrl++RJ4l/kv6jJsdpGwsySK2H4n7MeXangkxFtTluZpiWA -0UoF6C0xnV2KfOPGODwOtrkGiU/k+0BGANZOqpMbqofaLV8mS4FnVsRtDyiVUN0R -Q5RmrAvgfMt+vd0K57n55dr2+jxDtPtdGp/h2DD4g4uuacCe0jlUp1i+DYUi1H5/ -B3iWuIQHXwboqotBOtNQ -=KIqK ------END PGP SIGNATURE----- diff --git a/SOURCES/libguestfs-1.38.2.tar.gz.sig b/SOURCES/libguestfs-1.38.2.tar.gz.sig new file mode 100644 index 0000000..e0286f8 --- /dev/null +++ b/SOURCES/libguestfs-1.38.2.tar.gz.sig @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIcBAABAgAGBQJa/CJEAAoJEJFzj3Pht2igY10QAK2BLfAYb2CUntgIKlxWYbXd +5/gF6EvyH7l8/jD2sGcokPVY/8xYYEtu4HifbsW6QJttFTureujAFcaDb4KhL1Z2 +yLcu4HhqWWC5pO6LJUY7pUF+3ZaAPyHr3fUhniqA8VTwrn0rKRh9HVNPEa2IHZG+ +rE0MGMSPk/HKN6f3JDXE7BSSYaEaMNPWuaVW5KxLAEjCN5bl4lbjs1HJe6BGnNaG +TXRa8p+Dehpgp8g3qagtSKJQKTiq2kVkxLIj5mABeEVAbht3grfKlacaOIFq609s +rB/u0Z6fHEweCS1jpcR7CY3hQm2lHqCDfBWhR88ucvk0n3KACwfV2NixyqDc2J9V +R7OWUu5HxAKWd1J6N8SqODBHQcUhoBUOfMHN2dzd00OptgTI/yuyBw5oEWLJ8DP/ +3s8AWywyWT2LsZp4IavLqqRvF1Glm72N65k4iUVXngNVjSOtGZH8Eh/rYt+1PWKb +UZ6LhKOSRq4XsU8/E8168y2vXr77JHzqt9XX7B6sbV92OUDOxVOYtp7NfwhUx+VC +qCM5YEVqdT2Lf146LpC0Ng2Mhw9pYT3Vl5GL4lFzBeMn4J1T+LjRJDhZsVc3hjly +ChkCVURdI+xQMWbaUOyeelUf6V9WZvW9+hb9K3oDsGbs6KVyTciZWpM97nNz42dQ +x/rjwIVwRuoRWfwK+RCS +=5XhU +-----END PGP SIGNATURE----- diff --git a/SPECS/libguestfs.spec b/SPECS/libguestfs.spec index 4eee5e1..a9bfcfa 100644 --- a/SPECS/libguestfs.spec +++ b/SPECS/libguestfs.spec @@ -1,5 +1,12 @@ %global _hardened_build 1 +# 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 +%global v2v_arches x86_64 + # Trim older changelog entries. # https://lists.fedoraproject.org/pipermail/devel/2013-April/thread.html#181627 %global _changelog_trimtime %(date +%s -d "2 years ago") @@ -13,22 +20,22 @@ Summary: Access and modify virtual machine disk images Name: libguestfs Epoch: 1 -Version: 1.36.10 -Release: 6%{?dist}.2 +Version: 1.38.2 +Release: 12%{?dist} License: LGPLv2+ # Source and patches. URL: http://libguestfs.org/ -Source0: http://libguestfs.org/download/1.36-stable/%{name}-%{version}.tar.gz +Source0: http://libguestfs.org/download/1.38-stable/%{name}-%{version}.tar.gz %if 0%{verify_tarball_signature} -Source1: http://libguestfs.org/download/1.36-stable/%{name}-%{version}.tar.gz.sig +Source1: http://libguestfs.org/download/1.38-stable/%{name}-%{version}.tar.gz.sig %endif ExclusiveArch: x86_64 %{power64} aarch64 s390x # RHEL 7 git repository is: -# https://github.com/libguestfs/libguestfs/tree/rhel-7.5 +# https://github.com/libguestfs/libguestfs/tree/rhel-7.6 # Use 'copy-patches.sh' to copy the patches from the git repo # to the current directory. @@ -39,82 +46,82 @@ Patch0003: 0003-RHEL-7-Disable-unsupported-remote-drive-protocols-RH.patch Patch0004: 0004-RHEL-7-Remove-User-Mode-Linux-RHBZ-1144197.patch Patch0005: 0005-RHEL-7-v2v-Select-correct-qemu-binary-for-o-qemu-mod.patch Patch0006: 0006-RHEL-7-v2v-Disable-the-qemu-boot-option-RHBZ-1147313.patch -Patch0007: 0007-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch -Patch0008: 0008-RHEL-7-Revert-appliance-Change-example-ping-lines-to.patch -Patch0009: 0009-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch -Patch0010: 0010-RHEL-7-Revert-launch-libvirt-Better-error-when-bridg.patch -Patch0011: 0011-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch -Patch0012: 0012-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch -Patch0013: 0013-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch -Patch0014: 0014-RHEL-7-Disable-alternate-Augeas-lenses.patch -Patch0015: 0015-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch -Patch0016: 0016-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch -Patch0017: 0017-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch -Patch0018: 0018-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch -Patch0019: 0019-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch -Patch0020: 0020-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch -Patch0021: 0021-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch -Patch0022: 0022-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch -Patch0023: 0023-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch -Patch0024: 0024-RHEL-7-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch -Patch0025: 0025-RHEL-7-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch -Patch0026: 0026-sysprep-Remove-DHCP_HOSTNAME-from-ifcfg-files-RHBZ-1.patch -Patch0027: 0027-p2v-Run-fewer-scp-commands.patch -Patch0028: 0028-p2v-Fix-list-of-files-in-documentation.patch -Patch0029: 0029-p2v-tests-Fix-fake-scp-command-so-it-can-handle-mult.patch -Patch0030: 0030-v2v-Implement-i-vmx-to-read-VMware-vmx-files-directl.patch -Patch0031: 0031-v2v-tests-Fix-i-vmx-test-so-it-is-more-stable.patch -Patch0032: 0032-RHEL-7-v2v-disable-unconfig-of-manually-installed-VM.patch -Patch0033: 0033-v2v-i-ova-Prefer-pigz-or-pxz-for-uncompressing-OVA-f.patch -Patch0034: 0034-v2v-add-crypto-support-RHBZ-1451665.patch -Patch0035: 0035-v2v-Implement-input-from-nbdkit-vddk-plugin-RHBZ-147.patch -Patch0036: 0036-s390x-launch-libvirt-Use-console-device-sclp-for-app.patch -Patch0037: 0037-s390x-launch-direct-Use-sclp-as-serial-console-on-th.patch -Patch0038: 0038-s390x-appliance-Use-dev-ttysclp0-for-serial-console.patch -Patch0039: 0039-init-Add-comment-that-we-should-consider-using-proc-.patch -Patch0040: 0040-s390x-launch-direct-Use-virtio-ccw-on-this-architect.patch -Patch0041: 0041-s390x-tests-regressions-Skip-IDE-tests-on-S-390.patch -Patch0042: 0042-lib-Add-VIRTIO_DEVICE_NAME-macro-to-handle-virtio-mm.patch -Patch0043: 0043-v2v-i-vmx-Allow-deviceType-field-to-be-completely-om.patch -Patch0044: 0044-v2v-i-vmx-Add-a-test-case-which-lacks-scsi0-0.device.patch -Patch0045: 0045-v2v-vddk-Print-passthrough-options.patch -Patch0046: 0046-v2v-vddk-Check-if-nbdkit-supports-selinux-label-befo.patch -Patch0047: 0047-v2v-vddk-Force-source-format-to-raw.patch -Patch0048: 0048-v2v-Remove-dcpath-parameter-and-related-functionalit.patch -Patch0049: 0049-v2v-vCenter-Refactor-the-API-to-this-module.patch -Patch0050: 0050-v2v-vCenter-Split-up-get_session_cookie-function.patch -Patch0051: 0051-v2v-vCenter-Factor-out-get_https_url-code.patch -Patch0052: 0052-v2v-vCenter-Handle-disks-with-snapshots-RHBZ-1172425.patch -Patch0053: 0053-generator-Deprecate-direct-mode-guestfs_set_direct-g.patch -Patch0054: 0054-New-API-internal-get-console-socket-to-support-virt-.patch -Patch0055: 0055-lib-Return-EPIPE-for-appliance-closed-the-connection.patch -Patch0056: 0056-rescue-Modify-virt-rescue-so-it-doesn-t-use-direct-m.patch -Patch0057: 0057-rescue-Implement-m-and-i-options.patch -Patch0058: 0058-rescue-Implement-escape-sequences.patch -Patch0059: 0059-rescue-Move-suggest-code-to-separate-file.patch -Patch0060: 0060-rescue-docs-It-is-no-longer-necessary-to-mount-files.patch -Patch0061: 0061-rescue-docs-Note-that-you-can-run-virt-rescue-on-dis.patch -Patch0062: 0062-rescue-Don-t-document-suggest-option-in-help-output.patch -Patch0063: 0063-v2v-bootloaders-search-grub-config-for-all-distribut.patch -Patch0064: 0064-rescue-fix-size-check.patch -Patch0065: 0065-rescue-initialize-CLEANUP-pointer-variable.patch -Patch0066: 0066-v2v-i-ova-parse-MAC-address-from-rasd-Address-RHBZ-1.patch -Patch0067: 0067-v2v-Fix-RPM-file-owned-test-RHBZ-1503958.patch -Patch0068: 0068-v2v-bootloaders-handle-no-default-grubby-kernel-RHBZ.patch -Patch0069: 0069-lib-libvirt-stop-using-shareable-for-appliance-disk-.patch -Patch0070: 0070-v2v-vddk-Make-it-clearer-that-you-should-not-run-nbd.patch -Patch0071: 0071-podwrapper-nbdkit-man-pages-are-libguestfs-man-pages.patch -Patch0072: 0072-v2v-vddk-Update-minimum-version-of-nbdkit-to-1.1.16.patch -Patch0073: 0073-v2v-vddk-Further-rework-documentation.patch -Patch0074: 0074-v2v-docs-Remove-min-version-of-VDDK-recommend-nbdkit.patch -Patch0075: 0075-v2v-docs-State-that-vddk-thumbprint-is-only-required.patch -Patch0076: 0076-v2v-vddk-Switch-to-using-it-vddk-to-specify-VDDK-as-.patch -Patch0077: 0077-v2v-i-vmx-Enhance-VMX-support-with-ability-to-use-it.patch -Patch0078: 0078-builder-use-the-template-arch-when-caching-all-templ.patch -Patch0079: 0079-v2v-docs-Match-the-two-instances-of-path-to-nbdkit-i.patch -Patch0080: 0080-launch-direct-Omit-locking-option-for-non-file-disks.patch -Patch0081: 0081-launch-direct-Use-old-style-file-and-format-paramete.patch -Patch0082: 0082-customize-allow-missing-SELINUXTYPE-in-SELinux-confi.patch +Patch0007: 0007-RHEL-7-move-VIRTIO_DEVICE_NAME-macro-to-guestfs-inte.patch +Patch0008: 0008-RHEL-7-Revert-tests-rsync-Skip-this-test-when-the-ba.patch +Patch0009: 0009-RHEL-7-Revert-appliance-Change-example-ping-lines-to.patch +Patch0010: 0010-RHEL-7-Revert-launch-libvirt-Use-qemu-bridge-helper-.patch +Patch0011: 0011-RHEL-7-Revert-launch-libvirt-Better-error-when-bridg.patch +Patch0012: 0012-RHEL-7-Revert-appliance-add-dhcp-client-on-Mageia.patch +Patch0013: 0013-RHEL-7-Revert-appliance-add-dhcpcd-and-gptfdisk-on-A.patch +Patch0014: 0014-RHEL-7-Revert-appliance-Use-dhclient-or-dhcpcd-inste.patch +Patch0015: 0015-RHEL-7-Disable-alternate-Augeas-lenses.patch +Patch0016: 0016-RHEL-7-Fix-list-of-supported-sound-cards-to-match-RH.patch +Patch0017: 0017-RHEL-7-v2v-efi-Remove-references-to-Fedora-kraxel-s-.patch +Patch0018: 0018-RHEL-7-Reject-use-of-libguestfs-winsupport-features-.patch +Patch0019: 0019-RHEL-7-daemon-umount-all-Hack-to-avoid-umount-sysroo.patch +Patch0020: 0020-RHEL-7-Fix-tests-for-libguestfs-winsupport-7.2.patch +Patch0021: 0021-RHEL-7-Revert-v2v-Add-a-support-matrix-to-the-manual.patch +Patch0022: 0022-RHEL-7-All-qemu-kvm-in-RHEL-7-supports-discard-of-qc.patch +Patch0023: 0023-RHEL-7-tests-Disable-daemon-tests-that-require-the-u.patch +Patch0024: 0024-RHEL-7-v2v-Disable-the-virt-v2v-in-place-option.patch +Patch0025: 0025-RHEL-7-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch +Patch0026: 0026-RHEL-7-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-143020.patch +Patch0027: 0027-RHEL-7-v2v-disable-unconfig-of-manually-installed-VM.patch +Patch0028: 0028-v2v-Use-Std_utils.qemu_input_filename-instead-of-pre.patch +Patch0029: 0029-v2v-o-null-support-older-qemu-img-RHBZ-1580309.patch +Patch0030: 0030-v2v-ovf-Create-OVF-more-aligned-with-the-standard.patch +Patch0031: 0031-v2v-vdsm-add-vdsm-fixed-ovf-option.patch +Patch0032: 0032-v2v-OVF-Code-formatting.patch +Patch0033: 0033-v2v-DOM-Add-doc_to_string-function.patch +Patch0034: 0034-v2v-Add-op-output-password-file-option.patch +Patch0035: 0035-v2v-cmdline-Move-definition-to-before-its-only-use.patch +Patch0036: 0036-v2v-Add-general-mechanism-for-input-and-output-optio.patch +Patch0037: 0037-v2v-OVF-write-ovirt-id-attribute-for-the-OS-in-OVirt.patch +Patch0038: 0038-v2v-OVF-fix-ovf-id-for-VirtualSystem-in-OVirt-flavou.patch +Patch0039: 0039-v2v-Add-o-rhv-upload-output-mode-RHBZ-1557273.patch +Patch0040: 0040-v2v-refer-to-the-right-embed-script-in-EXTRA_DIST.patch +Patch0041: 0041-v2v-o-rhv-upload-Don-t-require-of-raw-parameter.patch +Patch0042: 0042-v2v-o-rhv-upload-install-RHV-tools-RHBZ-1561828.patch +Patch0043: 0043-v2v-Map-Windows-Server-2012-R2-x86-64-to-ovirt-ID-25.patch +Patch0044: 0044-v2v-fix-build-rules-for-output_rhv_upload_-_source.m.patch +Patch0045: 0045-v2v-fix-rhevexp-typo-in-documentation.patch +Patch0046: 0046-v2v-add-and-use-Create_ovf.ovf_flavour_to_string.patch +Patch0047: 0047-daemon-Move-lvmetad-to-early-in-the-appliance-boot-p.patch +Patch0048: 0048-v2v-o-rhv-upload-Set-inactivity-timeout-RHBZ-1586198.patch +Patch0049: 0049-v2v-linux-fix-kernel-detection-when-split-in-differe.patch +Patch0050: 0050-New-API-inspect_get_osinfo.patch +Patch0051: 0051-inspector-show-the-per-OS-osinfo-guess-RHBZ-1544842.patch +Patch0052: 0052-lib-libvirt-Convert-all-socket-parameters-to-an-abso.patch +Patch0053: 0053-v2v-o-rhv-upload-Optimize-http-request-sending.patch +Patch0054: 0054-v2v-o-rhv-upload-Log-full-imageio-response-on-failur.patch +Patch0055: 0055-v2v-Add-Disk-ovf-capacity-attribute-containing-disk-.patch +Patch0056: 0056-v2v-File-ovf-size-changed-to-the-actual-size-if-know.patch +Patch0057: 0057-p2v-Allow-virt-v2v-input-and-output-drivers-containi.patch +Patch0058: 0058-v2v-o-libvirt-Don-t-write-only-vendor-without-model-.patch +Patch0059: 0059-v2v-rvh-upload-plugin-Always-read-the-response.patch +Patch0060: 0060-v2v-rhv-upload-plugin-Fix-name-error.patch +Patch0061: 0061-v2v-rhv-upload-plugin-Remove-unused-variables.patch +Patch0062: 0062-v2v-o-rhv-upload-Always-fetch-server-options-when-op.patch +Patch0063: 0063-v2v-o-rhv-upload-Use-Unix-domain-socket-to-access-im.patch +Patch0064: 0064-v2v-improve-os-documentation-for-rhv-upload.patch +Patch0065: 0065-v2v-rhv-upload-plugin-Remove-unneeded-auth.patch +Patch0066: 0066-v2v-rhv-upload-plugin-Improve-error-handling.patch +Patch0067: 0067-v2v-rhv-upload-plugin-Optimize-only-direct-upload.patch +Patch0068: 0068-v2v-rhv-plugin-find-suitable-host-RHBZ-1596810-RHBZ-.patch +Patch0069: 0069-v2v-change-QXL-ResourceType-in-OVirt-flavour-RHBZ-15.patch +Patch0070: 0070-v2v-o-rhv-upload-check-for-ovirtsdk4-RHBZ-1601943.patch +Patch0071: 0071-v2v-rhv-plugin-fix-DC-search-string.patch +Patch0072: 0072-v2v-rhv-plugin-case-sensitive-search-queries.patch +Patch0073: 0073-Revert-lvm-do-not-pass-cache-to-vgscan.patch +Patch0074: 0074-daemon-inspect-ignore-fstab-devs-that-cannot-be-reso.patch +Patch0075: 0075-v2v-parse_libvirt_xml-handle-srN-CDROM-devices-RHBZ-.patch +Patch0076: 0076-v2v-o-rhv-upload-Fix-error-message-disk-numbering-RH.patch +Patch0077: 0077-v2v-o-rhv-upload-Properly-replace-SD_UUID-in-OVF-RHB.patch +Patch0078: 0078-ppc64le-Don-t-use-cpu-parameter-under-any-circumstan.patch +Patch0079: 0079-RHEL-7-v2v-rhv-upload-Remove-restriction-on-oa-spars.patch +Patch0080: 0080-RHEL-7-o-rhv-upload-Use-Python-2-instead-of-Python-3.patch +Patch0081: 0081-RHEL-7-v2v-rhv-upload-Disable-Nagle-algorithm.patch +Patch0082: 0082-RHEL-7-p2v-ignore-rhv-upload-driver-RHBZ-1590220.patch # Use git for patch management. BuildRequires: git @@ -142,7 +149,7 @@ Source7: libguestfs.keyring # RHEV-APT is taken from the RHEV Tools CD # See https://bugzilla.redhat.com/show_bug.cgi?id=1186850 Source96: rhsrvany.exe -Source97: RHEV-Application-Provisioning-Tool.exe_4.12 +Source97: RHEV-Application-Provisioning-Tool.exe_4.42 Source98: brew-overrides.sh Source99: copy-patches.sh @@ -151,6 +158,7 @@ Source99: copy-patches.sh BuildRequires: gcc BuildRequires: supermin5-devel >= 5.1.16-2 BuildRequires: hivex-devel >= 1.3.10-5.8.el7 +BuildRequires: ocaml-hivex-devel BuildRequires: perl(Pod::Simple) BuildRequires: perl(Pod::Man) BuildRequires: /usr/bin/pod2text @@ -279,7 +287,6 @@ Requires: lvm2 >= 7:2.02.166-1.el7 # For core inspection API. Requires: libdb-utils -Requires: osinfo-db # For core mount-local (FUSE) API. Requires: fuse @@ -470,6 +477,9 @@ Requires: xz #Requires: nbdkit, nbdkit-plugin-xz Requires: curl +# for virt-builder-repository: +Requires: osinfo-db + %description tools-c This package contains miscellaneous system administrator command line @@ -585,7 +595,7 @@ diskimage-builder command. It is compatible with most diskimage-builder elements. -%ifnarch %{power64} s390x +%ifarch %{v2v_arches} %package -n virt-v2v Summary: Convert a virtual machine to run on KVM License: GPLv2+ @@ -616,13 +626,17 @@ Requires: OVMF Requires: AAVMF %endif +# Needed for -it vddk, and -o rhv-upload. +Requires: nbdkit +Requires: nbdkit-plugin-python2 +Requires: nbdkit-plugin-vddk + %description -n virt-v2v Virt-v2v converts virtual machines from non-KVM hypervisors to run under KVM. To convert physical machines, see the virt-p2v-maker package. -%endif %package -n virt-p2v-maker @@ -649,6 +663,7 @@ conversion. You also need virt-v2v installed somewhere else to complete the conversion. To convert virtual machines from other hypervisors, see virt-v2v. +%endif %package bash-completion @@ -776,7 +791,9 @@ To develop software against these bindings, you need to install %package gobject-devel Summary: GObject bindings for %{name} Requires: %{name}-gobject = %{epoch}:%{version}-%{release} -Requires: gtk-doc + +Provides: libguestfs-gobject-doc = %{epoch}:%{version}-%{release} +Obsoletes: libguestfs-gobject-doc < %{epoch}:%{version}-%{release} %description gobject-devel %{name}-gobject contains GObject bindings for %{name}. @@ -785,16 +802,6 @@ This package is needed if you want to write software using the GObject bindings. It also contains GObject Introspection information. -%package gobject-doc -Summary: Documentation for %{name} GObject bindings -BuildArch: noarch -Requires: %{name}-gobject-devel = %{epoch}:%{version}-%{release} - -%description gobject-doc -%{name}-gobject-doc contains documentation for -%{name} GObject bindings. - - %package man-pages-ja Summary: Japanese (ja) man pages for %{name} BuildArch: noarch @@ -1012,8 +1019,7 @@ 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 -%ifarch %{power64} s390x -# We don't ship virt-v2v on POWER (RHBZ#1287826). +%ifnarch %{v2v_arches} rm $RPM_BUILD_ROOT%{_bindir}/virt-p2v* rm $RPM_BUILD_ROOT%{_bindir}/virt-v2v* rm $RPM_BUILD_ROOT%{_mandir}/man1/virt-p2v* @@ -1030,7 +1036,7 @@ rm -rf $RPM_BUILD_ROOT%{_libdir}/ocaml/v2v_test_harness rm -rf $RPM_BUILD_ROOT%{_libdir}/ocaml/stublibs/dllv2v_test_harness* rm -f $RPM_BUILD_ROOT%{_mandir}/man1/virt-v2v-test-harness.1* -%ifnarch %{power64} s390x +%ifarch %{v2v_arches} # Delete kiwi tools. rm $RPM_BUILD_ROOT%{_bindir}/virt-p2v-make-kiwi rm $RPM_BUILD_ROOT%{_mandir}/man1/virt-p2v-make-kiwi.1* @@ -1141,6 +1147,8 @@ install -m 0644 utils/boot-benchmark/boot-benchmark.1 $RPM_BUILD_ROOT%{_mandir}/ %{_mandir}/man1/virt-alignment-scan.1* %{_bindir}/virt-builder %{_mandir}/man1/virt-builder.1* +%{_bindir}/virt-builder-repository +%{_mandir}/man1/virt-builder-repository.1* %{_bindir}/virt-cat %{_mandir}/man1/virt-cat.1* %{_bindir}/virt-copy-in @@ -1200,7 +1208,7 @@ install -m 0644 utils/boot-benchmark/boot-benchmark.1 $RPM_BUILD_ROOT%{_mandir}/ %{_libdir}/guestfs/supermin.d/zz-packages-dib -%ifnarch %{power64} s390x +%ifarch %{v2v_arches} %files -n virt-v2v %doc COPYING README v2v/TODO %{_bindir}/virt-v2v @@ -1307,10 +1315,7 @@ install -m 0644 utils/boot-benchmark/boot-benchmark.1 $RPM_BUILD_ROOT%{_mandir}/ %{_includedir}/guestfs-gobject/*.h %{_datadir}/gir-1.0/Guestfs-1.0.gir %{_libdir}/pkgconfig/libguestfs-gobject-1.0.pc - - -%files gobject-doc -%{_datadir}/gtk-doc/html/guestfs +%{_mandir}/man3/guestfs-gobject.3* %files man-pages-ja @@ -1326,13 +1331,59 @@ install -m 0644 utils/boot-benchmark/boot-benchmark.1 $RPM_BUILD_ROOT%{_mandir}/ %changelog -* Mon Apr 23 2018 Pino Toscano - 1:1.36.10-6.el7_5.2 -- Fix qemu-img-ma dependency - resolves: rhbz#1570533 - -* Thu Mar 29 2018 Pino Toscano - 1:1.36.10-6.el7_5.1 +* Fri Aug 31 2018 Pino Toscano - 1:1.38.2-12 +- Rebase to libguestfs 1.38.2 in RHEL 7.6. + resolves: rhbz#1551055 +- v2v: warn about unknown VMware controller types + resolves: rhbz#1510801 +- df: show correct sizes in human-readable mode for filesystems with + block size = 512 + resolves: rhbz#1525262 +- v2v: fix example URL in man page + resolves: rhbz#1540535 - Fix SELinux relabelling when the SELinux config has no SELINUXTYPE key - resolves: rhbz#1558922 + resolves: rhbz#1541525 +- Fix qemu-img-ma dependency in non-x86_64 architectures + resolves: rhbz#1568676 +- v2v: update "resume=/dev/sdaX" entries in GRUB command lines + resolves: rhbz#1532224 +- v2v: fix virtio-rng and memballoon OVF fragment for RHV + resolves: rhbz#1550168 +- v2v: detect whether the root filesystem was not mounted in read-write mode + resolves: rhbz#1567763 +- v2v: import OVAs with snapshots + resolves: rhbz#1570407 +- v2v: ship a newer version of rhev-apt.exe + resolves: rhbz#1571237 +- Move the osinfo-db dependency to libguestfs-tools-c, since it's the only + place where it used now (by virt-builder-repository). +- v2v: new 'rhv-upload' method to stream images directly to oVirt/RHV using + oVirt REST API + resolves: rhbz#1557273 +- Start lvmetad earlier when booting the appliance + resolves: rhbz#1581810 +- v2v: fix kernel detection in Ubuntu guests since 18.04 + resolves: rhbz#1591248 +- v2v: convert the CPU topology correctly + resolves: rhbz#1541908 +- Add a new inspect_get_osinfo API, and add its result to the output of + virt-inspector + resolves: rhbz#1544842 +- Pass absolute paths to NBD sockets when using the libvirt backend + resolves: rhbz#1588451 +- v2v: do not write only without in libvirt XMLs + resolves: rhbz#1591789 +- v2v: depend on nbdkit, nbdkit-plugin-python2, and nbdkit-plugin-vddk, + used for -it vddk, and -o rhv-upload + resolves: rhbz#1589776 + resolves: rhbz#1608718 +- v2v/p2v: disable on aarch64, since it is not supported (nor even working) + there + resolves: rhbz#1601488 +- v2v: handle srN devices in libvirt XML (for virt-p2v) + resolves: rhbz#1612785 +- Do not use the -cpu parameter under any circumstances for ppc64le. + resolves: rhbz#1605071 * Mon Jan 22 2018 Pino Toscano - 1:1.36.10-6 - Rebase to libguestfs 1.36.10 in RHEL 7.5.