From b75d10f0d5ee9018b7a5000643039880a62f455e Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 29 Aug 2025 13:16:02 +0100 Subject: [PATCH] Rebase to virt-v2v 2.9.5 resolves: RHEL-111241 --- ...ify-server-certificate-docs-to-alpha.patch | 47 - ...m4-IPC-Run3-is-now-required-by-podwr.patch | 25 + ...RHEL-Fixes-for-libguestfs-winsupport.patch | 40 +- ....ml-Fix-escaping-of-export-.-paramet.patch | 67 - ...gure_pnputil_install-script-to-check.patch | 76 - ...correct-qemu-binary-for-o-qemu-mode-.patch | 6 +- ...-the-qemu-boot-oo-qemu-boot-option-R.patch | 14 +- 0004-Update-the-common-submodule.patch | 50 - ...OR_NO_MORE_ITEMS-status-from-PnPUtil.patch | 27 - ...-supported-sound-cards-to-match-RHEL.patch | 2 +- ...sk-force-VNC-as-display-RHBZ-1372671.patch | 4 +- ...rsion-of-libnbd-nbdcopy-in-debug-out.patch | 50 - ...-for-supported-v2v-hypervisors-guest.patch | 2 +- ...vddk-Remove-io-vddk-noextents-option.patch | 101 - ...=> 0008-RHEL-tests-Remove-btrfs-test.patch | 4 +- ...sh-vddk-file-Add-nbdkit-count-filter.patch | 114 - ...-about-virt-v2v-in-place-not-being-s.patch | 8 +- ...o-disk-to-allow-disk-names-to-be-ove.patch | 233 - ...d-on-libguestfs-1.56.1-2.el10-for-gu.patch | 2 +- ...output-Add-optional-create-parameter.patch | 141 - ...o-create-false-to-avoid-disk-creatio.patch | 119 - 0018-RHEL-Remove-input-from-Xen.patch | 543 -- 0019-RHEL-Remove-o-glance.patch | 239 - 0021-RHEL-Remove-block-driver-option.patch | 157 - ...virt-o-ovirt-upload-and-o-vdsm-modes.patch | 4712 ----------------- ...before-installing-virtio-win-drivers.patch | 24 - 0025-v2v-Fix-SELinux-relabelling.patch | 81 - 0027-convert-Model-target-boot-device.patch | 98 - ...order-depending-on-target-boot-devic.patch | 184 - ...-target-boot-device-for-Linux-guests.patch | 78 - copy-patches.sh | 2 +- sources | 4 +- virt-v2v.spec | 184 +- 33 files changed, 181 insertions(+), 7257 deletions(-) delete mode 100644 0001-docs-Move-oo-verify-server-certificate-docs-to-alpha.patch create mode 100644 0001-m4-guestfs-perl.m4-IPC-Run3-is-now-required-by-podwr.patch rename 0012-RHEL-Fixes-for-libguestfs-winsupport.patch => 0002-RHEL-Fixes-for-libguestfs-winsupport.patch (83%) delete mode 100644 0002-input-input_vddk.ml-Fix-escaping-of-export-.-paramet.patch delete mode 100644 0003-Modify-configure_pnputil_install-script-to-check.patch rename 0013-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch => 0003-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch (87%) rename 0014-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch => 0004-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch (88%) delete mode 100644 0004-Update-the-common-submodule.patch delete mode 100644 0005-Ignore-ERROR_NO_MORE_ITEMS-status-from-PnPUtil.patch rename 0015-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch => 0005-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch (92%) rename 0016-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch => 0006-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch (89%) delete mode 100644 0006-v2v-Print-the-version-of-libnbd-nbdcopy-in-debug-out.patch rename 0017-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch => 0007-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch (97%) delete mode 100644 0007-vddk-Remove-io-vddk-noextents-option.patch rename 0020-RHEL-tests-Remove-btrfs-test.patch => 0008-RHEL-tests-Remove-btrfs-test.patch (86%) delete mode 100644 0008-curl-ssh-vddk-file-Add-nbdkit-count-filter.patch rename 0023-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch => 0009-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch (88%) delete mode 100644 0009-o-kubevirt-Add-oo-disk-to-allow-disk-names-to-be-ove.patch rename 0026-RHEL-10-m4-Depend-on-libguestfs-1.56.1-2.el10-for-gu.patch => 0010-RHEL-10-m4-Depend-on-libguestfs-1.56.1-2.el10-for-gu.patch (92%) delete mode 100644 0010-output-Add-optional-create-parameter.patch delete mode 100644 0011-o-kubevirt-Add-oo-create-false-to-avoid-disk-creatio.patch delete mode 100644 0018-RHEL-Remove-input-from-Xen.patch delete mode 100644 0019-RHEL-Remove-o-glance.patch delete mode 100644 0021-RHEL-Remove-block-driver-option.patch delete mode 100644 0022-RHEL-Remove-o-ovirt-o-ovirt-upload-and-o-vdsm-modes.patch delete mode 100644 0024-remove-timeout-before-installing-virtio-win-drivers.patch delete mode 100644 0025-v2v-Fix-SELinux-relabelling.patch delete mode 100644 0027-convert-Model-target-boot-device.patch delete mode 100644 0028-output-Add-boot-order-depending-on-target-boot-devic.patch delete mode 100644 0029-convert-Detect-target-boot-device-for-Linux-guests.patch diff --git a/0001-docs-Move-oo-verify-server-certificate-docs-to-alpha.patch b/0001-docs-Move-oo-verify-server-certificate-docs-to-alpha.patch deleted file mode 100644 index 427ccb7..0000000 --- a/0001-docs-Move-oo-verify-server-certificate-docs-to-alpha.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 7566e3e433bd6ea44785b08164506fd013fe2b51 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 8 Jul 2025 11:11:48 +0100 -Subject: [PATCH] docs: Move -oo verify-server-certificate docs to alphabetical - place - -This option wasn't in alphabetical order. - -(cherry picked from commit 378967fc4984af4f06c586886a1148aebede8cff) ---- - docs/virt-v2v.pod | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod -index 3cfb0948..3eefe404 100644 ---- a/docs/virt-v2v.pod -+++ b/docs/virt-v2v.pod -@@ -611,14 +611,6 @@ volume property. - When using I<-o qemu> only, this boots the guest immediately after - virt-v2v finishes. - --=item B<-oo verify-server-certificate> -- --=item B<-oo verify-server-certificate=>C -- --For I<-o openstack> (L) only, this can --be used to disable SSL certification validation when connecting to --OpenStack by specifying I<-oo verify-server-certificate=false>. -- - =item B<-oo os->*B<=>* - - For I<-o openstack> (L) only, set optional -@@ -736,6 +728,14 @@ The OVF format understood by oVirt REST API. - For backward compatibility the default is I, but this may change in - the future. - -+=item B<-oo verify-server-certificate> -+ -+=item B<-oo verify-server-certificate=>C -+ -+For I<-o openstack> (L) only, this can -+be used to disable SSL certification validation when connecting to -+OpenStack by specifying I<-oo verify-server-certificate=false>. -+ - =item B<-op> file - - Supply a file containing a password to be used when connecting to the diff --git a/0001-m4-guestfs-perl.m4-IPC-Run3-is-now-required-by-podwr.patch b/0001-m4-guestfs-perl.m4-IPC-Run3-is-now-required-by-podwr.patch new file mode 100644 index 0000000..16e52cd --- /dev/null +++ b/0001-m4-guestfs-perl.m4-IPC-Run3-is-now-required-by-podwr.patch @@ -0,0 +1,25 @@ +From a6978649ccf9e8c8412db98a6af47f4fbae1c8cf Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 29 Aug 2025 11:06:01 +0100 +Subject: [PATCH] m4/guestfs-perl.m4: IPC::Run3 is now required by podwrapper + +Add it to the list of perl module that we check. + +Fixes: commit bdcc947b4e968e8e7ac4e56b87563e0e3d456294 +--- + m4/guestfs-perl.m4 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/m4/guestfs-perl.m4 b/m4/guestfs-perl.m4 +index 27d91011..68100df2 100644 +--- a/m4/guestfs-perl.m4 ++++ b/m4/guestfs-perl.m4 +@@ -42,7 +42,7 @@ dnl Check for Perl modules needed by Perl documentation and tests. + dnl XXX These should probably be required. + AS_IF([test "x$PERL" != "xno"],[ + missing_perl_modules=no +- for pm in Pod::Usage Getopt::Long Sys::Guestfs ; do ++ for pm in Pod::Usage Getopt::Long IPC::Run3 Sys::Guestfs ; do + AC_MSG_CHECKING([for $pm]) + if ! $PERL -M$pm -e1 >&AS_MESSAGE_LOG_FD 2>&1; then + AC_MSG_RESULT([no]) diff --git a/0012-RHEL-Fixes-for-libguestfs-winsupport.patch b/0002-RHEL-Fixes-for-libguestfs-winsupport.patch similarity index 83% rename from 0012-RHEL-Fixes-for-libguestfs-winsupport.patch rename to 0002-RHEL-Fixes-for-libguestfs-winsupport.patch index 39aee3b..ab8443a 100644 --- a/0012-RHEL-Fixes-for-libguestfs-winsupport.patch +++ b/0002-RHEL-Fixes-for-libguestfs-winsupport.patch @@ -1,4 +1,4 @@ -From 2cdab0acc99796d9e885697c6d9e50255bb3956b Mon Sep 17 00:00:00 2001 +From 340400e92649a4124d00fa0f6a8e95c7d99e89f4 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Sun, 30 Aug 2015 03:21:57 -0400 Subject: [PATCH] RHEL: Fixes for libguestfs-winsupport. @@ -19,17 +19,17 @@ https://bugzilla.redhat.com/show_bug.cgi?id=2187961#c1 7 files changed, 40 insertions(+), 5 deletions(-) diff --git a/convert/convert.ml b/convert/convert.ml -index ff82ad54..45d48a95 100644 +index 74160f1d..32a954c6 100644 --- a/convert/convert.ml +++ b/convert/convert.ml -@@ -53,6 +53,7 @@ let rec convert input_disks options source = +@@ -55,6 +55,7 @@ let rec convert input_disks options source = message (f_"Opening the source"); let g = open_guestfs ~identifier:"v2v" () in + g#set_program "virt-v2v"; - g#set_memsize (g#get_memsize () * 2); - (* Setting the number of vCPUs allows parallel mkinitrd, but make - * sure this is not too large because each vCPU consumes guest RAM. + let memsize = + match options.memsize with + | None -> diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh index b52d2522..8d036ee6 100755 --- a/test-data/phony-guests/make-windows-img.sh @@ -43,10 +43,10 @@ index b52d2522..8d036ee6 100755 run diff --git a/tests/test-block-driver.sh b/tests/test-block-driver.sh -index 595e969c..0b8ac6ea 100755 +index 1ea2181e..00aa8b41 100755 --- a/tests/test-block-driver.sh +++ b/tests/test-block-driver.sh -@@ -100,7 +100,11 @@ check_driver_presence () +@@ -99,7 +99,11 @@ check_driver_presence () local virtio_dir="/Windows/Drivers/VirtIO" @@ -60,10 +60,10 @@ index 595e969c..0b8ac6ea 100755 is-file $virtio_dir/$drv.cat is-file $virtio_dir/$drv.inf diff --git a/tests/test-in-place.sh b/tests/test-in-place.sh -index e66d2647..38d05de5 100755 +index 0c6432cf..2d17029c 100755 --- a/tests/test-in-place.sh +++ b/tests/test-in-place.sh -@@ -89,6 +89,12 @@ mktest () +@@ -88,6 +88,12 @@ mktest () :> "$script" :> "$expected" @@ -76,7 +76,7 @@ index e66d2647..38d05de5 100755 firstboot_dir="/Program Files/Guestfs/Firstboot" mktest "is-dir \"$firstboot_dir\"" true mktest "is-file \"$firstboot_dir/firstboot.bat\"" true -@@ -101,7 +107,7 @@ for drv in netkvm vioscsi viostor; do +@@ -100,7 +106,7 @@ for drv in netkvm vioscsi viostor; do done done @@ -86,10 +86,10 @@ index e66d2647..38d05de5 100755 # Test the base image remained untouched diff --git a/tests/test-virtio-win-iso.sh b/tests/test-virtio-win-iso.sh -index ccc42550..cd92db92 100755 +index 1ee343fd..0216a39b 100755 --- a/tests/test-virtio-win-iso.sh +++ b/tests/test-virtio-win-iso.sh -@@ -82,6 +82,12 @@ mktest () +@@ -80,6 +80,12 @@ mktest () :> "$script" :> "$expected" @@ -102,7 +102,7 @@ index ccc42550..cd92db92 100755 firstboot_dir="/Program Files/Guestfs/Firstboot" mktest "is-dir \"$firstboot_dir\"" true mktest "is-file \"$firstboot_dir/firstboot.bat\"" true -@@ -94,5 +100,5 @@ for drv in netkvm vioscsi viostor; do +@@ -92,5 +98,5 @@ for drv in netkvm vioscsi viostor; do done done @@ -110,10 +110,10 @@ index ccc42550..cd92db92 100755 +guestfish --ro -a "$d/windows-sda" < "$script" > "$response" diff -u "$expected" "$response" diff --git a/tests/test-windows-conversion.sh b/tests/test-windows-conversion.sh -index bfe04904..eeddcb86 100755 +index db688ddf..74f28bbb 100755 --- a/tests/test-windows-conversion.sh +++ b/tests/test-windows-conversion.sh -@@ -76,6 +76,12 @@ mktest () +@@ -74,6 +74,12 @@ mktest () :> "$script" :> "$expected" @@ -126,7 +126,7 @@ index bfe04904..eeddcb86 100755 firstboot_dir="/Program Files/Guestfs/Firstboot" mktest "is-dir \"$firstboot_dir\"" true mktest "is-file \"$firstboot_dir/firstboot.bat\"" true -@@ -83,7 +89,7 @@ mktest "is-dir \"$firstboot_dir/scripts\"" true +@@ -81,7 +87,7 @@ mktest "is-dir \"$firstboot_dir/scripts\"" true virtio_dir="/Windows/Drivers/VirtIO" mktest "ls \"$virtio_dir\"" "$(cat test-windows-conversion-ls.txt)" @@ -136,10 +136,10 @@ index bfe04904..eeddcb86 100755 # We also update the Registry several times, for firstboot, and (ONLY diff --git a/tests/test-windows-phony.sh b/tests/test-windows-phony.sh -index fa5f6a17..3f5dfe5e 100755 +index 22c0fb9e..96420ff9 100755 --- a/tests/test-windows-phony.sh +++ b/tests/test-windows-phony.sh -@@ -71,6 +71,17 @@ mktest () +@@ -69,6 +69,17 @@ mktest () :> "$script" :> "$expected" @@ -157,7 +157,7 @@ index fa5f6a17..3f5dfe5e 100755 firstboot_dir="/Program Files/Guestfs/Firstboot" mktest "is-dir \"$firstboot_dir\"" true mktest "is-file \"$firstboot_dir/firstboot.bat\"" true -@@ -80,7 +91,7 @@ mktest "ls \"$virtio_dir\"" "$(cat test-phony-$guestname-ls.txt)" +@@ -78,7 +89,7 @@ mktest "ls \"$virtio_dir\"" "$(cat test-phony-$guestname-ls.txt)" osinfo_name="${guestname%-32}" mktest "inspect-get-osinfo /dev/sda2" "$osinfo_name" diff --git a/0002-input-input_vddk.ml-Fix-escaping-of-export-.-paramet.patch b/0002-input-input_vddk.ml-Fix-escaping-of-export-.-paramet.patch deleted file mode 100644 index 59d734b..0000000 --- a/0002-input-input_vddk.ml-Fix-escaping-of-export-.-paramet.patch +++ /dev/null @@ -1,67 +0,0 @@ -From c2c829eb22add09de338da065214c9b6aced42e2 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 10 Jul 2025 09:13:54 +0100 -Subject: [PATCH] input/input_vddk.ml: Fix escaping of export=... parameter - -Commit b49ee14368 ("input: vddk: Use single nbdkit-vddk-plugin -instance with exports") switched to using the new nbdkit-vddk-plugin -export feature, where we can run a single nbdkit instance and choose -which disk we want to see using the NBD protocol exportname feature. - -As part of this, we are required to set an export parameter, which is -a wildcard that all exportnames must match. This is a safety feature -so that nbdkit will only serve a subset of the VMware files, instead -of allowing anyone who can attach to the nbdkit socket to read any -file on the server. (The socket is further protected by not being -readable to users other than the user running virt-v2v.) - -We compute this by doing a longest common prefix of all the disk names -associated with a guest. - -Ming Xie found a case where this failed. Given two names called: - - "[datastore1 (3)] esx8.0-win11-efi-secureboot-with-vtpm-and-turn-on-bitlocker/esx8.0-win11-efi-secureboot-with-vtpm-and-turn-on-bitlocker.vmdk" - "[datastore1 (3)] esx8.0-win11-efi-secureboot-with-vtpm-and-turn-on-bitlocker/esx8.0-win11-efi-secureboot-with-vtpm-and-turn-on-bitlocker_1.vmdk" - -we computed the wildcard: - - "\[datastore1 (3)\] esx8.0-win11-efi-secureboot-with-vtpm-and-turn-on-bitlocker/esx8.0-win11-efi-secureboot-with-vtpm-and-turn-on-bitlocker\*.vmdk" - -However the escaping is wrong. We correctly escape the '[' and ']' -characters, but incorrectly escape the '*' character (which is meant -to be a wildcard). - -This caused failure to convert when a guest has multiple disks and -nbdkit >= 1.44 is installed. - -Reported-by: Ming Xie -Fixes: commit 076727e55f4d4fed246097d3f89ebfe83e3de88f -Fixes: https://issues.redhat.com/browse/RHEL-102734 -(cherry picked from commit 5461976e229873a203062848c0de30e70067b3fb) ---- - input/input_vddk.ml | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/input/input_vddk.ml b/input/input_vddk.ml -index b70d76fb..39356129 100644 ---- a/input/input_vddk.ml -+++ b/input/input_vddk.ml -@@ -446,7 +446,7 @@ See also the virt-v2v-input-vmware(1) manual.") libNN - let wildcard = - match files with - | [] -> assert false (* can't happen, see assert above *) -- | [f] -> f -+ | [f] -> fnmatch_escape f - | files -> - (* Calculate the longest common prefix across all the files, - * then set the wildcard to this. -@@ -454,8 +454,7 @@ See also the virt-v2v-input-vmware(1) manual.") libNN - * XXX Is every file we want to read called *.vmdk? - *) - let prefix = String.longest_common_prefix files in -- prefix ^ "*.vmdk" in -- let wildcard = fnmatch_escape wildcard in -+ fnmatch_escape prefix ^ "*.vmdk" in - - let socket = sprintf "%s/in0" dir in - On_exit.unlink socket; diff --git a/0003-Modify-configure_pnputil_install-script-to-check.patch b/0003-Modify-configure_pnputil_install-script-to-check.patch deleted file mode 100644 index 2cefb6d..0000000 --- a/0003-Modify-configure_pnputil_install-script-to-check.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 5fda965d292bd1b5b62e47d357ddf046dfa007b6 Mon Sep 17 00:00:00 2001 -From: Vadim Rozenfeld -Date: Thu, 10 Jul 2025 10:12:56 +1000 -Subject: [PATCH] Modify configure_pnputil_install script to check pending - reboot status and report PnPUtil execution status - -This change adds checks for system reboot status and reports -the result of PnPUtil driver installation attempt. - -Related: https://issues.redhat.com/browse/RHEL-100682 - -Signed-off-by: Vadim Rozenfeld -(cherry picked from commit 594b05d6940c8719167d10c0cdfaa253349060ab) ---- - convert/convert_windows.ml | 48 +++++++++++++++++++++++++++++++++++--- - 1 file changed, 45 insertions(+), 3 deletions(-) - -diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml -index 71e867a5..8f0ff87b 100644 ---- a/convert/convert_windows.ml -+++ b/convert/convert_windows.ml -@@ -396,9 +396,51 @@ let convert (g : G.guestfs) source inspect i_firmware - and configure_pnputil_install () = - let fb_script = "@echo off\n\ - \n\ -- echo Wait for VirtIO drivers to be installed\n\ -- %systemroot%\\Sysnative\\PnPutil -i -a \ -- %systemroot%\\Drivers\\Virtio\\*.inf" in -+ setlocal EnableDelayedExpansion\n\ -+ set inf_dir=%systemroot%\\Drivers\\Virtio\\\n\ -+ echo Installing drivers from %inf_dir%\n\ -+ set REBOOT_PENDING=0\n\ -+ \n\ -+ timeout /t 10 /nobreak\n\ -+ \n\ -+ reg query \"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update\\RebootRequired\"\n\ -+ if %errorlevel%==0 (\n\ -+ echo Windows Update: Reboot required.\n\ -+ set REBOOT_PENDING=1\n\ -+ )\n\ -+ \n\ -+ reg query \"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootPending\"\n\ -+ if %errorlevel%==0 (\n\ -+ echo CBS: Reboot required.\n\ -+ set REBOOT_PENDING=1\n\ -+ )\n\ -+ \n\ -+ reg query \"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\" /v PendingFileRenameOperations\n\ -+ if %errorlevel%==0 (\n\ -+ echo Session Manager: Reboot required.\n\ -+ set REBOOT_PENDING=1\n\ -+ )\n\ -+ \n\ -+ if \"%REBOOT_PENDING%\"==\"1\" (\n\ -+ echo A reboot is pending.\n\ -+ exit /b 249\n\ -+ ) else (\n\ -+ echo No pending reboot detected.\n\ -+ )\n\ -+ \n\ -+ for %%f in (\"%inf_dir%*.inf\") do (\n\ -+ echo Installing: %%~nxf.\n\ -+ %systemroot%\\Sysnative\\PnPutil -i -a \"%%f\"\n\ -+ if !errorlevel! NEQ 0 (\n\ -+ echo Failed to install %%~nxf.\n\ -+ exit /b 249\n\ -+ ) else (\n\ -+ echo Successfully installed %%~nxf.\n\ -+ )\n\ -+ )\n\ -+ echo All drivers installed successfully.\n\ -+ exit /b 0\n\ -+ )" in - - (* Set priority higher than that of "network-configure" firstboot script. *) - Firstboot.add_firstboot_script g inspect.i_root ~prio:2000 diff --git a/0013-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch b/0003-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch similarity index 87% rename from 0013-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch rename to 0003-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch index 4442811..a875191 100644 --- a/0013-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch +++ b/0003-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch @@ -1,4 +1,4 @@ -From de879aad4bd0d17e884d571da3348965a9d02756 Mon Sep 17 00:00:00 2001 +From 3234be3b16565e4bee797bcf9e29be764ff7268c Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Sun, 28 Sep 2014 19:14:43 +0100 Subject: [PATCH] RHEL: v2v: Select correct qemu binary for -o qemu mode @@ -16,10 +16,10 @@ support cases. 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/output/output_qemu.ml b/output/output_qemu.ml -index 47a6f4ff..909b6e10 100644 +index 63299423..853f43d4 100644 --- a/output/output_qemu.ml +++ b/output/output_qemu.ml -@@ -164,7 +164,7 @@ module QEMU = struct +@@ -165,7 +165,7 @@ module QEMU = struct * module deals with shell and qemu comma quoting. *) let cmd = Qemuopts.create () in diff --git a/0014-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch b/0004-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch similarity index 88% rename from 0014-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch rename to 0004-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch index f5692f5..083ecb3 100644 --- a/0014-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch +++ b/0004-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch @@ -1,4 +1,4 @@ -From 21c7424d64065fe77d4bfd6c05f0ca85e0a08229 Mon Sep 17 00:00:00 2001 +From 59db6c7c45273b404d2a97143dfa9c0a9686511c Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 30 Sep 2014 10:50:27 +0100 Subject: [PATCH] RHEL: v2v: Disable the --qemu-boot / -oo qemu-boot option @@ -43,10 +43,10 @@ index 49f00754..bdf12c5d 100644 =item B<-o null> diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod -index e228fb33..35886561 100644 +index fbb5bbd6..faf6b355 100644 --- a/docs/virt-v2v.pod +++ b/docs/virt-v2v.pod -@@ -160,11 +160,6 @@ Since F contains the path(s) to the guest disk +@@ -167,11 +167,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. @@ -58,17 +58,17 @@ index e228fb33..35886561 100644 =head1 OPTIONS =over 4 -@@ -549,9 +544,6 @@ This is similar to I<-o local>, except that a shell script is written +@@ -575,9 +570,6 @@ This is similar to I<-o local>, except that a shell script is written which you can use to boot the guest in qemu. The converted disks and shell script are written to the directory specified by I<-os>. -When using this output mode, you can also specify the I<-oo qemu-boot> -option which boots the guest under qemu immediately. - + ifelse(ENABLE_OVIRT, yes, ` =item B<-o> B - Set the output method to I. -@@ -622,11 +614,6 @@ For I<-o openstack> (L) only, set a guest ID +@@ -650,11 +642,6 @@ For I<-o openstack> (L) only, set a guest ID which is saved on each Cinder volume in the C volume property. @@ -81,7 +81,7 @@ index e228fb33..35886561 100644 For I<-o openstack> (L) only, set optional diff --git a/output/output_qemu.ml b/output/output_qemu.ml -index 909b6e10..37371aad 100644 +index 853f43d4..dff08b66 100644 --- a/output/output_qemu.ml +++ b/output/output_qemu.ml @@ -65,6 +65,9 @@ module QEMU = struct diff --git a/0004-Update-the-common-submodule.patch b/0004-Update-the-common-submodule.patch deleted file mode 100644 index f65562c..0000000 --- a/0004-Update-the-common-submodule.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 1162c9c21497e24e3388689fd2c58e8dfa043bc4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sun, 13 Jul 2025 12:29:28 +0100 -Subject: [PATCH] Update the common submodule - -Pick up this commit from the submodule: - - commit b40e534fefb74af32bd496904e44ce9bca1a7b34 - Author: Vadim Rozenfeld - Date: Thu Jul 10 10:48:04 2025 +1000 - - Modify the firstboot script to check the scripts - -which is required for commit 594b05d694 ("Modify -configure_pnputil_install script to check pending reboot status and -report PnPUtil execution status") to work properly. - -Updates: commit 594b05d6940c8719167d10c0cdfaa253349060ab -(cherry picked from commit 3e08788aaebf96d86452dc2c88d610dc0b72d02e) ---- - common | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -Submodule common 0e9caa17..10d2b626: -diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml -index 6aca4c34..5f2642b0 100644 ---- a/common/mlcustomize/firstboot.ml -+++ b/common/mlcustomize/firstboot.ml -@@ -305,13 +305,19 @@ if not exist \"%%scripts_done%%\" ( - :: Pick the next script to run. - for %%%%f in (\"%%scripts%%\"\\*.bat) do ( - echo running \"%%%%f\" -- move \"%%%%f\" \"%%scripts_done%%\" -- pushd \"%%scripts_done%%\" -+ pushd \"%%scripts%%\" - call \"%%%%~nf\" - set elvl=!errorlevel! - echo .... exit code !elvl! - popd - -+ if !elvl! NEQ 249 ( -+ echo Script succeeded, moving to scripts-done -+ move \"%%%%f\" \"%%scripts_done%%\" -+ ) else ( -+ echo Script failed, will retry on next boot -+ ) -+ - :: Reboot the computer. This is necessary to free any locked - :: files which may prevent later scripts from running. - shutdown /r /t 0 /y diff --git a/0005-Ignore-ERROR_NO_MORE_ITEMS-status-from-PnPUtil.patch b/0005-Ignore-ERROR_NO_MORE_ITEMS-status-from-PnPUtil.patch deleted file mode 100644 index fc5e79b..0000000 --- a/0005-Ignore-ERROR_NO_MORE_ITEMS-status-from-PnPUtil.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 90376739e05166de15a94637f64e6b2256f5d90a Mon Sep 17 00:00:00 2001 -From: Vadim Rozenfeld -Date: Tue, 15 Jul 2025 18:35:16 +1000 -Subject: [PATCH] Ignore ERROR_NO_MORE_ITEMS status from PnPUtil. - -This status indicates the target device already has a -better or newer driver installed. - -Signed-off-by: Vadim Rozenfeld -(cherry picked from commit 523aff28975532a4fe715193c28c2ede21741392) ---- - convert/convert_windows.ml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml -index 8f0ff87b..2ff9bcfa 100644 ---- a/convert/convert_windows.ml -+++ b/convert/convert_windows.ml -@@ -431,7 +431,7 @@ let convert (g : G.guestfs) source inspect i_firmware - for %%f in (\"%inf_dir%*.inf\") do (\n\ - echo Installing: %%~nxf.\n\ - %systemroot%\\Sysnative\\PnPutil -i -a \"%%f\"\n\ -- if !errorlevel! NEQ 0 (\n\ -+ if !errorlevel! neq 0 if !errorlevel! neq 259 (\n\ - echo Failed to install %%~nxf.\n\ - exit /b 249\n\ - ) else (\n\ diff --git a/0015-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch b/0005-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch similarity index 92% rename from 0015-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch rename to 0005-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch index 3b1adc5..f956c6a 100644 --- a/0015-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch +++ b/0005-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch @@ -1,4 +1,4 @@ -From 04ee519268f9805ac0a9c54fe20e26ccb99c8550 Mon Sep 17 00:00:00 2001 +From 0a943cb304e66aba748b2d36cb2d65cd1a55180b Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 24 Apr 2015 09:45:41 -0400 Subject: [PATCH] RHEL: Fix list of supported sound cards to match RHEL qemu diff --git a/0016-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch b/0006-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch similarity index 89% rename from 0016-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch rename to 0006-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch index 6a7fc46..9286469 100644 --- a/0016-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch +++ b/0006-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch @@ -1,4 +1,4 @@ -From 4f5301bfa39c09df4ce4368abbafcb53ea139efc Mon Sep 17 00:00:00 2001 +From d0244f8ef20d18dd7c26c441f80261661d413e1f Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 2 Mar 2017 14:21:37 +0100 Subject: [PATCH] RHEL: v2v: -i disk: force VNC as display (RHBZ#1372671) @@ -9,7 +9,7 @@ The SDL output mode is not supported in RHEL's qemu-kvm. 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/input_disk.ml b/input/input_disk.ml -index 8b027fed..6dd1b0cf 100644 +index 2997efa2..00c11f80 100644 --- a/input/input_disk.ml +++ b/input/input_disk.ml @@ -78,7 +78,7 @@ module Disk = struct diff --git a/0006-v2v-Print-the-version-of-libnbd-nbdcopy-in-debug-out.patch b/0006-v2v-Print-the-version-of-libnbd-nbdcopy-in-debug-out.patch deleted file mode 100644 index cf52565..0000000 --- a/0006-v2v-Print-the-version-of-libnbd-nbdcopy-in-debug-out.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 4835c9c91cff55f1411a0413c1469e212124ba03 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 16 Jul 2025 13:10:01 +0100 -Subject: [PATCH] v2v: Print the version of libnbd / nbdcopy in debug output - -We didn't previously log the version of libnbd or nbdcopy, and nbdcopy -itself won't tell us (because we don't use the nbdcopy --verbose -option). However this information can be useful to know. This commit -enhances the verbose output of virt-v2v to include this. - -With current versions of nbdcopy it will look like this: - - info: nbdcopy version: - nbdcopy 1.23.4 - libnbd 1.23.4 - -Note the second line is the version of the installed library, which in -some (very unusual, and probably broken) situations might be different -from the version of the nbdcopy binary, which is why both are logged. - -libnbd 1.23.5 will soon enhance the output to include the downstream -package version (such as the RPM version) which is even more useful. -In future the output will look like: - - info: nbdcopy version: - nbdcopy 1.23.5 (libnbd-1.23.5-1.fc43) - libnbd 1.23.5 (libnbd-1.23.5-1.fc43) - -See: https://gitlab.com/nbdkit/libnbd/-/merge_requests/28 -(cherry picked from commit a8a0caf54ccaf52db70988494b6f5a397a1af105) ---- - v2v/v2v.ml | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/v2v/v2v.ml b/v2v/v2v.ml -index d32993d4..c780ab1d 100644 ---- a/v2v/v2v.ml -+++ b/v2v/v2v.ml -@@ -469,6 +469,11 @@ read the man page virt-v2v(1). - (* Do the copy. *) - with_open_out (v2vdir // "copy") (fun _ -> ()); - -+ if verbose () then ( -+ eprintf "info: nbdcopy version:\n%!"; -+ ignore (Sys.command (sprintf "%s --version >&2" Config.nbdcopy)) -+ ); -+ - (* Get the list of disks and corresponding NBD URIs. *) - let disks = - List.combine input_disks output_disks |> diff --git a/0017-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch b/0007-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch similarity index 97% rename from 0017-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch rename to 0007-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch index 74de0a2..6c5163b 100644 --- a/0017-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch +++ b/0007-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch @@ -1,4 +1,4 @@ -From a3ca5d7c85f44c55bccc8b964e00e4937a54a3b4 Mon Sep 17 00:00:00 2001 +From ba4244a69a6b0aa104c5801204542ae0dcb3a104 Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Tue, 26 Mar 2019 09:42:25 +0100 Subject: [PATCH] RHEL: point to KB for supported v2v hypervisors/guests diff --git a/0007-vddk-Remove-io-vddk-noextents-option.patch b/0007-vddk-Remove-io-vddk-noextents-option.patch deleted file mode 100644 index e4049e0..0000000 --- a/0007-vddk-Remove-io-vddk-noextents-option.patch +++ /dev/null @@ -1,101 +0,0 @@ -From ef40dab47ba94ca47e6a268853d415d9311aca04 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 9 Jul 2025 09:38:50 +0100 -Subject: [PATCH] vddk: Remove -io vddk-noextents option - -Commit 191b8cf418 ("input: Add undocumented -io vddk-noextents=true -option") added an option which could be used to insert the nbdkit -noextents filter on top of the VDDK source. This was designed so we -could test in production if this improved performance (which it -didn't). - -Since then we've spent more time investigating problems with -QueryAllocatedBlocks and believe we have a better solution in nbdkit. -See: -https://gitlab.com/nbdkit/nbdkit/-/commit/5a882e74cae3dbaa09bf3b942a02f9947b12f6e5 - -Reverts: commit 191b8cf418076ae3766b134ffa96eee048c7eb9d ---- - README | 1 - - input/input_vddk.ml | 35 ----------------------------------- - 2 files changed, 36 deletions(-) - -diff --git a/README b/README -index 49082a96..1cdbef15 100644 ---- a/README -+++ b/README -@@ -71,7 +71,6 @@ REQUIREMENTS - + nbdkit-blocksize-filter - + nbdkit-cow-filter - + nbdkit-multi-conn-filter -- + nbdkit-noextents-filter - + nbdkit-rate-filter - + nbdkit-retry-filter - -diff --git a/input/input_vddk.ml b/input/input_vddk.ml -index 39356129..12f43729 100644 ---- a/input/input_vddk.ml -+++ b/input/input_vddk.ml -@@ -58,7 +58,6 @@ All other settings are optional: - -io vddk-file=FILE Override nbdkit-vddk-plugin file= parameter - -io vddk-libdir=LIBDIR VDDK library parent directory - -io vddk-nfchostport=PORT VDDK nfchostport -- -io vddk-noextents=true Avoid slow VDDK QueryAllocatedBlocks API - -io vddk-port=PORT VDDK port - -io vddk-snapshot=SNAPSHOT-MOREF - VDDK snapshot moref -@@ -79,7 +78,6 @@ information on these settings. - "file"; - "libdir"; - "nfchostport"; -- "noextents"; - "port"; - "snapshot"; - "thumbprint"; -@@ -208,9 +206,6 @@ information on these settings. - try Some (List.assoc "libdir" io_options) with Not_found -> None in - let nfchostport = - try Some (List.assoc "nfchostport" io_options) with Not_found -> None in -- let noextents = -- try bool_of_string (List.assoc "noextents" io_options) -- with Not_found -> false in - let port = - try Some (List.assoc "port" io_options) with Not_found -> None in - let snapshot = -@@ -318,36 +313,6 @@ See also the virt-v2v-input-vmware(1) manual.") libNN - *) - Nbdkit.add_filter_if_available cmd "retry"; - -- (* VDDK's QueryAllocatedBlocks API is infamously slow. It appears -- * to block all other requests while it is running. This API is -- * also only called during the copy phase, not during conversion -- * (or if it is, extremely rarely). -- * -- * If fstrim was successful, then trimmed blocks are stored in -- * the COW filter (see below), and so requests for extents stop -- * at that layer. However for areas of the disk that fstrim -- * thinks contain data, we still have to go through to VDDK to -- * fetch extents. -- * -- * We could therefore add nbdkit-noextents-filter here (below COW, -- * above VDDK plugin) which stops extents requests from going -- * to VDDK, which would stop QueryAllocatedBlocks ever being -- * called. In my testing this is a moderate performance win. -- * -- * However ... in the case where fstrim failed, or for filesystems -- * or partitions on the disk that we don't understand, doing this -- * would mean that those are copied completely, as there would be -- * no extent data (nbdcopy will still sparsify them on the target, -- * but we'd have to copy all the bits from VMware). Because -- * here we don't know if this is the case, be conservative and -- * actually don't use this filter. -- * -- * If used, this filter should be close to the plugin and MUST -- * be below the COW filter. -- *) -- if noextents then -- Nbdkit.add_filter_if_available cmd "noextents"; -- - (* Split very large requests to avoid out of memory errors on the - * server. Since we're using this filter, also add minblock=512 - * although it will make no difference. diff --git a/0020-RHEL-tests-Remove-btrfs-test.patch b/0008-RHEL-tests-Remove-btrfs-test.patch similarity index 86% rename from 0020-RHEL-tests-Remove-btrfs-test.patch rename to 0008-RHEL-tests-Remove-btrfs-test.patch index e5b0fcc..e6a2644 100644 --- a/0020-RHEL-tests-Remove-btrfs-test.patch +++ b/0008-RHEL-tests-Remove-btrfs-test.patch @@ -1,4 +1,4 @@ -From 867666d94ada861146fcd0ae6643c0d69c2e4513 Mon Sep 17 00:00:00 2001 +From a3c45a46b4011ec3c363cac6b66897fa11ef95de Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 5 Jul 2022 11:58:09 +0100 Subject: [PATCH] RHEL: tests: Remove btrfs test @@ -9,7 +9,7 @@ RHEL does not have btrfs so this test always fails. 1 file changed, 1 deletion(-) diff --git a/tests/Makefile.am b/tests/Makefile.am -index 3a8bab3c..f9c748ed 100644 +index 26e41cc5..00d6eed5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -64,7 +64,6 @@ TESTS = \ diff --git a/0008-curl-ssh-vddk-file-Add-nbdkit-count-filter.patch b/0008-curl-ssh-vddk-file-Add-nbdkit-count-filter.patch deleted file mode 100644 index 38c1f46..0000000 --- a/0008-curl-ssh-vddk-file-Add-nbdkit-count-filter.patch +++ /dev/null @@ -1,114 +0,0 @@ -From cdb7ffa3a378a1832c92f40aef9e7dd6d8d093ff Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 9 Jul 2025 09:48:35 +0100 -Subject: [PATCH] curl, ssh, vddk, file: Add nbdkit-count-filter - -nbdkit-count-filter, added in nbdkit 1.45.1, prints a debug message -which just records the number of bytes read, written, trimmed or -zeroed. This is useful for determining how many bytes were actually -copied over the wire or written to disk, and that's a common question -that we currently have no easy way to answer. For more details about -this filter see: -https://gitlab.com/nbdkit/nbdkit/-/commit/3512c3ce9308b4d940119ac6cc87f1baa9afb655 -https://libguestfs.org/nbdkit-count-filter.1.html - -Use this filter (if available) unconditionally for all inputs that -read over the network, and for the common file-based outputs -(specifically -o kubevirt). - -It is only enabled if we're producing debug output (ie. conversion -logs). ---- - README | 1 + - input/input_vddk.ml | 7 +++++++ - input/nbdkit_curl.ml | 7 +++++++ - input/nbdkit_ssh.ml | 7 +++++++ - output/output.ml | 2 ++ - 5 files changed, 24 insertions(+) - -diff --git a/README b/README -index 1cdbef15..407869b4 100644 ---- a/README -+++ b/README -@@ -69,6 +69,7 @@ REQUIREMENTS - + nbdkit-vddk-plugin - - + nbdkit-blocksize-filter -+ + nbdkit-count-filter - + nbdkit-cow-filter - + nbdkit-multi-conn-filter - + nbdkit-rate-filter -diff --git a/input/input_vddk.ml b/input/input_vddk.ml -index 12f43729..e88befa2 100644 ---- a/input/input_vddk.ml -+++ b/input/input_vddk.ml -@@ -313,6 +313,13 @@ See also the virt-v2v-input-vmware(1) manual.") libNN - *) - Nbdkit.add_filter_if_available cmd "retry"; - -+ (* Add the count filter if available, to report bytes read. -+ * Since it writes a debug message, only do this if verbose. -+ * This should be close to the plugin so we're reporting what -+ * is read over the wire. -+ *) -+ if verbose () then Nbdkit.add_filter_if_available cmd "count"; -+ - (* Split very large requests to avoid out of memory errors on the - * server. Since we're using this filter, also add minblock=512 - * although it will make no difference. -diff --git a/input/nbdkit_curl.ml b/input/nbdkit_curl.ml -index d8c832b8..f8a0213e 100644 ---- a/input/nbdkit_curl.ml -+++ b/input/nbdkit_curl.ml -@@ -58,6 +58,13 @@ let create_curl ?bandwidth ?cookie_script ?cookie_script_renew ?cor - *) - Nbdkit.add_filter_if_available cmd "retry"; - -+ (* Add the count filter if available, to report bytes read. -+ * Since it writes a debug message, only do this if verbose. -+ * This should be close to the plugin so we're reporting what -+ * is read over the wire. -+ *) -+ if verbose () then Nbdkit.add_filter_if_available cmd "count"; -+ - (* IMPORTANT! Add the COW filter. It must be furthest away - * except for the rate filter. - *) -diff --git a/input/nbdkit_ssh.ml b/input/nbdkit_ssh.ml -index e6d99ede..4e4c918f 100644 ---- a/input/nbdkit_ssh.ml -+++ b/input/nbdkit_ssh.ml -@@ -54,6 +54,13 @@ let create_ssh ?bandwidth ?cor ?(retry=true) - if retry then - Nbdkit.add_filter_if_available cmd "retry"; - -+ (* Add the count filter if available, to report bytes read. -+ * Since it writes a debug message, only do this if verbose. -+ * This should be close to the plugin so we're reporting what -+ * is read over the wire. -+ *) -+ if verbose () then Nbdkit.add_filter_if_available cmd "count"; -+ - (* IMPORTANT! Add the COW filter. It must be furthest away - * except for the rate filter. - *) -diff --git a/output/output.ml b/output/output.ml -index b3629372..65325538 100644 ---- a/output/output.ml -+++ b/output/output.ml -@@ -98,6 +98,7 @@ let output_to_local_file ?(changeuid = fun f -> f ()) ?(compressed = false) - let cmd = Nbdkit.create "file" in - Nbdkit.add_arg cmd "file" filename; - Nbdkit.add_arg cmd "cache" "none"; -+ if verbose () then Nbdkit.add_filter_if_available cmd "count"; - let _, pid = Nbdkit.run_unix socket cmd in - pid - -@@ -197,6 +198,7 @@ let create_local_output_disks dir - let cmd = Nbdkit.create "file" in - Nbdkit.add_arg cmd "dir" output_storage; - Nbdkit.add_arg cmd "cache" "none"; -+ if verbose () then Nbdkit.add_filter_if_available cmd "count"; - let _, pid = Nbdkit.run_unix socket cmd in - On_exit.kill pid; - diff --git a/0023-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch b/0009-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch similarity index 88% rename from 0023-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch rename to 0009-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch index 7a1c260..a027b3d 100644 --- a/0023-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch +++ b/0009-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch @@ -1,4 +1,4 @@ -From 40333a5f19e6442d0765e11c5b7f8cc4adb8b090 Mon Sep 17 00:00:00 2001 +From f16be60b633c5a9ca47e51c31a42755c4747ce59 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 9 Jul 2024 11:30:09 +0100 Subject: [PATCH] RHEL: Add warning about virt-v2v-in-place not being supported @@ -10,7 +10,7 @@ Fixes: https://issues.redhat.com/browse/RHEL-40903 2 files changed, 7 insertions(+) diff --git a/docs/virt-v2v-in-place.pod b/docs/virt-v2v-in-place.pod -index 3d0d1b28..9714bbac 100644 +index 69d2092e..7c0a4d90 100644 --- a/docs/virt-v2v-in-place.pod +++ b/docs/virt-v2v-in-place.pod @@ -16,6 +16,10 @@ virt-v2v-in-place - Convert a guest to use KVM in-place @@ -25,10 +25,10 @@ index 3d0d1b28..9714bbac 100644 run on KVM. It does this conversion in place, modifying the original disk. diff --git a/in-place/in_place.ml b/in-place/in_place.ml -index a91ee39d..dba0772c 100644 +index 7e490867..6c2790af 100644 --- a/in-place/in_place.ml +++ b/in-place/in_place.ml -@@ -211,6 +211,9 @@ read the man page virt-v2v-in-place(1). +@@ -229,6 +229,9 @@ read the man page virt-v2v-in-place(1). let opthandle = create_standard_options argspec ~anon_fun ~key_opts:true ~machine_readable:true usage_msg in Getopt.parse opthandle.getopt; diff --git a/0009-o-kubevirt-Add-oo-disk-to-allow-disk-names-to-be-ove.patch b/0009-o-kubevirt-Add-oo-disk-to-allow-disk-names-to-be-ove.patch deleted file mode 100644 index 6966e8c..0000000 --- a/0009-o-kubevirt-Add-oo-disk-to-allow-disk-names-to-be-ove.patch +++ /dev/null @@ -1,233 +0,0 @@ -From 71d68738920971f0216cfe77f6873a518369045f Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 8 Jul 2025 10:40:48 +0100 -Subject: [PATCH] -o kubevirt: Add -oo disk to allow disk names to be - overridden - -Fixes: https://issues.redhat.com/browse/RHEL-101599 ---- - docs/virt-v2v.pod | 15 +++++++-- - output/output_kubevirt.ml | 58 ++++++++++++++++++++++++++------ - tests/Makefile.am | 2 ++ - tests/test-o-kubevirt-oo-disk.sh | 52 ++++++++++++++++++++++++++++ - 4 files changed, 115 insertions(+), 12 deletions(-) - create mode 100755 tests/test-o-kubevirt-oo-disk.sh - -diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod -index 3eefe404..5020d179 100644 ---- a/docs/virt-v2v.pod -+++ b/docs/virt-v2v.pod -@@ -466,8 +466,9 @@ Set the output method to I. B - - In this mode, the converted guest is written to a local directory --specified by I<-os /dir> (the directory must exist). The converted --guest’s disks are written to: -+specified by I<-os /dir> (the directory must exist). -+ -+By default the converted guest’s disks are written to: - - /dir/name-sda - /dir/name-sdb -@@ -479,6 +480,8 @@ and guest metadata is created in the associated YAML file: - - where C is the guest name. - -+You can override the disk paths by using I<-oo disk=...> option(s). -+ - =item B<-o> B - - Set the output method to I. This is the default. -@@ -600,6 +603,14 @@ For outputs which support qcow2 format (I<-of qcow2>), this writes a - compressed qcow2 file. It is the equivalent to the I<-c> option of - L. - -+=item B<-oo disk=>DISK -+ -+For I<-o kubevirt> this overrides the path to each output disk, -+instead of using the default which is C etc in the output -+storage (I<-os>) path. If you use this option at all, you must repeat -+it once for each guest disk. If you don't use it, then the default -+method of putting disks in the output storage path is used. -+ - =item B<-oo guest-id=>C - - For I<-o openstack> (L) only, set a guest ID -diff --git a/output/output_kubevirt.ml b/output/output_kubevirt.ml -index 76ecd39d..eae9c049 100644 ---- a/output/output_kubevirt.ml -+++ b/output/output_kubevirt.ml -@@ -35,7 +35,8 @@ let rfc1123_re = - "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" - - module Kubevirt = struct -- type poptions = bool * output_allocation * string * string * string -+ type poptions = -+ bool * string list option * output_allocation * string * string * string - - type t = unit - -@@ -49,15 +50,18 @@ module Kubevirt = struct - printf (f_"Output options that can be used with -o kubevirt: - - -oo compressed Compress the output file (used only with -of qcow2) -+ -oo disk=disk1 Specify filename of output disk (if used, must be -+ given once for each disk, else -os path is used) - ") - -- - let parse_options options source = - let compressed = ref false in -+ let disks = ref [] in - List.iter ( - function - | "compressed", "" -> compressed := true - | "compressed", v -> compressed := bool_of_string v -+ | "disk", v -> List.push_back disks v - | k, _ -> - error (f_"-o kubevirt: unknown output option ‘-oo %s’") k - ) options.output_options; -@@ -84,23 +88,57 @@ module Kubevirt = struct - end with an alphanumeric character. Rerun virt-v2v with \ - the '-on name' option to rename it."); - -- !compressed, options.output_alloc, options.output_format, -+ let disks = match !disks with [] -> None | disks -> Some disks in -+ -+ !compressed, disks, -+ options.output_alloc, options.output_format, - output_name, output_storage - - let setup dir options source input_disks = -- let compressed, output_alloc, output_format, output_name, output_storage = -- options in -+ let compressed, disks, -+ output_alloc, output_format, output_name, output_storage = options in - - let uris = -- create_local_output_disks dir ~compressed output_alloc output_format -- output_name output_storage input_disks in -+ match disks with -+ | None -> -+ create_local_output_disks dir ~compressed -+ output_alloc output_format output_name output_storage input_disks -+ | Some disks -> -+ (* -oo disk specified, so create the disks by hand. *) -+ let nr_input_disks = List.length input_disks -+ and nr_output_disks = List.length disks in -+ if nr_input_disks <> nr_output_disks then -+ error (f_"incorrect number of '-oo disk' parameters. This guest \ -+ has %d disks, but the parameter was used %d times.") -+ nr_input_disks nr_output_disks; -+ -+ let input_sizes = get_disk_sizes input_disks in -+ List.mapi ( -+ fun i (disk, size) -> -+ let socket = sprintf "%s/out%d" dir i in -+ On_exit.unlink socket; -+ -+ output_to_local_file ~compressed -+ output_alloc output_format disk size socket; -+ -+ NBD_URI.Unix (socket, None) -+ ) (List.combine disks input_sizes) -+ in -+ - (), uris - - let finalize dir options () output_disks source inspect target_meta = -- let _, output_alloc, output_format, output_name, output_storage = options in -+ let _, disks, -+ output_alloc, output_format, output_name, output_storage = options in - -- let doc = create_kubevirt_yaml source inspect target_meta -- (disk_path output_storage output_name) -+ (* This function will return the disk path for the i'th disk. *) -+ let disk_path = -+ match disks with -+ | None -> Output.disk_path output_storage output_name -+ | Some disks -> List.nth disks -+ in -+ -+ let doc = create_kubevirt_yaml source inspect target_meta disk_path - output_format output_name in - - let file = output_storage // output_name ^ ".yaml" in -diff --git a/tests/Makefile.am b/tests/Makefile.am -index 62237092..3a8bab3c 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -95,6 +95,7 @@ TESTS = \ - test-networks-and-bridges.sh \ - test-o-glance.sh \ - test-o-kubevirt-fedora.sh \ -+ test-o-kubevirt-oo-disk.sh \ - test-o-kubevirt-windows.sh \ - test-o-libvirt.sh \ - test-o-local-qcow2-compressed.sh \ -@@ -288,6 +289,7 @@ EXTRA_DIST += \ - test-o-glance.sh \ - test-o-kubevirt-fedora.sh \ - test-o-kubevirt-fedora.yaml.expected \ -+ test-o-kubevirt-oo-disk.sh \ - test-o-kubevirt-windows.sh \ - test-o-kubevirt-windows.yaml.expected \ - test-o-libvirt.sh \ -diff --git a/tests/test-o-kubevirt-oo-disk.sh b/tests/test-o-kubevirt-oo-disk.sh -new file mode 100755 -index 00000000..e1e6fd61 ---- /dev/null -+++ b/tests/test-o-kubevirt-oo-disk.sh -@@ -0,0 +1,52 @@ -+#!/bin/bash - -+# libguestfs virt-v2v test script -+# Copyright (C) 2018-2025 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 -o kubevirt + -oo disk option. -+ -+set -e -+set -x -+ -+source ./functions.sh -+set -e -+set -x -+ -+skip_if_skipped -+requires test -f ../test-data/phony-guests/fedora.img -+ -+libvirt_uri="test://$abs_top_builddir/test-data/phony-guests/guests.xml" -+fedora=../test-data/phony-guests/fedora.img -+ -+d=test-o-kubevirt-oo-disk.d -+rm -rf $d -+cleanup_fn rm -r $d -+mkdir $d -+ -+# Run virt-v2v -o kubevirt. -+$VG virt-v2v --debug-gc \ -+ -i libvirt -ic "$libvirt_uri" fedora \ -+ -o kubevirt -oo disk=$d/disk.img -os $d -+ -+ls -l $d -+ -+cat $d/fedora.yaml -+ -+# Check the disk was created. -+test -f $d/disk.img -+ -+# Check the default path was _not_ created. -+! test -f $d/fedora-sda diff --git a/0026-RHEL-10-m4-Depend-on-libguestfs-1.56.1-2.el10-for-gu.patch b/0010-RHEL-10-m4-Depend-on-libguestfs-1.56.1-2.el10-for-gu.patch similarity index 92% rename from 0026-RHEL-10-m4-Depend-on-libguestfs-1.56.1-2.el10-for-gu.patch rename to 0010-RHEL-10-m4-Depend-on-libguestfs-1.56.1-2.el10-for-gu.patch index f316469..23cc6e4 100644 --- a/0026-RHEL-10-m4-Depend-on-libguestfs-1.56.1-2.el10-for-gu.patch +++ b/0010-RHEL-10-m4-Depend-on-libguestfs-1.56.1-2.el10-for-gu.patch @@ -1,4 +1,4 @@ -From 687965a4797104fe20f8dc6eaab93d11a6b15775 Mon Sep 17 00:00:00 2001 +From 6954c74fcd5c5da71e20ec7f4613bcc9c7e3f934 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 13 Aug 2025 18:03:41 +0100 Subject: [PATCH] RHEL 10: m4: Depend on libguestfs 1.56.1-2.el10 for diff --git a/0010-output-Add-optional-create-parameter.patch b/0010-output-Add-optional-create-parameter.patch deleted file mode 100644 index e36e5af..0000000 --- a/0010-output-Add-optional-create-parameter.patch +++ /dev/null @@ -1,141 +0,0 @@ -From ab8623d45801d50e0d9450033ba74a31fdb872fc Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 8 Jul 2025 11:08:08 +0100 -Subject: [PATCH] output: Add optional ?create parameter - -This parameter of Output.create_local_output_disks and -Output.output_to_local_file allows the default creation of disks to be -skipped. It defaults to true (ie. create them) which is the normal -behaviour. - -This allows output modes to implement the '-oo create=false' option, -although none do so far. ---- - output/output.ml | 61 ++++++++++++++++++++++++++--------------------- - output/output.mli | 5 +++- - 2 files changed, 38 insertions(+), 28 deletions(-) - -diff --git a/output/output.ml b/output/output.ml -index 65325538..15cb50db 100644 ---- a/output/output.ml -+++ b/output/output.ml -@@ -66,7 +66,9 @@ let error_if_disk_count_gt input_disks n = - - type on_exit_kill = Kill | KillAndWait - --let output_to_local_file ?(changeuid = fun f -> f ()) ?(compressed = false) -+let output_to_local_file ?(changeuid = fun f -> f ()) -+ ?(compressed = false) -+ ?(create = true) - ?(on_exit_kill = Kill) - output_alloc output_format filename size socket = - (* Check nbdkit is installed and has the required plugin. *) -@@ -83,13 +85,15 @@ let output_to_local_file ?(changeuid = fun f -> f ()) ?(compressed = false) - is a local qcow2-format file, i.e. ‘-of qcow2’") - ); - -- let g = open_guestfs () in -- let preallocation = -- match output_alloc with -- | Preallocated -> Some "full" -- | Sparse -> None in -- changeuid ( -- fun () -> g#disk_create ?preallocation filename output_format size -+ if create then ( -+ let g = open_guestfs () in -+ let preallocation = -+ match output_alloc with -+ | Preallocated -> Some "full" -+ | Sparse -> None in -+ changeuid ( -+ fun () -> g#disk_create ?preallocation filename output_format size -+ ) - ); - - let pid = -@@ -151,6 +155,7 @@ let disk_path os name i = - - let create_local_output_disks dir - ?(compressed = false) -+ ?(create = true) - output_alloc output_format output_name output_storage - input_disks = - let input_sizes = get_disk_sizes input_disks in -@@ -171,25 +176,27 @@ let create_local_output_disks dir - error (f_"nbdkit-file-plugin is not installed or not working"); - - (* We still have to create the output disks. *) -- let g = open_guestfs () in -- let preallocation = -- match output_alloc with -- | Preallocated -> Some "full" -- | Sparse -> None in -- List.iter ( -- fun (size, filename) -> -- g#disk_create ?preallocation filename output_format size; -+ if create then ( -+ let g = open_guestfs () in -+ let preallocation = -+ match output_alloc with -+ | Preallocated -> Some "full" -+ | Sparse -> None in -+ List.iter ( -+ fun (size, filename) -> -+ g#disk_create ?preallocation filename output_format size; - -- (* We've had issues with there not being enough space to write -- * the disk image. Run df on the output filename. df follows -- * symlinks and reports the space on the filesystem. But don't -- * fail here if df cannot be run. -- *) -- if verbose () then ( -- let cmd = sprintf "df %s 1>&2" (quote filename) in -- ignore (Sys.command cmd) -- ) -- ) (List.combine input_sizes output_disk_names); -+ (* We've had issues with there not being enough space to write -+ * the disk image. Run df on the output filename. df follows -+ * symlinks and reports the space on the filesystem. But don't -+ * fail here if df cannot be run. -+ *) -+ if verbose () then ( -+ let cmd = sprintf "df %s 1>&2" (quote filename) in -+ ignore (Sys.command cmd) -+ ) -+ ) (List.combine input_sizes output_disk_names) -+ ); - - let socket = sprintf "%s/out0" dir in - On_exit.unlink socket; -@@ -220,7 +227,7 @@ let create_local_output_disks dir - On_exit.unlink socket; - - (* Create the actual output disk. *) -- output_to_local_file ~compressed output_alloc output_format -+ output_to_local_file ~compressed ~create output_alloc output_format - outdisk size socket; - - NBD_URI.Unix (socket, None) -diff --git a/output/output.mli b/output/output.mli -index 51bdde06..63a1c3f6 100644 ---- a/output/output.mli -+++ b/output/output.mli -@@ -84,6 +84,7 @@ val error_if_disk_count_gt : NBD_URI.t list -> int -> unit - - val create_local_output_disks : string -> - ?compressed:bool -> -+ ?create:bool -> - Types.output_allocation -> - string -> string -> string -> - NBD_URI.t list -> -@@ -98,7 +99,9 @@ val create_local_output_disks : string -> - type on_exit_kill = Kill | KillAndWait - - val output_to_local_file : ?changeuid:((unit -> unit) -> unit) -> -- ?compressed:bool -> ?on_exit_kill:on_exit_kill -> -+ ?compressed:bool -> -+ ?create:bool -> -+ ?on_exit_kill:on_exit_kill -> - Types.output_allocation -> - string -> string -> int64 -> string -> - unit diff --git a/0011-o-kubevirt-Add-oo-create-false-to-avoid-disk-creatio.patch b/0011-o-kubevirt-Add-oo-create-false-to-avoid-disk-creatio.patch deleted file mode 100644 index d218580..0000000 --- a/0011-o-kubevirt-Add-oo-create-false-to-avoid-disk-creatio.patch +++ /dev/null @@ -1,119 +0,0 @@ -From b0ac37f6c9f6ab8da44e631e9cb6af5649548634 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 8 Jul 2025 11:15:56 +0100 -Subject: [PATCH] -o kubevirt: Add -oo create=false to avoid disk creation - -Indicate that an external process will create the disks, so normal -creation of disks by virt-v2v should be skipped. - -Testing -------- - -I couldn't think of a way to add a test this since g#disk_create -(implemented in libguestfs.git:lib/create.c) will open(O_TRUNC) + -truncate(2) the existing disk, so the inode will remain the same. -Instead I tested it by hand by not creating the disk and observing the -error from nbdkit: - - nbdkit: error: realpath: /var/tmp/disk.img: No such file or directory - virt-v2v: error: nbdkit did not start up. There may be errors printed by - nbdkit above. - -Fixes: https://issues.redhat.com/browse/RHEL-101599 ---- - docs/virt-v2v.pod | 5 +++++ - output/output_kubevirt.ml | 17 +++++++++++------ - 2 files changed, 16 insertions(+), 6 deletions(-) - -diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod -index 5020d179..e228fb33 100644 ---- a/docs/virt-v2v.pod -+++ b/docs/virt-v2v.pod -@@ -603,6 +603,11 @@ For outputs which support qcow2 format (I<-of qcow2>), this writes a - compressed qcow2 file. It is the equivalent to the I<-c> option of - L. - -+=item B<-oo create=false> -+ -+For I<-o kubevirt>, indicate that another management process will -+create the output disks, so do not (re-)create them in virt-v2v. -+ - =item B<-oo disk=>DISK - - For I<-o kubevirt> this overrides the path to each output disk, -diff --git a/output/output_kubevirt.ml b/output/output_kubevirt.ml -index eae9c049..8a5ab56d 100644 ---- a/output/output_kubevirt.ml -+++ b/output/output_kubevirt.ml -@@ -36,7 +36,8 @@ let rfc1123_re = - - module Kubevirt = struct - type poptions = -- bool * string list option * output_allocation * string * string * string -+ bool * bool * string list option * -+ output_allocation * string * string * string - - type t = unit - -@@ -50,17 +51,21 @@ module Kubevirt = struct - printf (f_"Output options that can be used with -o kubevirt: - - -oo compressed Compress the output file (used only with -of qcow2) -+ -oo create=false Do not create the output disks - -oo disk=disk1 Specify filename of output disk (if used, must be - given once for each disk, else -os path is used) - ") - - let parse_options options source = - let compressed = ref false in -+ let create = ref true in - let disks = ref [] in - List.iter ( - function - | "compressed", "" -> compressed := true - | "compressed", v -> compressed := bool_of_string v -+ | "create", "" -> create := true -+ | "create", v -> create := bool_of_string v - | "disk", v -> List.push_back disks v - | k, _ -> - error (f_"-o kubevirt: unknown output option ‘-oo %s’") k -@@ -90,18 +95,18 @@ module Kubevirt = struct - - let disks = match !disks with [] -> None | disks -> Some disks in - -- !compressed, disks, -+ !compressed, !create, disks, - options.output_alloc, options.output_format, - output_name, output_storage - - let setup dir options source input_disks = -- let compressed, disks, -+ let compressed, create, disks, - output_alloc, output_format, output_name, output_storage = options in - - let uris = - match disks with - | None -> -- create_local_output_disks dir ~compressed -+ create_local_output_disks dir ~compressed ~create - output_alloc output_format output_name output_storage input_disks - | Some disks -> - (* -oo disk specified, so create the disks by hand. *) -@@ -118,7 +123,7 @@ module Kubevirt = struct - let socket = sprintf "%s/out%d" dir i in - On_exit.unlink socket; - -- output_to_local_file ~compressed -+ output_to_local_file ~compressed ~create - output_alloc output_format disk size socket; - - NBD_URI.Unix (socket, None) -@@ -128,7 +133,7 @@ module Kubevirt = struct - (), uris - - let finalize dir options () output_disks source inspect target_meta = -- let _, disks, -+ let _, _, disks, - output_alloc, output_format, output_name, output_storage = options in - - (* This function will return the disk path for the i'th disk. *) diff --git a/0018-RHEL-Remove-input-from-Xen.patch b/0018-RHEL-Remove-input-from-Xen.patch deleted file mode 100644 index e36b981..0000000 --- a/0018-RHEL-Remove-input-from-Xen.patch +++ /dev/null @@ -1,543 +0,0 @@ -From ef4fb3f73251ee72eb2c2c2e1f20a4392dc8a299 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 8 Jul 2024 09:35:54 +0100 -Subject: [PATCH] RHEL: Remove input from Xen - -Originally this bug was to remove input from RHEL 5 Xen only. This -change actually removes all conversions from Xen as in RHEL 9 we only -supported RHEL 5 Xen. - -Fixes: https://issues.redhat.com/browse/RHEL-37687 ---- - docs/Makefile.am | 14 ---- - docs/virt-v2v-input-xen.pod | 154 ------------------------------------ - docs/virt-v2v.pod | 50 ++---------- - input/Makefile.am | 2 - - input/input_xen_ssh.ml | 136 ------------------------------- - input/input_xen_ssh.mli | 21 ----- - input/select_input.ml | 4 - - v2v/v2v.ml | 1 - - 8 files changed, 5 insertions(+), 377 deletions(-) - delete mode 100644 docs/virt-v2v-input-xen.pod - delete mode 100644 input/input_xen_ssh.ml - delete mode 100644 input/input_xen_ssh.mli - -diff --git a/docs/Makefile.am b/docs/Makefile.am -index 14b0b074..aa899304 100644 ---- a/docs/Makefile.am -+++ b/docs/Makefile.am -@@ -23,7 +23,6 @@ EXTRA_DIST = \ - virt-v2v-hacking.pod \ - virt-v2v-in-place.pod \ - virt-v2v-input-vmware.pod \ -- virt-v2v-input-xen.pod \ - virt-v2v-inspector.pod \ - virt-v2v-open.pod \ - virt-v2v-output-local.pod \ -@@ -45,7 +44,6 @@ man_MANS = \ - virt-v2v-hacking.1 \ - virt-v2v-in-place.1 \ - virt-v2v-input-vmware.1 \ -- virt-v2v-input-xen.1 \ - virt-v2v-inspector.1 \ - virt-v2v-open.1 \ - virt-v2v-output-local.1 \ -@@ -64,7 +62,6 @@ noinst_DATA = \ - $(top_builddir)/website/virt-v2v-hacking.1.html \ - $(top_builddir)/website/virt-v2v-in-place.1.html \ - $(top_builddir)/website/virt-v2v-input-vmware.1.html \ -- $(top_builddir)/website/virt-v2v-input-xen.1.html \ - $(top_builddir)/website/virt-v2v-inspector.1.html \ - $(top_builddir)/website/virt-v2v-open.1.html \ - $(top_builddir)/website/virt-v2v-output-local.1.html \ -@@ -125,17 +122,6 @@ stamp-virt-v2v-input-vmware.pod: virt-v2v-input-vmware.pod - $< - touch $@ - --virt-v2v-input-xen.1 $(top_builddir)/website/virt-v2v-input-xen.1.html: stamp-virt-v2v-input-xen.pod -- --stamp-virt-v2v-input-xen.pod: virt-v2v-input-xen.pod -- $(PODWRAPPER) \ -- --man virt-v2v-input-xen.1 \ -- --html $(top_builddir)/website/virt-v2v-input-xen.1.html \ -- --license GPLv2+ \ -- --warning safe \ -- $< -- touch $@ -- - virt-v2v-inspector.1 $(top_builddir)/website/virt-v2v-inspector.1.html: stamp-virt-v2v-inspector.pod - - stamp-virt-v2v-inspector.pod: virt-v2v-inspector.pod -diff --git a/docs/virt-v2v-input-xen.pod b/docs/virt-v2v-input-xen.pod -deleted file mode 100644 -index 0417e89f..00000000 ---- a/docs/virt-v2v-input-xen.pod -+++ /dev/null -@@ -1,154 +0,0 @@ --=head1 NAME -- --virt-v2v-input-xen - Using virt-v2v to convert guests from Xen -- --=head1 SYNOPSIS -- -- virt-v2v -ic 'xen+ssh://root@xen.example.com' -- -ip passwordfile -- GUEST_NAME [-o* options] -- --=head1 DESCRIPTION -- --This page documents how to use L to convert guests from --RHEL 5 Xen, or SLES and OpenSUSE Xen hosts. -- --=head1 INPUT FROM XEN -- --=head2 SSH authentication -- --You can use SSH password authentication, by supplying the name of a --file containing the password to the I<-ip> option (note this option --does I take the password directly). You may need to adjust --F on the Xen server to set --C. -- --If you are not using password authentication, an alternative is to use --ssh-agent, and add your ssh public key to --F (on the Xen host). After doing this, --you should check that passwordless access works from the virt-v2v --server to the Xen host. For example: -- -- $ ssh root@xen.example.com -- [ logs straight into the shell, no password is requested ] -- --Note that support for non-interactive authentication via the I<-ip> --option is incomplete. Some operations remain that still require the --user to enter the password manually. Therefore ssh-agent is recommended --over the I<-ip> option. See L. -- --With some modern ssh implementations, legacy crypto algorithms required --to interoperate with RHEL 5 sshd are disabled. To enable them, you may --need to add the following C stanza to your F<~/.ssh/config>: -- -- Host xen.example.com -- KexAlgorithms +diffie-hellman-group14-sha1 -- MACs +hmac-sha1 -- HostKeyAlgorithms +ssh-rsa -- PubkeyAcceptedKeyTypes +ssh-rsa -- PubkeyAcceptedAlgorithms +ssh-rsa -- --(C and C have --identical meaning; the former is the old option name, the latter is the --new one. Virt-v2v uses both C and C when converting a guest --from Xen, and on some operating systems, C and C may not --both accept the same option variant.) -- --When connecting to RHEL 5 sshd from RHEL 9, the SHA1 algorithm's use in --signatures has to be re-enabled at the OpenSSL level, in addition to the --above SSH configuration. Create a file called F<$HOME/openssl-sha1.cnf> --with the following contents: -- -- .include /etc/ssl/openssl.cnf -- [openssl_init] -- alg_section = evp_properties -- [evp_properties] -- rh-allow-sha1-signatures = yes -- --and export the following variable into the environment of the --C process: -- -- OPENSSL_CONF=$HOME/openssl-sha1.cnf -- --Note that the C environment variable will only take effect --if the libvirt client library used by virt-v2v is at least version --8.6.0. -- --=head2 Test libvirt connection to remote Xen host -- --Use the L command to list the guests on the remote Xen host: -- -- $ virsh -c xen+ssh://root@xen.example.com list --all -- Id Name State -- ---------------------------------------------------- -- 0 Domain-0 running -- - rhel49-x86_64-pv shut off -- --You should also try dumping the metadata from any guest on your --server, like this: -- -- $ virsh -c xen+ssh://root@xen.example.com dumpxml rhel49-x86_64-pv -- -- rhel49-x86_64-pv -- [...] -- -- --B. Fix your libvirt configuration or the remote server --before continuing. -- --B, then the --conversion will fail. See L --below for a workaround. -- --=head2 Importing a guest -- --To import a particular guest from a Xen server, do: -- -- $ virt-v2v -ic 'xen+ssh://root@xen.example.com' \ -- rhel49-x86_64-pv \ -- -o local -os /var/tmp -- --where C is the name of the guest (which must be shut --down). -- --In this case the output flags are set to write the converted guest to --a temporary directory as this is just an example, but you can also --write to libvirt or any other supported target. -- --=head2 Xen or ssh conversions from block devices -- --Currently virt-v2v cannot directly access a Xen guest (or any guest --located remotely over ssh) if that guest’s disks are located on host --block devices. -- --To tell if a Xen guest uses host block devices, look at the guest XML. --You will see: -- -- -- ... -- -- --where C, C and C are all --indications that the disk is located on a host block device. -- --This happens because the qemu ssh block driver that we use to access --remote disks uses the ssh sftp protocol, and this protocol cannot --correctly detect the size of host block devices. -- --The workaround is to copy the block device from the remote Xen --server to a regular local file, copy the libvirt guest XML, --adjust the C element to point to the local file, and use --C<-i libvirtxml> mode instead. -- --=head1 SEE ALSO -- --L. -- --=head1 AUTHOR -- --Richard W.M. Jones -- --=head1 COPYRIGHT -- --Copyright (C) 2009-2025 Red Hat Inc. -diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod -index 35886561..8e31fd0b 100644 ---- a/docs/virt-v2v.pod -+++ b/docs/virt-v2v.pod -@@ -12,7 +12,7 @@ virt-v2v - Convert a guest to use KVM - =head1 DESCRIPTION - - Virt-v2v converts a single guest from a foreign hypervisor to run on --KVM. It can read Linux and Windows guests running on VMware, Xen, -+KVM. It can read Linux and Windows guests running on VMware, - Hyper-V and some other hypervisors, and convert them to KVM managed by - libvirt, OpenStack, oVirt, or several other targets. It can modify - the guest to make it bootable on KVM and install virtio drivers so it -@@ -59,8 +59,6 @@ management systems, guests. - - L — Input from VMware. - --L — Input from Xen. -- - L — Output to local files or local libvirt. - - L — Output to oVirt -@@ -189,10 +187,6 @@ This is only supported for: - - =item * - --L -- --=item * -- - L - when using the SSH transport method - -@@ -304,12 +298,10 @@ hypervisor. See L. - Specify a libvirt connection URI to use when reading the guest. This - is only used when S>. - --Only local libvirt connections, VMware vCenter connections, or RHEL 5 --Xen remote connections can be used. Other remote libvirt connections --will not work in general. -+Only local libvirt connections or VMware vCenter connections. -+Other remote libvirt connections will not work in general. - --See also L, --L. -+See also L. - - =item B<-if> format - -@@ -883,7 +875,7 @@ bandwidth. Virt-v2v should be able to copy guest data at gigabit - ethernet speeds or greater. - - Ensure that the network connections between servers (conversion --server, NFS server, vCenter, Xen) are as fast and as low latency as -+server, NFS server, vCenter) are as fast and as low latency as - possible. - - =head2 Disk space -@@ -1182,38 +1174,6 @@ changes to the Windows Registry and filesystem. - - =head1 NOTES - --=head2 Xen paravirtualized guests -- --Older versions of virt-v2v could turn a Xen paravirtualized (PV) guest --into a KVM guest by installing a new kernel. This version of virt-v2v --does I attempt to install any new kernels. Instead it will give --you an error if there are I Xen PV kernels available. -- --Therefore before conversion you should check that a regular kernel is --installed. For some older Linux distributions, this means installing --a kernel from the table below: -- -- RHEL 4 i686 with > 10GB of RAM: install 'kernel-hugemem' -- i686 SMP: install 'kernel-smp' -- other i686: install 'kernel' -- x86-64 SMP with > 8 CPUs: install 'kernel-largesmp' -- x86-64 SMP: install 'kernel-smp' -- other x86-64: install 'kernel' -- -- RHEL 5 i686: install 'kernel-PAE' -- x86-64: install 'kernel' -- -- SLES 10 i586 with > 10GB of RAM: install 'kernel-bigsmp' -- i586 SMP: install 'kernel-smp' -- other i586: install 'kernel-default' -- x86-64 SMP: install 'kernel-smp' -- other x86-64: install 'kernel-default' -- -- SLES 11+ i586: install 'kernel-pae' -- x86-64: install 'kernel-default' -- -- Windows (Does not apply, as there is no Xen PV Windows kernel) -- - =head2 Enabling virtio - - "Virtio" is the name for a set of drivers which make disk (block -diff --git a/input/Makefile.am b/input/Makefile.am -index d5e77f76..98ea5223 100644 ---- a/input/Makefile.am -+++ b/input/Makefile.am -@@ -29,7 +29,6 @@ SOURCES_MLI = \ - input_vcenter_https.mli \ - input_vddk.mli \ - input_vmx.mli \ -- input_xen_ssh.mli \ - name_from_disk.mli \ - nbdkit_curl.mli \ - nbdkit_ssh.mli \ -@@ -60,7 +59,6 @@ SOURCES_ML = \ - input_vcenter_https.ml \ - input_vddk.ml \ - input_vmx.ml \ -- input_xen_ssh.ml \ - select_input.ml - - # We pretend that we're building a C library. automake handles the -diff --git a/input/input_xen_ssh.ml b/input/input_xen_ssh.ml -deleted file mode 100644 -index 45864cfe..00000000 ---- a/input/input_xen_ssh.ml -+++ /dev/null -@@ -1,136 +0,0 @@ --(* helper-v2v-input -- * Copyright (C) 2009-2025 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 Common_gettext.Gettext -- --open Types --open Utils -- --open Parse_libvirt_xml --open Input -- --module XenSSH = struct -- let to_string options args = -- let xs = args in -- let xs = -- match options.input_conn with -- | Some ic -> ("-ic " ^ ic) :: xs -- | None -> xs in -- let xs = "-i libvirt" :: xs in -- String.concat " " xs -- -- let query_input_options () = -- printf (f_"No input options can be used in this mode.\n") -- -- let setup dir options args = -- if options.input_options <> [] then -- error (f_"no -io (input options) are allowed here"); -- -- if not options.read_only then -- error (f_"in-place mode does not work with Xen over SSH source"); -- -- (* Get the guest name. *) -- let guest = -- match args with -- | [arg] -> arg -- | _ -> -- error (f_"-i libvirt: expecting a libvirt guest name \ -- on the command line") in -- -- (* -ic must be set. *) -- let input_conn = -- match options.input_conn with -- | Some ic -> ic -- | None -> -- error (f_"-i libvirt: expecting -ic parameter for \ -- Xen over SSH connection") in -- -- let uri = -- try Xml.parse_uri input_conn -- with Invalid_argument msg -> -- error (f_"could not parse '-ic %s'. Original error message was: %s") -- input_conn msg in -- -- (* Connect to the hypervisor. *) -- let conn = -- let auth = Libvirt_utils.auth_for_password_file -- ?password_file:options.input_password () in -- Libvirt.Connect.connect_auth ~name:input_conn auth in -- -- (* Parse the libvirt XML. *) -- let source, disks, _ = parse_libvirt_domain conn guest in -- -- let server = -- match uri.Xml.uri_server with -- | Some server -> server -- | None -> -- error (f_"‘-ic %s’ URL does not contain a host name field") -- input_conn in -- -- let port = -- match uri.uri_port with -- | 0 | 22 -> None -- | i -> Some (string_of_int i) in -- -- let user = uri.uri_user in -- -- let password = -- match options.input_password with -- | None -> None -- | Some ip -> Some (Nbdkit_ssh.PasswordFile ip) in -- -- (* Create an nbdkit instance for each disk. *) -- let uris = -- List.mapi ( -- fun i { d_format = format; d_type } -> -- let socket = sprintf "%s/in%d" dir i in -- On_exit.unlink socket; -- -- (match d_type with -- | NBD _ | HTTP _ -> (* These should never happen? *) -- assert false -- -- | BlockDev _ -> -- (* Conversion from a remote block device over SSH isn't -- * supported because OpenSSH sftp server doesn't know how -- * to get the size of a block device. Therefore we disallow -- * this and refer users to the manual. -- *) -- error (f_"input from xen over ssh does not support disks stored \ -- on remote block devices. See virt-v2v-input-xen(1) \ -- section \"Xen or ssh conversions from block devices\".") -- -- | LocalFile path -> -- let cor = dir // "convert" in -- let bandwidth = options.bandwidth in -- let nbdkit = Nbdkit_ssh.create_ssh ?bandwidth ~cor ?password -- ?port ~server ?user path in -- let _, pid = Nbdkit.run_unix socket nbdkit in -- On_exit.kill pid -- ); -- -- NBD_URI.Unix (socket, None) -- ) disks in -- -- source, uris --end -diff --git a/input/input_xen_ssh.mli b/input/input_xen_ssh.mli -deleted file mode 100644 -index 339309b8..00000000 ---- a/input/input_xen_ssh.mli -+++ /dev/null -@@ -1,21 +0,0 @@ --(* virt-v2v -- * Copyright (C) 2009-2025 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. -- *) -- --(** Input from Xen over SSH *) -- --module XenSSH : Input.INPUT -diff --git a/input/select_input.ml b/input/select_input.ml -index a5eb1433..bbf0180f 100644 ---- a/input/select_input.ml -+++ b/input/select_input.ml -@@ -90,10 +90,6 @@ let select_input ?(allow_remote = true) input_mode input_conn input_transport = - | Some server, Some ("esx"|"gsx"|"vpx"), Some Input.VDDK, true -> - (module Input_vddk.VDDK) - -- (* Xen over SSH *) -- | Some server, Some "xen+ssh", _, true -> -- (module Input_xen_ssh.XenSSH) -- - (* Old virt-v2v also supported qemu+ssh://. However I am - * deliberately not supporting this in new virt-v2v. Don't - * use virt-v2v if a guest already runs on KVM. -diff --git a/v2v/v2v.ml b/v2v/v2v.ml -index c780ab1d..1811f9e6 100644 ---- a/v2v/v2v.ml -+++ b/v2v/v2v.ml -@@ -335,7 +335,6 @@ read the man page virt-v2v(1). - pr "virt-v2v-2.0\n"; - pr "libguestfs-rewrite\n"; - pr "vcenter-https\n"; -- pr "xen-ssh\n"; - pr "vddk\n"; - pr "colours-option\n"; - pr "vdsm-compat-option\n"; diff --git a/0019-RHEL-Remove-o-glance.patch b/0019-RHEL-Remove-o-glance.patch deleted file mode 100644 index f6f1815..0000000 --- a/0019-RHEL-Remove-o-glance.patch +++ /dev/null @@ -1,239 +0,0 @@ -From 5c5d4163dfa7cbdd10450d677a85aeaf87e1a14b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 30 Jun 2021 11:15:52 +0100 -Subject: [PATCH] RHEL: Remove -o glance - -Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1977539 ---- - docs/virt-v2v-output-openstack.pod | 54 ++---------------------------- - docs/virt-v2v.pod | 20 ----------- - output/output_glance.mli | 2 +- - output/select_output.ml | 5 --- - output/select_output.mli | 1 - - tests/test-o-glance.sh | 3 ++ - v2v/v2v.ml | 2 -- - 7 files changed, 6 insertions(+), 81 deletions(-) - -diff --git a/docs/virt-v2v-output-openstack.pod b/docs/virt-v2v-output-openstack.pod -index 9bef76ea..04595816 100644 ---- a/docs/virt-v2v-output-openstack.pod -+++ b/docs/virt-v2v-output-openstack.pod -@@ -10,13 +10,10 @@ virt-v2v-output-openstack - Using virt-v2v to convert guests to OpenStack - [-oo verify-server-certificate=false] - [-oo os-username=admin] [-oo os-*=*] - -- virt-v2v [-i* options] -o glance -- - =head1 DESCRIPTION - - This page documents how to use L to convert guests to run --on OpenStack. There are two output modes you can select, but only --I<-o openstack> should be used normally. -+on OpenStack. - - =over 4 - -@@ -27,15 +24,6 @@ Full description: L - This is the modern method for uploading to OpenStack via the REST API. - Guests can be directly converted into Cinder volumes. - --=item B<-o glance> -- --Full description: L -- --This is the old method for uploading to Glance. Unfortunately Glance --is not well suited to storing converted guests (since virt-v2v deals --with "pets" not templated "cattle"), so this method is not recommended --unless you really know what you are doing. -- - =back - - =head1 OUTPUT TO OPENSTACK -@@ -176,48 +164,10 @@ no Cinder volume type is used. - The following options are B supported with OpenStack: I<-oa>, - I<-of>. - --=head1 OUTPUT TO GLANCE -- --Note this is a legacy option. In most cases you should use --L instead. -- --To output to OpenStack Glance, use the I<-o glance> option. -- --This runs the L CLI program which must be installed on the --virt-v2v conversion host. For authentication to work, you will need --to set C environment variables. See --L above. -- --Virt-v2v adds metadata for the guest to Glance, describing such things --as the guest operating system and what drivers it requires. The --command C will display the metadata as "Property" --fields such as C and C. -- --=head2 Glance and sparseness -- --Glance image upload doesn't appear to correctly handle sparseness. --For this reason, using qcow2 will be faster and use less space on the --Glance server. Use the virt-v2v S> option. -- --=head2 Glance and multiple disks -- --If the guest has a single disk, then the name of the disk in Glance --will be the name of the guest. You can control this using the I<-on> --option. -- --Glance doesn't have a concept of associating multiple disks with a --single guest, and Nova doesn't allow you to boot a guest from multiple --Glance disks either. If the guest has multiple disks, then the first --(assumed to be the system disk) will have the name of the guest, and --the second and subsequent data disks will be called --C-disk2>, C-disk3> etc. It may be best to --leave the system disk in Glance, and import the data disks to Cinder. -- - =head1 SEE ALSO - - L, --L, --L. -+L. - - =head1 AUTHOR - -diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod -index 8e31fd0b..fde60a8c 100644 ---- a/docs/virt-v2v.pod -+++ b/docs/virt-v2v.pod -@@ -439,14 +439,6 @@ See L below. - - This is the same as I<-o local>. - --=item B<-o> B -- --This is a legacy option. You should probably use I<-o openstack> --instead. -- --Set the output method to OpenStack Glance. In this mode the converted --guest is uploaded to Glance. See L. -- - =item B<-o> B - - Set the output method to I. B (or F). - --=item I<-o glance> -- --This temporarily places a full copy of the output disks in --C<$VIRT_V2V_TMPDIR> (or F). -- - =item I<-o local> - - =item I<-o qemu> -@@ -1053,13 +1040,6 @@ See also L. - Because of how Cinder volumes are presented as F block devices, - using I<-o openstack> normally requires that virt-v2v is run as root. - --=item Writing to Glance -- --This does I need root (in fact it probably won’t work), but may --require either a special user and/or for you to source a script that --sets authentication environment variables. Consult the Glance --documentation. -- - =item Writing to block devices - - This normally requires root. See the next section. -diff --git a/output/output_glance.mli b/output/output_glance.mli -index 83d67576..7ab1503c 100644 ---- a/output/output_glance.mli -+++ b/output/output_glance.mli -@@ -18,4 +18,4 @@ - - (** [-o glance] output mode. *) - --module Glance : Output.OUTPUT -+(*module Glance : Output.OUTPUT*) -diff --git a/output/select_output.ml b/output/select_output.ml -index ab4bfe4d..b1f7d0ab 100644 ---- a/output/select_output.ml -+++ b/output/select_output.ml -@@ -21,7 +21,6 @@ open Common_gettext.Gettext - - type output_mode = - | Disk -- | Glance - | Kubevirt - | Libvirt - | Null -@@ -33,7 +32,6 @@ type output_mode = - - let output_modes = [ - Disk; -- Glance; - Kubevirt; - Libvirt; - Null; -@@ -46,7 +44,6 @@ let output_modes = [ - - let string_of_output_mode = function - | Disk -> "disk" -- | Glance -> "glance" - | Kubevirt -> "kubevirt" - | Libvirt -> "libvirt" - | Null -> "null" -@@ -57,7 +54,6 @@ let string_of_output_mode = function - | VDSM -> "vdsm" - - let output_mode_of_string = function -- | "glance" -> Glance - | "kubevirt" -> Kubevirt - | "libvirt" -> Libvirt - | "disk" | "local" -> Disk -@@ -75,7 +71,6 @@ let select_output = function - | Some Disk -> (module Output_disk.Disk) - | Some Null -> (module Output_null.Null) - | Some QEmu -> (module Output_qemu.QEMU) -- | Some Glance -> (module Output_glance.Glance) - | Some Kubevirt -> (module Output_kubevirt.Kubevirt) - | Some Openstack -> (module Output_openstack.Openstack) - | Some OVirt_Upload -> (module Output_ovirt_upload.OVirtUpload) -diff --git a/output/select_output.mli b/output/select_output.mli -index a509a1db..093c9b9a 100644 ---- a/output/select_output.mli -+++ b/output/select_output.mli -@@ -18,7 +18,6 @@ - - type output_mode = - | Disk -- | Glance - | Kubevirt - | Libvirt - | Null -diff --git a/tests/test-o-glance.sh b/tests/test-o-glance.sh -index 9e32d2bf..632579ee 100755 ---- a/tests/test-o-glance.sh -+++ b/tests/test-o-glance.sh -@@ -20,6 +20,9 @@ - - set -e - -+# Feature is disabled in RHEL 9. -+exit 77 -+ - source ./functions.sh - set -e - set -x -diff --git a/v2v/v2v.ml b/v2v/v2v.ml -index 1811f9e6..5d3a9dbb 100644 ---- a/v2v/v2v.ml -+++ b/v2v/v2v.ml -@@ -267,8 +267,6 @@ 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 -- - There is a companion front-end called \"virt-p2v\" which comes as an - ISO or CD image that can be booted on physical machines. - diff --git a/0021-RHEL-Remove-block-driver-option.patch b/0021-RHEL-Remove-block-driver-option.patch deleted file mode 100644 index 08bc1c9..0000000 --- a/0021-RHEL-Remove-block-driver-option.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 0c2aebab2d1c3cf7a02c16dd6a5af4ae55a69995 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 28 Apr 2023 12:28:19 +0100 -Subject: [PATCH] RHEL: Remove --block-driver option - -Go back to the old default of always installing virtio-blk drivers in -Windows guests. - -Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2190387 ---- - docs/virt-v2v-in-place.pod | 10 ---------- - docs/virt-v2v.pod | 10 ---------- - in-place/in_place.ml | 11 +---------- - tests/Makefile.am | 1 - - v2v/v2v.ml | 11 +---------- - 5 files changed, 2 insertions(+), 41 deletions(-) - -diff --git a/docs/virt-v2v-in-place.pod b/docs/virt-v2v-in-place.pod -index 6c02a99c..3d0d1b28 100644 ---- a/docs/virt-v2v-in-place.pod -+++ b/docs/virt-v2v-in-place.pod -@@ -72,16 +72,6 @@ Display help. - - See I<--network> below. - --=item B<--block-driver> B -- --=item B<--block-driver> B -- --When choosing a block driver for Windows guests, prefer C or --C. The default is C. -- --Note this has no effect for Linux guests at the moment. That may be --added in future. -- - =item B<--colors> - - =item B<--colours> -diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod -index fde60a8c..0e68de10 100644 ---- a/docs/virt-v2v.pod -+++ b/docs/virt-v2v.pod -@@ -212,16 +212,6 @@ The options are silently ignored for other input methods. - - See I<--network> below. - --=item B<--block-driver> B -- --=item B<--block-driver> B -- --When choosing a block driver for Windows guests, prefer C or --C. The default is C. -- --Note this has no effect for Linux guests at the moment. That may be --added in future. -- - =item B<--colors> - - =item B<--colours> -diff --git a/in-place/in_place.ml b/in-place/in_place.ml -index 604a662d..a91ee39d 100644 ---- a/in-place/in_place.ml -+++ b/in-place/in_place.ml -@@ -49,7 +49,6 @@ let rec main () = - - let bandwidth = ref None in - let bandwidth_file = ref None in -- let block_driver = ref None in - let input_conn = ref None in - let input_format = ref None in - let input_password = ref None in -@@ -162,8 +161,6 @@ let rec main () = - let argspec = [ - [ S 'b'; L"bridge" ], Getopt.String ("in:out", add_bridge), - s_"Map bridge ‘in’ to ‘out’"; -- [ L"block-driver" ], Getopt.String ("driver", set_string_option_once "--block-driver" block_driver), -- s_"Prefer 'virtio-blk' or 'virtio-scsi'"; - [ S 'i' ], Getopt.String (input_modes, set_input_mode), - s_"Set input mode (default: libvirt)"; - [ M"ic" ], Getopt.String ("uri", set_string_option_once "-ic" input_conn), -@@ -230,12 +227,6 @@ read the man page virt-v2v-in-place(1). - - (* Dereference the arguments. *) - let args = List.rev !args in -- let block_driver = -- match !block_driver with -- | None | Some "virtio-blk" -> Virtio_blk -- | Some "virtio-scsi" -> Virtio_SCSI -- | Some driver -> -- error (f_"unknown block driver ‘--block-driver %s’") driver in - let customize_ops = get_customize_ops () in - let input_conn = !input_conn in - let input_mode = !input_mode in -@@ -298,7 +289,7 @@ read the man page virt-v2v-in-place(1). - - (* Get the conversion options. *) - let conv_options = { -- Convert.block_driver = block_driver; -+ Convert.block_driver = Virtio_blk; - keep_serial_console = true; - ks = opthandle.ks; - network_map; -diff --git a/tests/Makefile.am b/tests/Makefile.am -index f9c748ed..c0aa8498 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -57,7 +57,6 @@ TESTS_ENVIRONMENT = $(top_builddir)/run --test - - TESTS = \ - test-bad-networks-and-bridges.sh \ -- test-block-driver.sh \ - test-cdrom.sh \ - test-checksum-bad.sh \ - test-checksum-good-qcow2.sh \ -diff --git a/v2v/v2v.ml b/v2v/v2v.ml -index 5d3a9dbb..2e8071db 100644 ---- a/v2v/v2v.ml -+++ b/v2v/v2v.ml -@@ -48,7 +48,6 @@ let rec main () = - - let bandwidth = ref None in - let bandwidth_file = ref None in -- let block_driver = ref None in - let input_conn = ref None in - let input_format = ref None in - let input_password = ref None in -@@ -201,8 +200,6 @@ let rec main () = - s_"Set bandwidth dynamically from file"; - [ S 'b'; L"bridge" ], Getopt.String ("in:out", add_bridge), - s_"Map bridge ‘in’ to ‘out’"; -- [ L"block-driver" ], Getopt.String ("driver", set_string_option_once "--block-driver" block_driver), -- s_"Prefer 'virtio-blk' or 'virtio-scsi'"; - [ S 'i' ], Getopt.String (input_modes, set_input_mode), - s_"Set input mode (default: libvirt)"; - [ M"ic" ], Getopt.String ("uri", set_string_option_once "-ic" input_conn), -@@ -295,12 +292,6 @@ read the man page virt-v2v(1). - - (* Dereference the arguments. *) - let args = List.rev !args in -- let block_driver = -- match !block_driver with -- | None | Some "virtio-blk" -> Virtio_blk -- | Some "virtio-scsi" -> Virtio_SCSI -- | Some driver -> -- error (f_"unknown block driver ‘--block-driver %s’") driver in - let customize_ops = get_customize_ops () in - let input_conn = !input_conn in - let input_mode = !input_mode in -@@ -413,7 +404,7 @@ read the man page virt-v2v(1). - - (* Get the conversion options. *) - let conv_options = { -- Convert.block_driver = block_driver; -+ Convert.block_driver = Virtio_blk; - keep_serial_console = not remove_serial_console; - ks = opthandle.ks; - network_map; diff --git a/0022-RHEL-Remove-o-ovirt-o-ovirt-upload-and-o-vdsm-modes.patch b/0022-RHEL-Remove-o-ovirt-o-ovirt-upload-and-o-vdsm-modes.patch deleted file mode 100644 index a87f086..0000000 --- a/0022-RHEL-Remove-o-ovirt-o-ovirt-upload-and-o-vdsm-modes.patch +++ /dev/null @@ -1,4712 +0,0 @@ -From 089fcc5c95211ba3100a622326cba2da859141ce Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 8 Jul 2024 09:56:54 +0100 -Subject: [PATCH] RHEL: Remove -o ovirt, -o ovirt-upload and -o vdsm modes - -Fixes: https://issues.redhat.com/browse/RHEL-36712 ---- - docs/Makefile.am | 14 - - docs/virt-v2v-output-ovirt.pod | 231 -------- - docs/virt-v2v.pod | 201 +------ - output/Makefile.am | 43 +- - output/output_ovirt.ml | 319 ----------- - output/output_ovirt.mli | 21 - - output/output_ovirt_upload.ml | 514 ----------------- - output/output_ovirt_upload.mli | 21 - - output/output_ovirt_upload_cancel_source.mli | 19 - - .../output_ovirt_upload_createvm_source.mli | 19 - - .../output_ovirt_upload_finalize_source.mli | 19 - - output/output_ovirt_upload_plugin_source.mli | 19 - - .../output_ovirt_upload_precheck_source.mli | 19 - - .../output_ovirt_upload_transfer_source.mli | 19 - - output/output_ovirt_upload_vmcheck_source.mli | 19 - - output/output_vdsm.ml | 239 -------- - output/output_vdsm.mli | 21 - - output/ovirt-upload-cancel.py | 96 ---- - output/ovirt-upload-createvm.py | 137 ----- - output/ovirt-upload-finalize.py | 174 ------ - output/ovirt-upload-plugin.py | 525 ------------------ - output/ovirt-upload-precheck.py | 135 ----- - output/ovirt-upload-transfer.py | 298 ---------- - output/ovirt-upload-vmcheck.py | 72 --- - output/select_output.ml | 16 - - output/select_output.mli | 3 - - tests/Makefile.am | 15 - - tests/test-o-ovirt-upload-module/imageio.py | 71 --- - .../ovirtsdk4/__init__.py | 150 ----- - .../ovirtsdk4/types.py | 184 ------ - tests/test-o-ovirt-upload-oo-query.sh | 41 -- - tests/test-o-ovirt-upload.sh | 74 --- - tests/test-o-ovirt.ovf.expected | 113 ---- - tests/test-o-ovirt.sh | 87 --- - tests/test-o-vdsm-oo-query.sh | 41 -- - tests/test-o-vdsm-options.ovf.expected | 113 ---- - tests/test-o-vdsm-options.sh | 96 ---- - v2v/v2v.ml | 5 - - 38 files changed, 4 insertions(+), 4199 deletions(-) - delete mode 100644 docs/virt-v2v-output-ovirt.pod - delete mode 100644 output/output_ovirt.ml - delete mode 100644 output/output_ovirt.mli - delete mode 100644 output/output_ovirt_upload.ml - delete mode 100644 output/output_ovirt_upload.mli - delete mode 100644 output/output_ovirt_upload_cancel_source.mli - delete mode 100644 output/output_ovirt_upload_createvm_source.mli - delete mode 100644 output/output_ovirt_upload_finalize_source.mli - delete mode 100644 output/output_ovirt_upload_plugin_source.mli - delete mode 100644 output/output_ovirt_upload_precheck_source.mli - delete mode 100644 output/output_ovirt_upload_transfer_source.mli - delete mode 100644 output/output_ovirt_upload_vmcheck_source.mli - delete mode 100644 output/output_vdsm.ml - delete mode 100644 output/output_vdsm.mli - delete mode 100644 output/ovirt-upload-cancel.py - delete mode 100644 output/ovirt-upload-createvm.py - delete mode 100644 output/ovirt-upload-finalize.py - delete mode 100644 output/ovirt-upload-plugin.py - delete mode 100644 output/ovirt-upload-precheck.py - delete mode 100644 output/ovirt-upload-transfer.py - delete mode 100644 output/ovirt-upload-vmcheck.py - delete mode 100755 tests/test-o-ovirt-upload-module/imageio.py - delete mode 100644 tests/test-o-ovirt-upload-module/ovirtsdk4/__init__.py - delete mode 100644 tests/test-o-ovirt-upload-module/ovirtsdk4/types.py - delete mode 100755 tests/test-o-ovirt-upload-oo-query.sh - delete mode 100755 tests/test-o-ovirt-upload.sh - delete mode 100644 tests/test-o-ovirt.ovf.expected - delete mode 100755 tests/test-o-ovirt.sh - delete mode 100755 tests/test-o-vdsm-oo-query.sh - delete mode 100644 tests/test-o-vdsm-options.ovf.expected - delete mode 100755 tests/test-o-vdsm-options.sh - -diff --git a/docs/Makefile.am b/docs/Makefile.am -index aa899304..9639b352 100644 ---- a/docs/Makefile.am -+++ b/docs/Makefile.am -@@ -27,7 +27,6 @@ EXTRA_DIST = \ - virt-v2v-open.pod \ - virt-v2v-output-local.pod \ - virt-v2v-output-openstack.pod \ -- virt-v2v-output-ovirt.pod \ - virt-v2v-release-notes-1.42.pod \ - virt-v2v-release-notes-2.0.pod \ - virt-v2v-release-notes-2.2.pod \ -@@ -48,7 +47,6 @@ man_MANS = \ - virt-v2v-open.1 \ - virt-v2v-output-local.1 \ - virt-v2v-output-openstack.1 \ -- virt-v2v-output-ovirt.1 \ - virt-v2v-release-notes-1.42.1 \ - virt-v2v-release-notes-2.0.1 \ - virt-v2v-release-notes-2.2.1 \ -@@ -66,7 +64,6 @@ noinst_DATA = \ - $(top_builddir)/website/virt-v2v-open.1.html \ - $(top_builddir)/website/virt-v2v-output-local.1.html \ - $(top_builddir)/website/virt-v2v-output-openstack.1.html \ -- $(top_builddir)/website/virt-v2v-output-ovirt.1.html \ - $(top_builddir)/website/virt-v2v-release-notes-1.42.1.html \ - $(top_builddir)/website/virt-v2v-release-notes-2.0.1.html \ - $(top_builddir)/website/virt-v2v-release-notes-2.2.1.html \ -@@ -168,17 +165,6 @@ stamp-virt-v2v-output-openstack.pod: virt-v2v-output-openstack.pod - $< - touch $@ - --virt-v2v-output-ovirt.1 $(top_builddir)/website/virt-v2v-output-ovirt.1.html: stamp-virt-v2v-output-ovirt.pod -- --stamp-virt-v2v-output-ovirt.pod: virt-v2v-output-ovirt.pod -- $(PODWRAPPER) \ -- --man virt-v2v-output-ovirt.1 \ -- --html $(top_builddir)/website/virt-v2v-output-ovirt.1.html \ -- --license GPLv2+ \ -- --warning safe \ -- $< -- touch $@ -- - virt-v2v-release-notes-1.42.1 $(top_builddir)/website/virt-v2v-release-notes-1.42.1.html: stamp-virt-v2v-release-notes-1.42.pod - - stamp-virt-v2v-release-notes-1.42.pod: virt-v2v-release-notes-1.42.pod -diff --git a/docs/virt-v2v-output-ovirt.pod b/docs/virt-v2v-output-ovirt.pod -deleted file mode 100644 -index 6ba04ad0..00000000 ---- a/docs/virt-v2v-output-ovirt.pod -+++ /dev/null -@@ -1,231 +0,0 @@ --=head1 NAME -- --virt-v2v-output-ovirt - Using virt-v2v to convert guests to oVirt -- --=head1 SYNOPSIS -- -- virt-v2v [-i* options] -o ovirt-upload [-oc ENGINE_URL] -os STORAGE -- [-op PASSWORD] [-of raw] -- [-oo ovirt-cafile=FILE] -- [-oo ovirt-cluster=CLUSTER] -- [-oo ovirt-proxy] -- [-oo ovirt-disk-uuid=UUID ...] -- [-oo ovirt-verifypeer] -- -- virt-v2v [-i* options] -o ovirt -os [esd:/path|/path] -- -- virt-v2v [-i* options] -o vdsm -- [-oo vdsm-image-uuid=UUID] -- [-oo vdsm-vol-uuid=UUID] -- [-oo vdsm-vm-uuid=UUID] -- [-oo vdsm-ovf-output=DIR] -- --=head1 DESCRIPTION -- --This page documents how to use L to convert guests to an --oVirt management instance. There are three output modes that you can --select, but only I<-o ovirt-upload> should be used normally, the other --two are deprecated: -- --=over 4 -- --=item B<-o ovirt-upload> B<-os> STORAGE -- --Full description: L -- --This is the modern method for uploading to oVirt via the REST API. It --requires oVirt E 4.2. -- --=item B<-o ovirt> B<-os> esd:/path -- --=item B<-o ovirt> B<-os> /path -- --Full description: L -- --This is the old method for uploading to oVirt via the Export Storage --Domain (ESD). The ESD can either be accessed over NFS (using the --I<-os esd:/path> form) or if you have already NFS-mounted it somewhere --specify the path to the mountpoint as I<-os /path>. -- --The Export Storage Domain was deprecated in oVirt 4, and so we expect --that this method will stop working at some point in the future. -- --=item B<-o vdsm> -- --This is the old method used internally by the oVirt user interface. --It is never intended to be used directly by end users. -- --=back -- --=head1 OUTPUT TO OVIRT -- --This new method to upload guests to oVirt directly via the REST API --requires oVirt E 4.2. -- --You need to specify I<-o ovirt-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 ovirt-cafile=>F -- --The F file (Certificate Authority), copied from --F on the oVirt engine. -- --If I<-oo ovirt-verifypeer> is enabled then this option can --be used to control which CA is used to verify the client’s --identity. If this option is not used then the system’s --global trust store is used. -- --=item I<-oo ovirt-cluster=>C -- --Set the oVirt Cluster Name. If not given it uses C. -- --=item I<-oo ovirt-disk-uuid=>C -- --This option can used to manually specify UUIDs for the disks when --creating the virtual machine. If not specified, the oVirt engine will --generate random UUIDs for the disks. Please note that: -- --=over 4 -- --=item * -- --you B pass as many I<-oo ovirt-disk-uuid=UUID> options as the --amount of disks in the guest -- --=item * -- --the specified UUIDs must not conflict with the UUIDs of existing disks -- --=back -- --=item I<-oo ovirt-proxy> -- --Proxy the upload through oVirt Engine. This is slower than uploading --directly to the oVirt node but may be necessary if you do not have --direct network access to the nodes. -- --=item I<-oo ovirt-verifypeer> -- --Verify the oVirt server’s identity by checking the server‘s --certificate against the Certificate Authority. -- --=back -- --=head1 OUTPUT TO EXPORT STORAGE DOMAIN -- --This section only applies to the I<-o ovirt> output mode. If you use --virt-v2v from the oVirt user interface, then behind the scenes the --import is managed by VDSM using the I<-o vdsm> output mode (which end --users should not try to use directly). -- --You have to specify I<-o ovirt> and an I<-os> option that points to the --oVirt Export Storage Domain. You can either specify the NFS server --and mountpoint, eg. S>, or you can --mount that first and point to the directory where it is mounted, --eg. S>. Be careful not to point to the Data Storage --Domain by accident as that will not work. -- --On successful completion virt-v2v will have written the new guest to --the Export Storage Domain, but it will not yet be ready to run. It --must be imported into oVirt using the UI before it can be used. -- --In oVirt E 2.2 this is done from the Storage tab. Select the --export domain the guest was written to. A pane will appear underneath --the storage domain list displaying several tabs, one of which is "VM --Import". The converted guest will be listed here. Select the --appropriate guest an click "Import". See the oVirt documentation for --additional details. -- --If you export several guests, then you can import them all at the same --time through the UI. -- --=head2 Testing oVirt conversions -- --If you do not have an oVirt instance to test against, then you can --test conversions by creating a directory structure which looks enough --like a oVirt Export Storage Domain to trick virt-v2v: -- -- uuid=`uuidgen` -- mkdir /tmp/ovirt -- mkdir /tmp/ovirt/$uuid -- mkdir /tmp/ovirt/$uuid/images -- mkdir /tmp/ovirt/$uuid/master -- mkdir /tmp/ovirt/$uuid/master/vms -- touch /tmp/ovirt/$uuid/dom_md -- virt-v2v [...] -o ovirt -os /tmp/ovirt -- --=head2 Debugging oVirt import failures -- --When you export to the oVirt Export Storage Domain, and then import --that guest through the oVirt UI, you may encounter an import failure. --Diagnosing these failures is infuriatingly difficult as the UI --generally hides the true reason for the failure. -- --There are several log files of interest: -- --=over 4 -- --=item F -- --In oVirt E 4.1.0, VDSM preserves the virt-v2v log file for --30 days in this directory. -- --This directory is found on the host which performed the conversion. --The host can be selected in the import dialog, or can be found under --the C tab in oVirt administration. -- --=item F -- --As above, this file is present on the host which performed the --conversion. It contains detailed error messages from low-level --operations executed by VDSM, and is useful if the error was not caused --by virt-v2v, but by VDSM. -- --=item F -- --This log file is stored on the oVirt server. It contains more detail --for any errors caused by the oVirt GUI. -- --=back -- --=head1 SEE ALSO -- --L. -- --=head1 AUTHOR -- --Richard W.M. Jones -- --=head1 COPYRIGHT -- --Copyright (C) 2009-2025 Red Hat Inc. -diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod -index 0e68de10..b63da9f3 100644 ---- a/docs/virt-v2v.pod -+++ b/docs/virt-v2v.pod -@@ -14,9 +14,9 @@ virt-v2v - Convert a guest to use KVM - Virt-v2v converts a single guest from a foreign hypervisor to run on - KVM. It can read Linux and Windows guests running on VMware, - Hyper-V and some other hypervisors, and convert them to KVM managed by --libvirt, OpenStack, oVirt, or several other targets. It can modify --the guest to make it bootable on KVM and install virtio drivers so it --will run quickly. -+libvirt, OpenStack or several -+other targets. It can modify the guest to make it bootable on KVM and -+install virtio drivers so it will run quickly. - - There is also a companion front-end called L which comes - as an ISO, CD or PXE image that can be booted on physical machines to -@@ -61,8 +61,6 @@ L — Input from VMware. - - L — Output to local files or local libvirt. - --L — Output to oVirt -- - L — Output to OpenStack. - - L — Release notes for 1.42 release. -@@ -94,21 +92,6 @@ disks to F. - - For more information see L. - --=head2 Convert from VMware to oVirt -- --This is the same as the previous example, except you want to send the --guest to an oVirt Data Domain using the oVirt 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 ovirt-upload -oc https://ovirt-engine.example.com/ovirt-engine/api \ -- -os ovirt-data -op /tmp/ovirt-admin-password -of raw \ -- -oo ovirt-cafile=/tmp/ca.pem --bridge ovirtmgmt -- --In this case the host running virt-v2v acts as a B. -- --For more information see L. -- - =head2 Convert from ESXi hypervisor over SSH to local libvirt - - You have an ESXi hypervisor called C with SSH access -@@ -490,26 +473,6 @@ no metadata is written. - - Set the output method to OpenStack. See L. - --=item B<-o> B -- --Set the output method to I. -- --The converted guest is written to an oVirt Export Storage Domain. The --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 oVirt. You have to do that manually later using the UI. -- --See L. -- --=item B<-o> B -- --Set the output method to I. -- --The converted guest is written directly to an oVirt Data Domain. This --is a faster method than I<-o ovirt>, but requires oVirt E 4.2. -- --See L. -- - =item B<-o> B - - Set the output method to I. -@@ -518,15 +481,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>. - --=item B<-o> B -- --Set the output method to I. -- --This mode is similar to I<-o ovirt>, but the full path to the --data domain must be given: --Fdata-center-uuidE/Edata-domain-uuidE>. --This mode is only used when virt-v2v runs under VDSM control. -- - =item B<-oa> B - - =item B<-oa> B -@@ -594,117 +548,11 @@ For I<-o openstack> (L) only, set optional - OpenStack authentication. For example I<-oo os-username=>NAME is - equivalent to C. - --=item B<-oo ovirt-cafile=>F -- --For I<-o ovirt-upload> (L) only, the --F file (Certificate Authority), copied from --F on the oVirt engine. -- --=item B<-oo ovirt-cluster=>C -- --For I<-o ovirt-upload> (L) only, set the --oVirt Cluster Name. If not given it uses C. -- --=item B<-oo ovirt-proxy> -- --For I<-o ovirt-upload> (L) only, proxy the --upload through oVirt Engine. This is slower than uploading directly --to the oVirt node but may be necessary if you do not have direct --network access to the nodes. -- --=item B<-oo ovirt-verifypeer> -- --For I<-o ovirt-upload> (L) only, verify the --oVirt server’s identity by checking the server‘s certificate against --the Certificate Authority. -- - =item B<-oo server-id=>C - - For I<-o openstack> (L) only, set the name - of the conversion appliance where virt-v2v is running. - --=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 ovirt>) 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 oVirt 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 ovirtexp -- --The OVF format used in oVirt 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<-oo verify-server-certificate> - - =item B<-oo verify-server-certificate=>C -@@ -730,28 +578,6 @@ 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 ovirt-upload>, this is the name of the destination Storage --Domain. -- --For I<-o openstack>, this is the optional Cinder volume type. -- --For I<-o ovirt>, this can be an NFS path of the Export Storage Domain --of the form ChostE:EpathE>, eg: -- -- ovirt-storage.example.com:/ovirt/export -- --The NFS export must be mountable and writable by the user and host --running virt-v2v, since the virt-v2v program has to actually mount it --when it runs. So you probably have to run virt-v2v as C. -- --B You can mount the Export Storage Domain yourself, and point --I<-os> to the mountpoint. Note that virt-v2v will still need to write --to this remote directory, so virt-v2v will still need to run as --C. -- --You will get an error if virt-v2v is unable to mount/write to the --Export Storage Domain. -- - =item B<--parallel> N - - Enable parallel copying if the guest has multiple disks. I is the -@@ -991,26 +817,6 @@ require either root or a special user: - - =over 4 - --=item Mounting the Export Storage Domain -- --When using I<-o ovirt -os server:/esd> virt-v2v has to have sufficient --privileges to NFS mount the Export Storage Domain from C. -- --You can avoid needing root here by mounting it yourself before running --virt-v2v, and passing I<-os /mountpoint> instead, but first of all --read the next S
-- --=item Writing to the Export Storage Domain as 36:36 -- --oVirt cannot read files and directories from the Export Storage --Domain unless they have UID:GID 36:36. You will see VM import --problems if the UID:GID is not correct. -- --When you run virt-v2v I<-o ovirt> as root, virt-v2v attempts to create --files and directories with the correct ownership. If you run virt-v2v --as non-root, it will probably still work, but you will need to --manually change ownership after virt-v2v has finished. -- - =item Writing to libvirt - - When using I<-o libvirt>, you may need to run virt-v2v as root so that -@@ -1557,7 +1363,6 @@ virt-v2v binary. Typical output looks like this: - virt-v2v - libguestfs-rewrite - colours-option -- vdsm-compat-option - input:disk - [...] - output:local -diff --git a/output/Makefile.am b/output/Makefile.am -index 9e1ceabf..c2ee1b3b 100644 ---- a/output/Makefile.am -+++ b/output/Makefile.am -@@ -17,14 +17,7 @@ - - include $(top_srcdir)/subdir-rules.mk - --BUILT_SOURCES = \ -- output_ovirt_upload_cancel_source.ml \ -- output_ovirt_upload_createvm_source.ml \ -- output_ovirt_upload_finalize_source.ml \ -- output_ovirt_upload_plugin_source.ml \ -- output_ovirt_upload_precheck_source.ml \ -- output_ovirt_upload_transfer_source.ml \ -- output_ovirt_upload_vmcheck_source.ml -+BUILT_SOURCES = - - EXTRA_DIST = \ - $(SOURCES_MLI) \ -@@ -32,13 +25,6 @@ EXTRA_DIST = \ - $(SOURCES_C) \ - $(BUILT_SOURCES) \ - embed.sh \ -- ovirt-upload-cancel.py \ -- ovirt-upload-createvm.py \ -- ovirt-upload-finalize.py \ -- ovirt-upload-plugin.py \ -- ovirt-upload-precheck.py \ -- ovirt-upload-transfer.py \ -- ovirt-upload-vmcheck.py \ - test-python-syntax.sh - - SOURCES_MLI = \ -@@ -63,7 +49,6 @@ SOURCES_MLI = \ - output_ovirt_upload_transfer_source.mli \ - output_ovirt_upload_vmcheck_source.mli \ - output_qemu.mli \ -- output_vdsm.mli \ - python_script.mli \ - qemuopts.mli \ - select_output.mli -@@ -75,13 +60,6 @@ SOURCES_ML = \ - create_kubevirt_yaml.ml \ - qemuopts.ml \ - openstack_image_properties.ml \ -- output_ovirt_upload_cancel_source.ml \ -- output_ovirt_upload_createvm_source.ml \ -- output_ovirt_upload_finalize_source.ml \ -- output_ovirt_upload_plugin_source.ml \ -- output_ovirt_upload_precheck_source.ml \ -- output_ovirt_upload_transfer_source.ml \ -- output_ovirt_upload_vmcheck_source.ml \ - output.ml \ - output_disk.ml \ - output_glance.ml \ -@@ -90,30 +68,11 @@ SOURCES_ML = \ - output_null.ml \ - output_openstack.ml \ - output_qemu.ml \ -- output_ovirt.ml \ -- output_ovirt_upload.ml \ -- output_vdsm.ml \ - select_output.ml - - SOURCES_C = \ - qemuopts-c.c - --# These files are generated and contain *.py embedded as an OCaml string. --output_ovirt_upload_cancel_source.ml: $(srcdir)/ovirt-upload-cancel.py -- $(srcdir)/embed.sh code $^ $@ --output_ovirt_upload_createvm_source.ml: $(srcdir)/ovirt-upload-createvm.py -- $(srcdir)/embed.sh code $^ $@ --output_ovirt_upload_finalize_source.ml: $(srcdir)/ovirt-upload-finalize.py -- $(srcdir)/embed.sh code $^ $@ --output_ovirt_upload_plugin_source.ml: $(srcdir)/ovirt-upload-plugin.py -- $(srcdir)/embed.sh code $^ $@ --output_ovirt_upload_precheck_source.ml: $(srcdir)/ovirt-upload-precheck.py -- $(srcdir)/embed.sh code $^ $@ --output_ovirt_upload_transfer_source.ml: $(srcdir)/ovirt-upload-transfer.py -- $(srcdir)/embed.sh code $^ $@ --output_ovirt_upload_vmcheck_source.ml: $(srcdir)/ovirt-upload-vmcheck.py -- $(srcdir)/embed.sh code $^ $@ -- - # We pretend that we're building a C library. automake handles the - # compilation of the C sources for us. At the end we take the C - # objects and OCaml objects and link them into the OCaml library. -diff --git a/output/output_ovirt.ml b/output/output_ovirt.ml -deleted file mode 100644 -index 0f0f4c36..00000000 ---- a/output/output_ovirt.ml -+++ /dev/null -@@ -1,319 +0,0 @@ --(* virt-v2v -- * Copyright (C) 2009-2025 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 -- --open Output -- --module OVirt = struct -- type poptions = Types.output_allocation * string * string * string -- -- type t = string * string * string * string list * string list * int64 list -- -- let to_string options = "-o ovirt" -- -- let query_output_options () = -- printf (f_"No output options can be used in this mode.\n") -- -- let parse_options options source = -- if options.output_options <> [] then -- error (f_"no -oo (output options) are allowed here"); -- if options.output_password <> None then -- error_option_cannot_be_used_in_output_mode "ovirt" "-op"; -- -- (* -os must be set, but at this point we cannot check it. *) -- let output_storage = -- match options.output_storage with -- | None -> error (f_"-o ovirt: -os option was not specified") -- | Some d -> d in -- -- let output_name = Option.value ~default:source.s_name options.output_name in -- -- (options.output_alloc, options.output_format, output_name, output_storage) -- -- let rec setup dir options source input_disks = -- error_if_disk_count_gt input_disks 23; -- let input_sizes = get_disk_sizes input_disks in -- let output_alloc, output_format, output_name, output_storage = options in -- -- (* UID:GID required for files and directories when writing to ESD. *) -- let uid = 36 and gid = 36 in -- -- (* Create a UID-switching handle. If we're not root, create a dummy -- * one because we cannot switch UIDs. -- *) -- let running_as_root = geteuid () = 0 in -- let changeuid_t = -- if running_as_root then -- Changeuid.create ~uid ~gid () -- else -- Changeuid.create () in -- -- let esd_mp, esd_uuid = -- mount_and_check_storage_domain (s_"Export Storage Domain") -- output_storage in -- debug "ovirt: ESD mountpoint: %s\novirt: ESD UUID: %s" esd_mp esd_uuid; -- -- (* See if we can write files as UID:GID 36:36. *) -- let () = -- let testfile = esd_mp // esd_uuid // String.random8 () in -- Changeuid.make_file changeuid_t testfile ""; -- let stat = stat testfile in -- Changeuid.unlink changeuid_t testfile; -- let actual_uid = stat.st_uid and actual_gid = stat.st_gid in -- debug "ovirt: actual UID:GID of new files is %d:%d" actual_uid actual_gid; -- if uid <> actual_uid || gid <> actual_gid then ( -- if running_as_root then -- warning (f_"cannot write files to the NFS server as %d:%d, \ -- even though we appear to be running as root. This \ -- probably means the NFS client or idmapd is not \ -- configured properly.\n\nYou will have to chown \ -- the files that virt-v2v creates after the run, \ -- otherwise oVirt will not be able to import the VM.") -- uid gid -- else -- warning (f_"cannot write files to the NFS server as %d:%d. \ -- You might want to stop virt-v2v (^C) and rerun it \ -- as root.") uid gid -- ) in -- -- (* Create unique UUIDs for everything *) -- let vm_uuid = uuidgen () in -- (* Generate random image and volume UUIDs for each target disk. *) -- let image_uuids = List.map (fun _ -> uuidgen ()) input_disks in -- let vol_uuids = List.map (fun _ -> uuidgen ()) input_disks in -- -- (* We need to create the target image director(ies) so there's a place -- * for the main program to copy the images to. However if image -- * conversion fails for any reason then we delete this directory. -- *) -- let images_dir = esd_mp // esd_uuid // "images" in -- List.iter ( -- fun image_uuid -> -- let d = images_dir // image_uuid in -- Changeuid.mkdir changeuid_t d 0o755 -- ) image_uuids; -- On_exit.f ( -- fun () -> -- (* virt-v2v writes v2vdir/done on success only. *) -- let success = Sys.file_exists (dir // "done") in -- if not success then ( -- List.iter ( -- fun image_uuid -> -- let d = images_dir // image_uuid in -- let cmd = sprintf "rm -rf %s" (quote d) in -- Changeuid.command changeuid_t cmd -- ) image_uuids -- ) -- ); -- -- (* The final directory structure should look like this: -- * ///images/ -- * / # first disk -- * /.meta # first disk -- * / # second disk -- * /.meta # second disk -- * / # etc -- * /.meta # -- *) -- -- (* Generate the randomly named target files (just the names). -- * The main code is what generates the files themselves. -- *) -- let filenames = -- List.map ( -- fun (image_uuid, vol_uuid) -> -- let filename = images_dir // image_uuid // vol_uuid in -- debug "ovirt: disk: %s" filename; -- filename -- ) (List.combine image_uuids vol_uuids) in -- -- (* Generate the .meta file associated with each volume. *) -- let metas = -- Create_ovf.create_meta_files output_alloc output_format -- esd_uuid image_uuids input_sizes in -- List.iter ( -- fun (filename, meta) -> -- let meta_filename = filename ^ ".meta" in -- Changeuid.make_file changeuid_t meta_filename meta -- ) (List.combine filenames metas); -- -- (* Set up the NBD servers. *) -- let uris = -- List.mapi ( -- fun i (size, filename) -> -- let socket = sprintf "%s/out%d" dir i in -- On_exit.unlink socket; -- -- (* Create the actual output disk. *) -- let changeuid f = -- Changeuid.func changeuid_t ( -- fun () -> -- (* Run the command to create the file. *) -- f (); -- (* Make the file sufficiently writable so that possibly root, -- * or root squashed nbdkit will definitely be able to open it. -- * An example of how root squashing nonsense makes everyone -- * less secure. -- *) -- chmod filename 0o666 -- ) -- in -- -- (* We have to wait for the NBD server to exit rather than just -- * killing it, otherwise it races with unmounting. See: -- * https://bugzilla.redhat.com/show_bug.cgi?id=1953286#c26 -- *) -- let on_exit_kill = Output.KillAndWait in -- -- output_to_local_file ~changeuid ~on_exit_kill -- output_alloc output_format filename size socket; -- -- NBD_URI.Unix (socket, None) -- ) (List.combine input_sizes filenames) in -- -- (* Save parameters since we need them during finalization. *) -- let t = esd_mp, esd_uuid, vm_uuid, image_uuids, vol_uuids, input_sizes in -- t, uris -- -- and mount_and_check_storage_domain domain_class os = -- (* The user can either specify -os nfs:/export, or a local directory -- * which is assumed to be the already-mounted NFS export. -- *) -- match String.split ":/" os with -- | mp, "" -> (* Already mounted directory. *) -- check_storage_domain domain_class os mp -- | server, export -> -- let export = "/" ^ export in -- -- (* Create a mountpoint. Default mode is too restrictive for us -- * when we need to write into the directory as 36:36. -- *) -- let mp = Mkdtemp.temp_dir "v2v." in -- chmod mp 0o755; -- -- (* Try mounting it. *) -- let cmd = [ "mount"; sprintf "%s:%s" server export; mp ] in -- if run_command cmd <> 0 then -- error (f_"mount command failed, see earlier errors.\n\nThis probably \ -- means you didn't specify the right %s path [-os %s], or \ -- else you need to rerun virt-v2v as root.") domain_class os; -- -- (* Make sure it is unmounted at exit, as late as possible (prio=9999) *) -- On_exit.f ~prio:9999 ( -- fun () -> -- let cmd = [ "umount"; mp ] in -- ignore (run_command cmd); -- try rmdir mp with _ -> () -- ); -- -- check_storage_domain domain_class os mp -- -- and check_storage_domain domain_class os mp = -- (* Typical SD mountpoint looks like this: -- * $ ls /tmp/mnt -- * 39b6af0e-1d64-40c2-97e4-4f094f1919c7 __DIRECT_IO_TEST__ lost+found -- * $ ls /tmp/mnt/39b6af0e-1d64-40c2-97e4-4f094f1919c7 -- * dom_md images master -- * We expect exactly one of those magic UUIDs. -- *) -- let entries = -- try Sys.readdir mp -- with Sys_error msg -> -- error (f_"could not read the %s specified by the '-os %s' \ -- parameter on the command line. Is it really an \ -- OVirt %s? The original error is: %s") -- domain_class os domain_class msg in -- let entries = Array.to_list entries in -- let uuids = List.filter ( -- fun entry -> -- String.length entry = 36 && -- entry.[8] = '-' && entry.[13] = '-' && entry.[18] = '-' && -- entry.[23] = '-' -- ) entries in -- let uuid = -- match uuids with -- | [uuid] -> uuid -- | [] -> -- error (f_"there are no UUIDs in the %s (%s). Is it really an \ -- OVirt %s?") domain_class os domain_class -- | _::_ -> -- error (f_"there are multiple UUIDs in the %s (%s). This is \ -- unexpected, and may be a bug in virt-v2v or OVirt.") -- domain_class os in -- -- (* Check that the domain has been attached to a Data Center by -- * checking that the master/vms directory exists. -- *) -- let () = -- let master_vms_dir = mp // uuid // "master" // "vms" in -- if not (is_directory master_vms_dir) then -- error (f_"%s does not exist or is not a directory.\n\nMost likely \ -- cause: Either the %s (%s) has not been attached to any \ -- Data Center, or the path %s is not an %s at all.\n\n\ -- You have to attach the %s to a Data Center using the \ -- oVirt user interface first.\n\nIf you don’t \ -- know what the %s mount point should be then you can \ -- also find this out through the oVirt user interface.") -- master_vms_dir domain_class os os -- domain_class domain_class domain_class in -- -- (* Looks good, so return the SD mountpoint and UUID. *) -- (mp, uuid) -- -- let finalize dir options t output_disks source inspect target_meta = -- let output_alloc, output_format, output_name, output_storage = options in -- let esd_mp, esd_uuid, vm_uuid, image_uuids, vol_uuids, sizes = t in -- -- (* UID:GID required for files and directories when writing to ESD. *) -- let uid = 36 and gid = 36 in -- -- (* Create a UID-switching handle. If we're not root, create a dummy -- * one because we cannot switch UIDs. -- *) -- let running_as_root = geteuid () = 0 in -- let changeuid_t = -- if running_as_root then -- Changeuid.create ~uid ~gid () -- else -- Changeuid.create () in -- -- (* Create the metadata. *) -- let ovf = -- Create_ovf.create_ovf source inspect target_meta sizes -- output_alloc output_format output_name esd_uuid image_uuids vol_uuids -- ~need_actual_sizes:true output_disks vm_uuid -- Create_ovf.OVirtExportStorageDomain in -- -- (* Write it to the metadata file. *) -- let dir = esd_mp // esd_uuid // "master" // "vms" // vm_uuid in -- Changeuid.mkdir changeuid_t dir 0o755; -- let file = dir // vm_uuid ^ ".ovf" in -- Changeuid.output changeuid_t file (fun chan -> DOM.doc_to_chan chan ovf) -- -- let request_size = None --end -diff --git a/output/output_ovirt.mli b/output/output_ovirt.mli -deleted file mode 100644 -index 29e66059..00000000 ---- a/output/output_ovirt.mli -+++ /dev/null -@@ -1,21 +0,0 @@ --(* virt-v2v -- * Copyright (C) 2009-2025 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 ovirt] output mode. *) -- --module OVirt : Output.OUTPUT -diff --git a/output/output_ovirt_upload.ml b/output/output_ovirt_upload.ml -deleted file mode 100644 -index e7577edb..00000000 ---- a/output/output_ovirt_upload.ml -+++ /dev/null -@@ -1,514 +0,0 @@ --(* virt-v2v -- * Copyright (C) 2009-2025 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 Common_gettext.Gettext -- --open Types --open Utils -- --open Output -- --module OVirtUpload = struct -- type poptions = string * string * string * string * string * -- string option * string option * bool * bool * -- string list option -- -- type t = int64 list * string list * string list * -- Python_script.script * Python_script.script * -- JSON.field list * string option * string option * -- string option * string * int list ref -- -- let to_string options = -- "-o ovirt-upload" ^ -- (match options.output_conn with -- | Some oc -> " -oc " ^ oc -- | None -> "") ^ -- (match options.output_storage with -- | Some os -> " -os " ^ os -- | None -> "") -- -- let query_output_options () = -- printf (f_"Output options (-oo) which can be used with -o ovirt-upload: -- -- -oo ovirt-cafile=CA.PEM Set ‘ca.pem’ certificate bundle filename. -- -oo ovirt-cluster=CLUSTERNAME Set oVirt cluster name. -- -oo ovirt-proxy Connect via oVirt Engine proxy (default: false). -- -oo ovirt-verifypeer[=true|false] Verify server identity (default: false). -- --You can override the UUIDs of the disks, instead of using autogenerated UUIDs --after their uploads (if you do, you must supply one for each disk): -- -- -oo ovirt-disk-uuid=UUID Disk UUID --") -- -- let rec parse_options options source = -- let output_conn = -- match options.output_conn with -- | None -> -- error (f_"-o ovirt-upload: use ‘-oc’ to point to the oVirt \ -- server REST API URL, which is usually \ -- https://servername/ovirt-engine/api") -- | Some oc -> oc in -- (* In theory we could make the password optional in future. *) -- let output_password = -- match options.output_password with -- | None -> -- error (f_"-o ovirt-upload: output password file was not specified, \ -- use ‘-op’ to point to a file which contains the password \ -- used to connect to the oVirt server") -- | Some op -> op in -- let output_storage = -- match options.output_storage with -- | None -> -- error (f_"-o ovirt-upload: output storage was not specified, \ -- use ‘-os’"); -- | Some os -> os in -- -- let ovirt_cafile = ref None in -- let ovirt_cluster = ref None in -- let ovirt_direct = ref true in -- let ovirt_verifypeer = ref false in -- let ovirt_disk_uuids = ref None in -- -- List.iter ( -- function -- | ("ovirt-cafile"|"rhv-cafile"), v -> -- if !ovirt_cafile <> None then -- error (f_"-o ovirt-upload: -oo ovirt-cafile set more than once"); -- ovirt_cafile := Some v -- | ("ovirt-cluster"|"rhv-cluster"), v -> -- if !ovirt_cluster <> None then -- error (f_"-o ovirt-upload: -oo ovirt-cluster set more than once"); -- ovirt_cluster := Some v -- | ("ovirt-direct"|"rhv-direct"), "" -> ovirt_direct := true -- | ("ovirt-direct"|"rhv-direct"), v -> ovirt_direct := bool_of_string v -- | ("ovirt-proxy"|"rhv-proxy"), "" -> ovirt_direct := false -- | ("ovirt-proxy"|"rhv-proxy"), v -> ovirt_direct := not (bool_of_string v) -- | ("ovirt-verifypeer"|"rhv-verifypeer"), "" -> ovirt_verifypeer := true -- | ("ovirt-verifypeer"|"rhv-verifypeer"), v -> -- ovirt_verifypeer := bool_of_string v -- | ("ovirt-disk-uuid"|"rhv-disk-uuid"), v -> -- if not (is_nonnil_uuid v) then -- error (f_"-o ovirt-upload: invalid UUID for -oo ovirt-disk-uuid"); -- ovirt_disk_uuids := -- Some (v :: (Option.value ~default:[] !ovirt_disk_uuids)) -- | k, _ -> -- error (f_"-o ovirt-upload: unknown output option ‘-oo %s’") k -- ) options.output_options; -- -- let ovirt_cafile = !ovirt_cafile in -- let ovirt_cluster = !ovirt_cluster in -- let ovirt_direct = !ovirt_direct in -- let ovirt_verifypeer = !ovirt_verifypeer in -- let ovirt_disk_uuids = Option.map List.rev !ovirt_disk_uuids in -- -- let output_name = Option.value ~default:source.s_name options.output_name in -- -- (output_conn, options.output_format, -- output_password, output_name, output_storage, -- ovirt_cafile, ovirt_cluster, ovirt_direct, -- ovirt_verifypeer, ovirt_disk_uuids) -- -- and is_nonnil_uuid uuid = -- let nil_uuid = "00000000-0000-0000-0000-000000000000" in -- let rex_uuid = lazy ( -- let hex = "[a-fA-F0-9]" in -- let str = sprintf "^%s{8}-%s{4}-%s{4}-%s{4}-%s{12}$" -- hex hex hex hex hex in -- PCRE.compile str -- ) in -- if uuid = nil_uuid then false -- else PCRE.matches (Lazy.force rex_uuid) uuid -- -- let rec setup dir options source input_disks = -- error_if_disk_count_gt input_disks 23; -- let input_sizes = get_disk_sizes input_disks in -- let output_conn, output_format, -- output_password, output_name, output_storage, -- ovirt_cafile, ovirt_cluster, ovirt_direct, -- ovirt_verifypeer, ovirt_disk_uuids = options in -- -- (* Check that the 'ovirtsdk4' Python module is available. *) -- let error_unless_ovirtsdk4_module_available () = -- let res = run_command [ Python_script.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 -- -- (* Check that nbdkit is available and new enough. *) -- let error_unless_nbdkit_working () = -- if not (Nbdkit.is_installed ()) then -- error (f_"nbdkit is not installed or not working. It is required \ -- to use ‘-o ovirt-upload’. See the virt-v2v-output-ovirt(1) \ -- manual.") -- in -- -- (* Check that the python3 plugin is installed and working -- * and can load the plugin script. -- *) -- let error_unless_nbdkit_python_plugin_working plugin_script = -- let cmd = sprintf "nbdkit python %s --dump-plugin >/dev/null" -- (quote (Python_script.path plugin_script)) in -- debug "%s" cmd; -- if Sys.command cmd <> 0 then -- error (f_"nbdkit python plugin is not installed or not working. \ -- It is required if you want to use ‘-o ovirt-upload’. -- --See also the virt-v2v-output-ovirt(1) manual."); -- in -- -- (* Check that nbdkit was compiled with SELinux support (for the -- * --selinux-label option). -- *) -- let error_unless_nbdkit_compiled_with_selinux () = -- if have_selinux then ( -- let config = Nbdkit.config () in -- let selinux = try List.assoc "selinux" config with Not_found -> "no" in -- if selinux = "no" 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 -- -- Python_script.error_unless_python_interpreter_found (); -- error_unless_ovirtsdk4_module_available (); -- error_unless_nbdkit_working (); -- error_unless_nbdkit_compiled_with_selinux (); -- -- (* Python code. *) -- let precheck_script = -- Python_script.create ~name:"ovirt-upload-precheck.py" -- Output_ovirt_upload_precheck_source.code in -- let vmcheck_script = -- Python_script.create ~name:"ovirt-upload-vmcheck.py" -- Output_ovirt_upload_vmcheck_source.code in -- let plugin_script = -- Python_script.create ~name:"ovirt-upload-plugin.py" -- Output_ovirt_upload_plugin_source.code in -- let transfer_script = -- Python_script.create ~name:"ovirt-upload-transfer.py" -- Output_ovirt_upload_transfer_source.code in -- let finalize_script = -- Python_script.create ~name:"ovirt-upload-finalize.py" -- Output_ovirt_upload_finalize_source.code in -- let cancel_script = -- Python_script.create ~name:"ovirt-upload-cancel.py" -- Output_ovirt_upload_cancel_source.code in -- let createvm_script = -- Python_script.create ~name:"ovirt-upload-createvm.py" -- Output_ovirt_upload_createvm_source.code in -- -- error_unless_nbdkit_python_plugin_working plugin_script; -- -- (* 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; -- "ovirt_cafile", json_optstring ovirt_cafile; -- "ovirt_cluster", -- JSON.String (Option.value ~default:"Default" ovirt_cluster); -- "ovirt_direct", JSON.Bool ovirt_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 ovirt_verifypeer); -- ] in -- -- (* nbdkit command line which is invariant between disks. *) -- let cmd = Nbdkit.create "python" in -- Nbdkit.add_arg cmd "script" (Python_script.path plugin_script); -- -- (* Match number of parallel coroutines in qemu-img *) -- Nbdkit.set_threads cmd 8; -- -- (* Python code prechecks. *) -- let json_params = match ovirt_disk_uuids with -- | None -> json_params -- | Some uuids -> -- let ids = List.map (fun uuid -> JSON.String uuid) uuids in -- ("ovirt_disk_uuids", JSON.List ids) :: json_params -- in -- let precheck_json = dir // "v2vprecheck.json" in -- let fd = Unix.openfile precheck_json [O_WRONLY; O_CREAT; O_TRUNC] 0o600 in -- if Python_script.run_command ~stdout_fd:fd -- precheck_script json_params [] <> 0 then -- error (f_"failed server prechecks, see earlier errors"); -- if verbose () then -- debug "precheck output before parsing: %s" -- (read_whole_file precheck_json); -- let json = JSON_parser.json_parser_tree_parse_file precheck_json in -- debug "precheck output parsed as: %s" -- (JSON.string_of_doc ~fmt:JSON.Indented ["", json]); -- let ovirt_storagedomain_uuid = -- Some (JSON_parser.object_get_string "ovirt_storagedomain_uuid" json) in -- let ovirt_cluster_uuid = -- Some (JSON_parser.object_get_string "ovirt_cluster_uuid" json) in -- let ovirt_cluster_cpu_architecture = -- Some (JSON_parser.object_get_string "ovirt_cluster_cpu_architecture" json) in -- -- (* If the disk UUIDs were not provided, then generate them. -- * This is simpler than letting oVirt generate them and trying -- * to read them back from oVirt. -- *) -- let disk_uuids = -- match ovirt_disk_uuids with -- | Some uuids -> -- let nr_disks = List.length input_disks in -- if List.length uuids <> nr_disks then -- error (f_"the number of ‘-oo ovirt-disk-uuid’ parameters passed on \ -- the command line has to match the number of guest \ -- disk images (for this guest: %d)") nr_disks; -- uuids -- | None -> List.map (fun _ -> uuidgen ()) input_disks in -- -- (* This will accumulate the list of transfer IDs from the transfer -- * script. -- *) -- let transfer_ids = ref [] in -- -- let ovirt_cluster_name = -- match List.assoc "ovirt_cluster" json_params with -- | JSON.String s -> s -- | _ -> assert false in -- -- let json_params = -- ("output_name", JSON.String output_name) :: json_params in -- -- (* Check that the VM does not exist. This can't run in #precheck because -- * we need to know the name of the virtual machine. -- *) -- if Python_script.run_command vmcheck_script json_params [] <> 0 then -- error (f_"failed vmchecks, see earlier errors"); -- -- (* Cancel the transfer and delete disks. -- * -- * This ignores errors since the only time we are doing this is on -- * the failure path. -- *) -- let cancel transfer_ids disk_uuids = -- let ids = List.map (fun id -> JSON.String id) transfer_ids in -- let json_params = ("transfer_ids", JSON.List ids) :: json_params in -- let ids = List.map (fun uuid -> JSON.String uuid) disk_uuids in -- let json_params = ("disk_uuids", JSON.List ids) :: json_params in -- ignore (Python_script.run_command cancel_script json_params []) -- in -- -- (* Set up an at-exit handler to perform some cleanups. -- * - Kill nbdkit PIDs (only before finalization). -- * - Delete the orphan disks (only on conversion failure). -- *) -- let nbdkit_pids = ref [] in -- On_exit.f ( -- fun () -> -- (* Kill the nbdkit PIDs. *) -- List.iter ( -- fun pid -> -- try kill pid Sys.sigterm -- with exn -> debug "%s" (Printexc.to_string exn) -- ) !nbdkit_pids; -- nbdkit_pids := []; -- -- (* virt-v2v writes v2vdir/done on success only. *) -- let success = Sys.file_exists (dir // "done") in -- if not success then ( -- if disk_uuids <> [] then -- cancel !transfer_ids disk_uuids -- ) -- ); -- -- (* Create an nbdkit instance for each disk and set the -- * target URI to point to the NBD socket. -- *) -- let uris = -- List.mapi ( -- fun i (size, uuid) -> -- let socket = sprintf "%s/out%d" dir i in -- On_exit.unlink socket; -- -- let disk_name = sprintf "%s-%03d" output_name i in -- let json_params = -- ("disk_name", JSON.String disk_name) :: json_params in -- -- let disk_format = -- match output_format with -- | "raw" as fmt -> fmt -- | "qcow2" as fmt -> fmt -- | _ -> -- error (f_"ovirt-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.") -- output_format in -- let json_params = -- ("disk_format", JSON.String disk_format) :: json_params in -- -- let json_params = -- ("disk_size", JSON.Int size) :: json_params in -- -- let json_params = -- ("disk_uuid", JSON.String uuid) :: json_params in -- -- (* Write the JSON parameters to a file. *) -- let json_param_file = dir // sprintf "out.params%d.json" i in -- with_open_out -- json_param_file -- (fun chan -> output_string chan (JSON.string_of_doc json_params)); -- -- (* Start the transfer. *) -- let transfer_json = dir // sprintf "v2vtransfer%d.json" i in -- let fd = -- Unix.openfile transfer_json [O_WRONLY; O_CREAT; O_TRUNC] 0o600 in -- if Python_script.run_command ~stdout_fd:fd -- transfer_script json_params [] <> 0 then -- error (f_"failed to start transfer, see earlier errors"); -- if verbose () then -- debug "transfer output before parsing: %s" -- (read_whole_file transfer_json); -- let json = JSON_parser.json_parser_tree_parse_file transfer_json in -- debug "transfer output parsed as: %s" -- (JSON.string_of_doc ~fmt:JSON.Indented ["", json]); -- let destination_url = -- JSON_parser.object_get_string "destination_url" json in -- let transfer_id = -- JSON_parser.object_get_string "transfer_id" json in -- List.push_back transfer_ids transfer_id; -- let is_ovirt_host = -- JSON_parser.object_get_bool "is_ovirt_host" json in -- -- (* Create the nbdkit instance. *) -- Nbdkit.add_arg cmd "size" (Int64.to_string size); -- Nbdkit.add_arg cmd "url" destination_url; -- Option.iter (Nbdkit.add_arg cmd "cafile") ovirt_cafile; -- if not ovirt_verifypeer then -- Nbdkit.add_arg cmd "insecure" "true"; -- if is_ovirt_host then -- Nbdkit.add_arg cmd "is_ovirt_host" "true"; -- let _, pid = Nbdkit.run_unix socket cmd in -- List.push_front pid nbdkit_pids; -- -- NBD_URI.Unix (socket, None) -- ) (List.combine input_sizes disk_uuids) in -- -- (* Stash some data we will need during finalization. *) -- let t = (input_sizes : int64 list), disk_uuids, !transfer_ids, -- finalize_script, createvm_script, json_params, -- ovirt_storagedomain_uuid, ovirt_cluster_uuid, -- ovirt_cluster_cpu_architecture, ovirt_cluster_name, nbdkit_pids in -- -- t, uris -- -- and json_optstring = function -- | Some s -> JSON.String s -- | None -> JSON.Null -- -- let finalize dir options t output_disks source inspect target_meta = -- let output_conn, output_format, -- output_password, output_name, output_storage, -- ovirt_cafile, ovirt_cluster, ovirt_direct, -- ovirt_verifypeer, ovirt_disk_uuids = options in -- let input_sizes, disk_uuids, transfer_ids, -- finalize_script, createvm_script, json_params, -- ovirt_storagedomain_uuid, ovirt_cluster_uuid, -- ovirt_cluster_cpu_architecture, ovirt_cluster_name, -- nbdkit_pids = t in -- -- (* Check the cluster CPU arch matches what we derived about the -- * guest during conversion. -- *) -- (match ovirt_cluster_cpu_architecture with -- | None -> assert false -- | Some arch -> -- if arch <> target_meta.guestcaps.gcaps_arch then -- error (f_"the cluster ‘%s’ does not support the architecture %s \ -- but %s") -- ovirt_cluster_name target_meta.guestcaps.gcaps_arch arch -- ); -- -- (* We must kill all our nbdkit instances before finalizing the -- * transfer. See: -- * https://listman.redhat.com/archives/libguestfs/2022-February/msg00111.html -- * -- * We want to fail here if the kill fails because nbdkit -- * died already, as that would be unexpected. -- *) -- let () = -- let pids = !nbdkit_pids in -- List.iter (fun pid -> kill pid Sys.sigterm) pids; -- List.iter (fun pid -> ignore (waitpid [] pid)) pids; -- nbdkit_pids := [] (* Don't kill them again in the On_exit handler. *) in -- -- (* Finalize all the transfers. *) -- let json_params = -- let ids = List.map (fun id -> JSON.String id) transfer_ids in -- let json_params = ("transfer_ids", JSON.List ids) :: json_params in -- let ids = List.map (fun uuid -> JSON.String uuid) disk_uuids in -- let json_params = ("disk_uuids", JSON.List ids) :: json_params in -- json_params in -- if Python_script.run_command finalize_script json_params [] <> 0 then -- error (f_"failed to finalize the transfers, see earlier errors"); -- -- (* The storage domain UUID. *) -- let sd_uuid = -- match ovirt_storagedomain_uuid with -- | None -> assert false -- | Some uuid -> uuid in -- -- (* The volume and VM UUIDs are made up. *) -- let vol_uuids = List.map (fun _ -> uuidgen ()) input_sizes -- and vm_uuid = uuidgen () in -- -- (* Create the metadata. *) -- let ovf = -- Create_ovf.create_ovf source inspect target_meta input_sizes -- Sparse output_format output_name -- sd_uuid disk_uuids vol_uuids output_disks vm_uuid OVirt in -- let ovf = DOM.doc_to_string ovf in -- -- let json_params = -- match ovirt_cluster_uuid with -- | None -> assert false -- | Some uuid -> ("ovirt_cluster_uuid", JSON.String uuid) :: json_params in -- -- let ovf_file = dir // "vm.ovf" in -- with_open_out ovf_file (fun chan -> output_string chan ovf); -- if Python_script.run_command createvm_script json_params [ovf_file] <> 0 -- then -- error (f_"failed to create virtual machine, see earlier errors") -- -- (* The imageio server has high overhead per request. Using 4 MiB -- * request size is 1.8x times faster compared with nbdcopy default -- * request size (256k). -- *) -- let request_size = Some (4*1024*1024) --end -diff --git a/output/output_ovirt_upload.mli b/output/output_ovirt_upload.mli -deleted file mode 100644 -index 06daca34..00000000 ---- a/output/output_ovirt_upload.mli -+++ /dev/null -@@ -1,21 +0,0 @@ --(* virt-v2v -- * Copyright (C) 2009-2025 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 ovirt-upload] output mode. *) -- --module OVirtUpload : Output.OUTPUT -diff --git a/output/output_ovirt_upload_cancel_source.mli b/output/output_ovirt_upload_cancel_source.mli -deleted file mode 100644 -index aa33bc54..00000000 ---- a/output/output_ovirt_upload_cancel_source.mli -+++ /dev/null -@@ -1,19 +0,0 @@ --(* virt-v2v -- * Copyright (C) 2019 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/output/output_ovirt_upload_createvm_source.mli b/output/output_ovirt_upload_createvm_source.mli -deleted file mode 100644 -index c1bafa15..00000000 ---- a/output/output_ovirt_upload_createvm_source.mli -+++ /dev/null -@@ -1,19 +0,0 @@ --(* 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/output/output_ovirt_upload_finalize_source.mli b/output/output_ovirt_upload_finalize_source.mli -deleted file mode 100644 -index aa33bc54..00000000 ---- a/output/output_ovirt_upload_finalize_source.mli -+++ /dev/null -@@ -1,19 +0,0 @@ --(* virt-v2v -- * Copyright (C) 2019 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/output/output_ovirt_upload_plugin_source.mli b/output/output_ovirt_upload_plugin_source.mli -deleted file mode 100644 -index c1bafa15..00000000 ---- a/output/output_ovirt_upload_plugin_source.mli -+++ /dev/null -@@ -1,19 +0,0 @@ --(* 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/output/output_ovirt_upload_precheck_source.mli b/output/output_ovirt_upload_precheck_source.mli -deleted file mode 100644 -index aa33bc54..00000000 ---- a/output/output_ovirt_upload_precheck_source.mli -+++ /dev/null -@@ -1,19 +0,0 @@ --(* virt-v2v -- * Copyright (C) 2019 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/output/output_ovirt_upload_transfer_source.mli b/output/output_ovirt_upload_transfer_source.mli -deleted file mode 100644 -index aa33bc54..00000000 ---- a/output/output_ovirt_upload_transfer_source.mli -+++ /dev/null -@@ -1,19 +0,0 @@ --(* virt-v2v -- * Copyright (C) 2019 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/output/output_ovirt_upload_vmcheck_source.mli b/output/output_ovirt_upload_vmcheck_source.mli -deleted file mode 100644 -index c1bafa15..00000000 ---- a/output/output_ovirt_upload_vmcheck_source.mli -+++ /dev/null -@@ -1,19 +0,0 @@ --(* 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/output/output_vdsm.ml b/output/output_vdsm.ml -deleted file mode 100644 -index db12e0b1..00000000 ---- a/output/output_vdsm.ml -+++ /dev/null -@@ -1,239 +0,0 @@ --(* virt-v2v -- * Copyright (C) 2009-2025 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 Common_gettext.Gettext -- --open Types --open Utils -- --open Output -- --module VDSM = struct -- type poptions = Types.output_allocation * string * string * string * -- string list * string list * string * string * -- string * Create_ovf.ovf_flavour -- -- type t = string * string * int64 list -- -- let to_string options = "-o vdsm" -- -- let query_output_options () = -- let ovf_flavours_str = String.concat "|" Create_ovf.ovf_flavours in -- -- 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: ovirtexp) -- --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_options options source = -- if options.output_password <> None then -- error_option_cannot_be_used_in_output_mode "vdsm" "-op"; -- -- 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.OVirtExportStorageDomain 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 more than once"); -- vm_uuid := Some v; -- | "vdsm-ovf-output", v -> -- if !ovf_output <> None then -- error (f_"-o vdsm: -oo vdsm-ovf-output set more than once"); -- 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.output_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.value ~default:"." !ovf_output in -- let ovf_flavour = !ovf_flavour in -- -- (* -os must be set, but at this point we cannot check it. *) -- let output_storage = -- match options.output_storage with -- | None -> error (f_"-o vdsm: -os option was not specified") -- | 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 -- -- let output_name = Option.value ~default:source.s_name options.output_name in -- -- (options.output_alloc, options.output_format, -- output_name, output_storage, -- image_uuids, vol_uuids, vm_uuid, ovf_output, -- compat, ovf_flavour) -- -- let setup dir options source input_disks = -- error_if_disk_count_gt input_disks 23; -- let input_sizes = get_disk_sizes input_disks in -- let output_alloc, output_format, -- output_name, output_storage, -- image_uuids, vol_uuids, vm_uuid, ovf_output, -- compat, ovf_flavour = options in -- -- if List.length image_uuids <> List.length input_disks || -- List.length vol_uuids <> List.length input_disks then -- 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 input_disks); -- -- let dd_mp, dd_uuid = -- let fields = -- String.nsplit "/" output_storage in (* ... "data-center" "UUID" *) -- let fields = List.rev fields in (* "UUID" "data-center" ... *) -- let fields = List.drop_while ((=) "") fields in -- match fields with -- | uuid :: rest when String.length uuid = 36 -> -- let mp = String.concat "/" (List.rev rest) in -- mp, uuid -- | _ -> -- error (f_"vdsm: invalid -os parameter \ -- does not contain a valid UUID: %s") -- output_storage in -- -- debug "VDSM: DD mountpoint: %s\nVDSM: DD UUID: %s" dd_mp dd_uuid; -- -- (* Note that VDSM has to create all these directories. *) -- let images_dir = dd_mp // dd_uuid // "images" in -- List.iter ( -- fun image_uuid -> -- let d = images_dir // image_uuid in -- if not (is_directory d) then -- error (f_"image directory (%s) does not exist or is not a directory") -- d -- ) image_uuids; -- -- (* Note that VDSM has to create this directory too. *) -- if not (is_directory ovf_output) then -- error (f_"OVF (metadata) directory (%s) does not exist or \ -- is not a directory") -- ovf_output; -- -- debug "VDSM: OVF (metadata) directory: %s" ovf_output; -- -- (* The final directory structure should look like this: -- * ///images/ -- * / # first disk -- * /.meta # first disk -- * / # second disk -- * /.meta # second disk -- * / # etc -- * /.meta # -- *) -- -- (* Create the target filenames. *) -- let filenames = -- List.map ( -- fun (image_uuid, vol_uuid) -> -- let filename = images_dir // image_uuid // vol_uuid in -- debug "VDSM: disk: %s" filename; -- filename -- ) (List.combine image_uuids vol_uuids) in -- -- (* Generate the .meta files associated with each volume. *) -- let metas = -- Create_ovf.create_meta_files output_alloc output_format -- dd_uuid image_uuids input_sizes in -- List.iter ( -- fun (filename, meta) -> -- let meta_filename = filename ^ ".meta" in -- with_open_out meta_filename (fun chan -> output_string chan meta) -- ) (List.combine filenames metas); -- -- (* Set up the NBD servers. *) -- let uris = -- List.mapi ( -- fun i (size, filename) -> -- let socket = sprintf "%s/out%d" dir i in -- On_exit.unlink socket; -- -- (* Create the actual output disk. *) -- output_to_local_file output_alloc output_format filename size socket; -- -- NBD_URI.Unix (socket, None) -- ) (List.combine input_sizes filenames) in -- -- (* Save parameters since we need them during finalization. *) -- let t = dd_mp, dd_uuid, input_sizes in -- t, uris -- -- let finalize dir options t output_disks source inspect target_meta = -- let output_alloc, output_format, -- output_name, output_storage, -- image_uuids, vol_uuids, vm_uuid, ovf_output, -- compat, ovf_flavour = options in -- let dd_mp, dd_uuid, sizes = t in -- -- (* Create the metadata. *) -- let ovf = Create_ovf.create_ovf source inspect target_meta sizes -- output_alloc output_format output_name dd_uuid -- image_uuids -- vol_uuids -- output_disks -- vm_uuid -- ovf_flavour in -- -- (* Write it to the metadata file. *) -- let file = ovf_output // vm_uuid ^ ".ovf" in -- with_open_out file (fun chan -> DOM.doc_to_chan chan ovf) -- -- let request_size = None --end -diff --git a/output/output_vdsm.mli b/output/output_vdsm.mli -deleted file mode 100644 -index c598f5df..00000000 ---- a/output/output_vdsm.mli -+++ /dev/null -@@ -1,21 +0,0 @@ --(* virt-v2v -- * Copyright (C) 2009-2025 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 vdsm] output mode. *) -- --module VDSM : Output.OUTPUT -diff --git a/output/ovirt-upload-cancel.py b/output/ovirt-upload-cancel.py -deleted file mode 100644 -index fed44b45..00000000 ---- a/output/ovirt-upload-cancel.py -+++ /dev/null -@@ -1,96 +0,0 @@ --# -*- python -*- --# oVirt upload cancel used by ‘virt-v2v -o ovirt-upload’ --# Copyright (C) 2019-2025 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 --from contextlib import closing --from urllib.parse import urlparse, urlunparse -- --import ovirtsdk4 as sdk --import ovirtsdk4.types as types -- -- --def debug(s): -- if params['verbose']: -- print(s, file=sys.stderr) -- sys.stderr.flush() -- -- --# 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" --netloc = f"{parsed.hostname:parsed.port}" if parsed.port else parsed.hostname -- --# Connect to the server. --connection = sdk.Connection( -- url=urlunparse(parsed._replace(netloc=netloc)), -- username=username, -- password=output_password, -- ca_file=params['ovirt_cafile'], -- log=logging.getLogger(), -- insecure=params['insecure'], --) -- --with closing(connection): -- system_service = connection.system_service() -- image_transfers_service = system_service.image_transfers_service() -- -- # Try to cancel the transfers. This should delete the associated disk. -- for id in params['transfer_ids']: -- try: -- transfer_service = \ -- image_transfers_service.image_transfer_service(id) -- transfer_service.cancel() -- except sdk.NotFoundError: -- debug("unexpected error: transfer id %s not found" % id) -- except Exception: -- if params['verbose']: -- traceback.print_exc() -- -- disks_service = system_service.disks_service() -- -- # In case we didn't associate a disk with a transfer and as a last -- # resort, delete the disk too. -- for uuid in params['disk_uuids']: -- try: -- disk_service = disks_service.disk_service(uuid) -- disk_service.remove() -- except (sdk.NotFoundError, sdk.Error): -- # We expect these exceptions so ignore them. -- pass -- except Exception: -- if params['verbose']: -- traceback.print_exc() -diff --git a/output/ovirt-upload-createvm.py b/output/ovirt-upload-createvm.py -deleted file mode 100644 -index 6afde782..00000000 ---- a/output/ovirt-upload-createvm.py -+++ /dev/null -@@ -1,137 +0,0 @@ --# -*- python -*- --# oVirt upload create VM used by ‘virt-v2v -o ovirt-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 --import uuid -- --from urllib.parse import urlparse, urlunparse -- --import ovirtsdk4 as sdk --import ovirtsdk4.types as types -- -- --def debug(s): -- if params['verbose']: -- print(s, file=sys.stderr) -- sys.stderr.flush() -- -- --def jobs_completed(system_service, correlation_id): -- jobs_service = system_service.jobs_service() -- -- try: -- jobs = jobs_service.list( -- search="correlation_id=%s" % correlation_id) -- except sdk.Error as e: -- debug( -- "Error searching for jobs with correlation id %s: %s" % -- (correlation_id, e)) -- # We don't know, assume that jobs did not complete yet. -- return False -- -- # STARTED is the only "in progress" status, anything else means the job -- # has already terminated. -- if all(job.status != types.JobStatus.STARTED for job in jobs): -- failed_jobs = [(job.description, str(job.status)) -- for job in jobs -- if job.status != types.JobStatus.FINISHED] -- if failed_jobs: -- raise RuntimeError( -- "Failed to create a VM! Failed jobs: %r" % failed_jobs) -- return True -- else: -- running_jobs = [(job.description, str(job.status)) for job in jobs] -- debug("Some jobs with correlation id %s are running: %s" % -- (correlation_id, running_jobs)) -- return False -- -- --# Seconds to wait for the VM import job to complete in oVirt. --timeout = 3 * 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 --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" --netloc = f"{parsed.hostname:parsed.port}" if parsed.port else parsed.hostname -- --# Connect to the server. --connection = sdk.Connection( -- url=urlunparse(parsed._replace(netloc=netloc)), -- username=username, -- password=output_password, -- ca_file=params['ovirt_cafile'], -- log=logging.getLogger(), -- insecure=params['insecure'], --) -- --system_service = connection.system_service() -- --# Get the cluster. --cluster = system_service.clusters_service().cluster_service(params['ovirt_cluster_uuid']) --cluster = cluster.get() -- --correlation_id = str(uuid.uuid4()) --vms_service = system_service.vms_service() --vm = vms_service.add( -- types.Vm( -- cluster=cluster, -- initialization=types.Initialization( -- configuration=types.Configuration( -- type=types.ConfigurationType.OVA, -- data=ovf, -- ) -- ) -- ), -- query={'correlation_id': correlation_id}, --) -- --# Wait for the import job to finish. --endt = time.monotonic() + timeout --while True: -- time.sleep(10) -- if jobs_completed(system_service, correlation_id): -- break -- if time.monotonic() > endt: -- raise RuntimeError( -- "Timed out waiting for VM creation!" -- " Jobs still running for correlation id %s" % correlation_id) -diff --git a/output/ovirt-upload-finalize.py b/output/ovirt-upload-finalize.py -deleted file mode 100644 -index 8dd4a731..00000000 ---- a/output/ovirt-upload-finalize.py -+++ /dev/null -@@ -1,174 +0,0 @@ --# -*- python -*- --# oVirt upload finalize used by ‘virt-v2v -o ovirt-upload’ --# Copyright (C) 2018-2025 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 urllib.parse import urlparse, urlunparse -- --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 -- -- --def debug(s): -- if params['verbose']: -- print(s, file=sys.stderr) -- sys.stderr.flush() -- -- --def finalize_transfer(connection, transfer_id, disk_id): -- """ -- Finalize a transfer, making the transfer disk available. -- -- If finalizing succeeds, the transfer's disk status will change to OK -- and transfer's phase will change to FINISHED_SUCCESS. Unfortunately, -- the disk status is modified before the transfer finishes, and oVirt -- may still hold a lock on the disk at this point. -- -- The only way to make sure that the disk is unlocked, is to wait -- until the transfer phase switches FINISHED_SUCCESS. Unfortunately -- oVirt makes this hard to use because the transfer is removed shortly -- after switching the phase to the final phase. However if the -- transfer was removed, we can be sure that the disk is not locked, -- since oVirt releases the locks before removing the transfer. -- -- On errors, the transfer's phase will change to FINISHED_FAILURE and -- the disk status will change to ILLEGAL and it will be removed. Again -- the transfer will be removed shortly after that. -- -- If oVirt fails to finalize the transfer, transfer's phase will -- change to PAUSED_SYSTEM. In this case the disk's status will change -- to ILLEGAL and it will not be removed. -- -- oVirt 4.4.7 made waiting for transfer easier by keeping transfers -- after they complete, but we must support older versions so we have -- generic code that work with any version. -- -- For more info see: -- - http://ovirt.github.io/ovirt-engine-api-model/4.4/#services/image_transfer -- - http://ovirt.github.io/ovirt-engine-sdk/master/types.m.html#ovirtsdk4.types.ImageTransfer -- """ -- debug("finalizing transfer %s" % transfer_id) -- transfer_service = (connection.system_service() -- .image_transfers_service() -- .image_transfer_service(transfer_id)) -- -- start = time.monotonic() -- -- transfer_service.finalize() -- -- while True: -- time.sleep(1) -- try: -- transfer = transfer_service.get() -- except sdk.NotFoundError: -- # Transfer was removed (ovirt < 4.4.7). We need to check the -- # disk status to understand if the transfer was successful. -- # Due to the way oVirt does locking, we know that the disk -- # is unlocked at this point so we can check only once. -- -- debug("transfer %s was removed, checking disk %s status" -- % (transfer_id, disk_id)) -- -- disk_service = (connection.system_service() -- .disks_service() -- .disk_service(disk_id)) -- -- try: -- disk = disk_service.get() -- except sdk.NotFoundError: -- raise RuntimeError( -- "transfer %s failed: disk %s was removed" -- % (transfer_id, disk_id)) -- -- debug("disk %s is %s" % (disk.id, disk.status)) -- -- if disk.status == types.DiskStatus.OK: -- break -- -- raise RuntimeError( -- "transfer %s failed: disk is %s" % (transfer_id, disk.status)) -- else: -- # Transfer exists, check if it reached one of the final -- # phases, or we timed out. -- -- debug("transfer %s is %s" % (transfer.id, transfer.phase)) -- -- if transfer.phase == types.ImageTransferPhase.FINISHED_SUCCESS: -- break -- -- if transfer.phase == types.ImageTransferPhase.FINISHED_FAILURE: -- raise RuntimeError( -- "transfer %s has failed" % (transfer_id,)) -- -- if transfer.phase == types.ImageTransferPhase.PAUSED_SYSTEM: -- raise RuntimeError( -- "transfer %s was paused by system" % (transfer.id,)) -- -- if time.monotonic() > start + timeout: -- raise RuntimeError( -- "timed out waiting for transfer %s to finalize, " -- "transfer is %s" -- % (transfer.id, transfer.phase)) -- -- debug("transfer %s finalized in %.3f seconds" -- % (transfer_id, time.monotonic() - start)) -- -- --# 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" --netloc = f"{parsed.hostname:parsed.port}" if parsed.port else parsed.hostname -- --# Connect to the server. --connection = sdk.Connection( -- url=urlunparse(parsed._replace(netloc=netloc)), -- username=username, -- password=output_password, -- ca_file=params['ovirt_cafile'], -- log=logging.getLogger(), -- insecure=params['insecure'], --) -- --# Finalize all the transfers. --for (transfer_id, disk_id) in zip(params['transfer_ids'], params['disk_uuids']): -- finalize_transfer(connection, transfer_id, disk_id) -- --connection.close() -diff --git a/output/ovirt-upload-plugin.py b/output/ovirt-upload-plugin.py -deleted file mode 100644 -index a10ecfd5..00000000 ---- a/output/ovirt-upload-plugin.py -+++ /dev/null -@@ -1,525 +0,0 @@ --# -*- python -*- --# oVirt upload nbdkit plugin used by ‘virt-v2v -o ovirt-upload’ --# Copyright (C) 2018-2025 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 queue --import socket --import ssl --import threading --import time -- --from contextlib import contextmanager --from http.client import HTTPSConnection, HTTPConnection --from urllib.parse import urlparse -- --import nbdkit -- --# Using version 2 supporting the buffer protocol for better performance. --API_VERSION = 2 -- --# Maximum number of connection to imageio server. Based on testing with imageio --# client, this give best performance. --MAX_CONNECTIONS = 4 -- --# Maximum idle time allowed for imageio connections. --IDLE_TIMEOUT = 30 -- --# Required parameters. --size = None --url = None -- --# Optional parameters. --cafile = None --insecure = False --is_ovirt_host = False -- --# List of options read from imageio server. --options = None -- --# Pool of HTTP connections. --pool = None -- --# Set when plugin is cleaning up. --done = threading.Event() -- --# Set when periodic flush request fails. --pool_error = None -- -- --# Parse parameters. --def config(key, value): -- global cafile, url, is_ovirt_host, insecure, size -- -- if key == "cafile": -- cafile = value -- elif key == "insecure": -- insecure = value.lower() in ['true', '1'] -- elif key == "is_ovirt_host": -- is_ovirt_host = value.lower() in ['true', '1'] -- elif key == "size": -- size = int(value) -- elif key == "url": -- url = urlparse(value) -- else: -- raise RuntimeError("unknown configuration key '%s'" % key) -- -- --def config_complete(): -- # These parameters are required. -- if url is None: -- raise RuntimeError("url parameter was not set") -- if size is None: -- raise RuntimeError("size parameter was not set") -- -- --def after_fork(): -- global options, pool -- -- http = create_http(url) -- options = get_options(http, url) -- http.close() -- -- nbdkit.debug("imageio features: flush=%(can_flush)r " -- "zero=%(can_zero)r unix_socket=%(unix_socket)r " -- "max_readers=%(max_readers)r max_writers=%(max_writers)r" -- % options) -- -- pool = create_http_pool(url, options) -- -- t = threading.Thread(target=pool_keeper, name="poolkeeper") -- t.daemon = True -- t.start() -- -- --# This function is not actually defined before nbdkit 1.28, but it --# doesn't particularly matter if we don't close the pool because --# clients should call flush(). --def cleanup(): -- nbdkit.debug("cleaning up") -- done.set() -- close_http_pool(pool) -- -- --def thread_model(): -- """ -- Using parallel model to speed up transfer with multiple connections to -- imageio server. -- """ -- return nbdkit.THREAD_MODEL_PARALLEL -- -- --def open(readonly): -- return 1 -- -- --def can_trim(h): -- return False -- -- --def can_flush(h): -- return options['can_flush'] -- -- --def can_fua(h): -- # imageio flush feature is is compatible with NBD_CMD_FLAG_FUA. -- return options['can_flush'] -- -- --def can_multi_conn(h): -- # We can always handle multiple connections, and the number of NBD -- # connections is independent of the number of HTTP clients in the -- # pool. -- return True -- -- --def get_size(h): -- return size -- -- --# Any unexpected HTTP response status from the server will end up calling this --# function which logs the full error, and raises a RuntimeError exception. --def request_failed(r, msg): -- 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. -- nbdkit.debug("unexpected response from imageio server:") -- nbdkit.debug(msg) -- nbdkit.debug("%d: %s" % (status, reason)) -- nbdkit.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: --# https://github.com/oVirt/ovirt-imageio/blob/master/daemon/test/server_test.py --def pread(h, buf, offset, flags): -- count = len(buf) -- headers = {"Range": "bytes=%d-%d" % (offset, offset + count - 1)} -- -- with http_context(pool) as http: -- http.request("GET", url.path, headers=headers) -- -- r = http.getresponse() -- # 206 = HTTP Partial Content. -- if r.status != 206: -- request_failed(r, -- "could not read sector offset %d size %d" % -- (offset, count)) -- -- content_length = int(r.getheader("content-length")) -- if content_length != count: -- # Should never happen. -- request_failed(r, -- "unexpected Content-Length offset %d size %d got %d" % -- (offset, count, content_length)) -- -- with memoryview(buf) as view: -- got = 0 -- while got < count: -- n = r.readinto(view[got:]) -- if n == 0: -- request_failed(r, -- "short read offset %d size %d got %d" % -- (offset, count, got)) -- got += n -- -- --def pwrite(h, buf, offset, flags): -- count = len(buf) -- -- flush = "y" if (options['can_flush'] and (flags & nbdkit.FLAG_FUA)) else "n" -- -- with http_context(pool) as http: -- http.putrequest("PUT", url.path + "?flush=" + flush) -- # 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() -- -- try: -- http.send(buf) -- except BrokenPipeError: -- pass -- -- r = http.getresponse() -- if r.status != 200: -- request_failed(r, -- "could not write sector offset %d size %d" % -- (offset, count)) -- -- r.read() -- -- --def zero(h, count, offset, flags): -- # 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 options['can_zero']: -- emulate_zero(h, count, offset, flags) -- return -- -- flush = bool(options['can_flush'] and (flags & nbdkit.FLAG_FUA)) -- -- # Construct the JSON request for zeroing. -- buf = json.dumps({'op': "zero", -- 'offset': offset, -- 'size': count, -- 'flush': flush}).encode() -- -- headers = {"Content-Type": "application/json", -- "Content-Length": str(len(buf))} -- -- with http_context(pool) as http: -- http.request("PATCH", url.path, body=buf, headers=headers) -- -- r = http.getresponse() -- if r.status != 200: -- request_failed(r, -- "could not zero sector offset %d size %d" % -- (offset, count)) -- -- r.read() -- -- --def emulate_zero(h, count, offset, flags): -- flush = "y" if (options['can_flush'] and (flags & nbdkit.FLAG_FUA)) else "n" -- -- with http_context(pool) as http: -- http.putrequest("PUT", url.path + "?flush=" + flush) -- http.putheader("Content-Range", -- "bytes %d-%d/*" % (offset, offset + count - 1)) -- http.putheader("Content-Length", str(count)) -- http.endheaders() -- -- try: -- buf = bytearray(128 * 1024) -- while count > len(buf): -- http.send(buf) -- count -= len(buf) -- http.send(memoryview(buf)[:count]) -- except BrokenPipeError: -- pass -- -- r = http.getresponse() -- if r.status != 200: -- request_failed(r, -- "could not write zeroes offset %d size %d" % -- (offset, count)) -- -- r.read() -- -- --def flush(h, flags): -- if pool_error: -- raise pool_error -- -- # Wait until all inflight requests are completed, and send a flush -- # request for all imageio connections. -- locked = [] -- -- # Lock the pool by taking all connections out. -- while len(locked) < pool.maxsize: -- locked.append(pool.get()) -- -- try: -- for item in locked: -- send_flush(item.http) -- item.last_used = time.monotonic() -- finally: -- # Unlock the pool by putting the connection back. -- for item in locked: -- pool.put(item) -- -- --def send_flush(http): -- # Construct the JSON request for flushing. -- buf = json.dumps({'op': "flush"}).encode() -- -- headers = {"Content-Type": "application/json", -- "Content-Length": str(len(buf))} -- -- http.request("PATCH", url.path, body=buf, headers=headers) -- -- r = http.getresponse() -- if r.status != 200: -- request_failed(r, "could not flush") -- -- r.read() -- -- --# 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 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) -- -- --class PoolItem: -- -- def __init__(self, http): -- self.http = http -- self.last_used = None -- -- --# Connection pool. --def create_http_pool(url, options): -- count = min(options["max_readers"], -- options["max_writers"], -- MAX_CONNECTIONS) -- -- nbdkit.debug("creating http pool connections=%d" % count) -- -- unix_socket = options["unix_socket"] if is_ovirt_host else None -- -- pool = queue.Queue(count) -- -- for i in range(count): -- http = create_http(url, unix_socket=unix_socket) -- pool.put(PoolItem(http)) -- -- return pool -- -- --def pool_keeper(): -- """ -- Thread flushing idle connections, keeping them alive. -- -- If a connection does not send any request for 60 seconds, imageio -- server closes the connection. Recovering from closed connection is -- hard and unsafe, so this thread ensure that connections never -- becomes idle by sending a flush request if the connection is idle -- for too much time. -- -- In normal conditions, all connections are busy most of the time, so -- the keeper will find no idle connections. If there short delays in -- nbdcopy, the keeper will find some idle connections, but will -- quickly return them back to the pool. In the pathological case when -- nbdcopy is blocked for 3 minutes on vddk input, the keeper will send -- a flush request on all connections every ~30 seconds, until nbdcopy -- starts communicating again. -- """ -- global pool_error -- -- nbdkit.debug("poolkeeper: started") -- -- while not done.wait(IDLE_TIMEOUT / 2): -- idle = [] -- -- while True: -- try: -- idle.append(pool.get_nowait()) -- except queue.Empty: -- break -- -- if idle: -- now = time.monotonic() -- for item in idle: -- if item.last_used and now - item.last_used > IDLE_TIMEOUT: -- nbdkit.debug("poolkeeper: flushing idle connection") -- try: -- send_flush(item.http) -- item.last_used = now -- except Exception as e: -- # We will report this error on the next request. -- pool_error = e -- item.last_used = None -- -- pool.put(item) -- -- nbdkit.debug("poolkeeper: stopped") -- -- --@contextmanager --def http_context(pool): -- """ -- Context manager yielding an imageio http connection from the pool. Blocks -- until a connection is available. -- """ -- if pool_error: -- raise pool_error -- -- item = pool.get() -- try: -- yield item.http -- finally: -- item.last_used = time.monotonic() -- pool.put(item) -- -- --def close_http_pool(pool): -- """ -- Wait until all inflight requests are done, close all connections and remove -- them from the pool. -- -- No request can be served by the pool after this call. -- """ -- nbdkit.debug("closing http pool") -- -- locked = [] -- -- while len(locked) < pool.maxsize: -- locked.append(pool.get()) -- -- for item in locked: -- item.http.close() -- -- --def create_http(url, unix_socket=None): -- """ -- Create http connection for transfer url. -- -- Returns HTTPConnection. -- """ -- if unix_socket: -- nbdkit.debug("creating unix http connection socket=%r" % unix_socket) -- try: -- return UnixHTTPConnection(unix_socket) -- except Exception as e: -- # Very unlikely, but we can recover by using https. -- nbdkit.debug("cannot create unix socket connection: %s" % e) -- -- if url.scheme == "https": -- context = \ -- ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH, -- cafile=cafile) -- if insecure: -- context.check_hostname = False -- context.verify_mode = ssl.CERT_NONE -- -- nbdkit.debug("creating https connection host=%s port=%s" % -- (url.hostname, url.port)) -- return HTTPSConnection(url.hostname, url.port, context=context) -- elif url.scheme == "http": -- nbdkit.debug("creating http connection host=%s port=%s" % -- (url.hostname, url.port)) -- return HTTPConnection(url.hostname, url.port) -- else: -- raise RuntimeError("unknown URL scheme (%s)" % url.scheme) -- -- --def get_options(http, url): -- """ -- Send OPTIONS request to imageio server and return options dict. -- """ -- http.request("OPTIONS", url.path) -- r = http.getresponse() -- data = r.read() -- -- if r.status == 200: -- j = json.loads(data) -- features = j["features"] -- return { -- "can_flush": "flush" in features, -- "can_zero": "zero" in features, -- "unix_socket": j.get('unix_socket'), -- "max_readers": j.get("max_readers", 1), -- "max_writers": j.get("max_writers", 1), -- } -- -- elif r.status == 405 or r.status == 204: -- # Old imageio servers returned either 405 Method Not Allowed or -- # 204 No Content (with an empty body). -- return { -- "can_flush": False, -- "can_zero": False, -- "unix_socket": None, -- "max_readers": 1, -- "max_writers": 1, -- } -- else: -- raise RuntimeError("could not use OPTIONS request: %d: %s" % -- (r.status, r.reason)) -diff --git a/output/ovirt-upload-precheck.py b/output/ovirt-upload-precheck.py -deleted file mode 100644 -index 00d5a829..00000000 ---- a/output/ovirt-upload-precheck.py -+++ /dev/null -@@ -1,135 +0,0 @@ --# -*- python -*- --# oVirt pre-upload checks used by ‘virt-v2v -o ovirt-upload’ --# Copyright (C) 2018-2025 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 re --import sys -- --from urllib.parse import urlparse, urlunparse -- --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" --netloc = f"{parsed.hostname:parsed.port}" if parsed.port else parsed.hostname -- --# Check the storage domain name is valid --# (https://bugzilla.redhat.com/show_bug.cgi?id=1986386#c1) --# Also this means it cannot contain spaces or glob symbols, so --# the search below is valid. --output_storage = params['output_storage'] --if not re.match('^[-a-zA-Z0-9_]+$', output_storage): -- raise RuntimeError("The storage domain (-os) parameter ‘%s’ is not valid" % -- output_storage) -- --# Connect to the server. --connection = sdk.Connection( -- url=urlunparse(parsed._replace(netloc=netloc)), -- username=username, -- password=output_password, -- ca_file=params['ovirt_cafile'], -- log=logging.getLogger(), -- insecure=params['insecure'], --) -- --system_service = connection.system_service() -- --# Check whether there is a datacenter for the specified storage. --data_centers = system_service.data_centers_service().list( -- search='storage.name=%s' % output_storage, -- case_sensitive=True, --) --if len(data_centers) == 0: -- storage_domains = system_service.storage_domains_service().list( -- search='name=%s' % output_storage, -- case_sensitive=True, -- ) -- if len(storage_domains) == 0: -- # The storage domain does not even exist. -- raise RuntimeError("The storage domain ‘%s’ does not exist" % -- output_storage) -- -- # The storage domain is not attached to a datacenter -- # (shouldn't happen, would fail on disk creation). -- raise RuntimeError("The storage domain ‘%s’ is not attached to a DC" % -- output_storage) --datacenter = data_centers[0] -- --# Get the storage domain. --storage_domains = connection.follow_link(datacenter.storage_domains) --try: -- storage_domain = [sd for sd in storage_domains -- if sd.name == output_storage][0] --except IndexError: -- raise RuntimeError("The storage domain ‘%s’ does not exist" % -- output_storage) -- --# Get the cluster. --clusters = connection.follow_link(datacenter.clusters) --clusters = [cluster for cluster in clusters if cluster.name == params['ovirt_cluster']] --if len(clusters) == 0: -- raise RuntimeError("The cluster ‘%s’ is not part of the DC ‘%s’, " -- "where the storage domain ‘%s’ is" % -- (params['ovirt_cluster'], datacenter.name, -- output_storage)) --cluster = clusters[0] --cpu = cluster.cpu --if cpu.architecture == types.Architecture.UNDEFINED: -- raise RuntimeError("The cluster ‘%s’ has an unknown architecture" % -- (params['ovirt_cluster'])) -- --# Find if any disk already exists with specified UUID. --# Only used with -oo ovirt-disk-uuid. It is assumed that the --# random UUIDs that we generate are unlikely to conflict. --disks_service = system_service.disks_service() -- --for uuid in params.get('ovirt_disk_uuids', []): -- try: -- disk_service = disks_service.disk_service(uuid).get() -- raise RuntimeError("Disk with the UUID '%s' already exists" % uuid) -- except sdk.NotFoundError: -- pass -- --# Otherwise everything is OK, print a JSON with the results. --results = { -- "ovirt_storagedomain_uuid": storage_domain.id, -- "ovirt_cluster_uuid": cluster.id, -- "ovirt_cluster_cpu_architecture": cpu.architecture.value, --} -- --json.dump(results, sys.stdout) -diff --git a/output/ovirt-upload-transfer.py b/output/ovirt-upload-transfer.py -deleted file mode 100644 -index 22a99592..00000000 ---- a/output/ovirt-upload-transfer.py -+++ /dev/null -@@ -1,298 +0,0 @@ --# -*- python -*- --# oVirt upload start transfer used by ‘virt-v2v -o ovirt-upload’ --# Copyright (C) 2018-2025 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 inspect --import json --import logging --import sys --import time --from contextlib import closing --from urllib.parse import urlparse, urlunparse -- --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 -- -- --def debug(s): -- if params['verbose']: -- print(s, file=sys.stderr) -- sys.stderr.flush() -- -- --def find_host(connection): -- """Return the current host object or None.""" -- try: -- with open("/etc/vdsm/vdsm.id") as f: -- vdsm_id = f.readline().strip() -- except FileNotFoundError: -- # Expected condition when running on non-oVirt host. -- debug("not an oVirt host, using non-oVirt host") -- return None -- except Exception as e: -- # Unexpected but we can degrade to remote transfer. -- debug(f"warning: cannot read host id, using non-oVirt host: {e}") -- return None -- -- debug("hw_id = %r" % vdsm_id) -- -- system_service = connection.system_service() -- storage_name = params['output_storage'] -- data_centers = system_service.data_centers_service().list( -- search='storage.name=%s' % storage_name, -- case_sensitive=True, -- ) -- if len(data_centers) == 0: -- # The storage domain is not attached to a datacenter -- # (shouldn't happen, would fail on disk creation). -- debug("storage 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 and datacenter=%s and status=Up" -- % (vdsm_id, datacenter.name), -- case_sensitive=True, -- ) -- if len(hosts) == 0: -- # 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] -- debug("host.id = %r" % host.id) -- -- return types.Host(id=host.id) -- -- --def create_disk(connection): -- """ -- Create a new disk for the transfer and wait until the disk is ready. -- -- Returns disk object. -- """ -- system_service = connection.system_service() -- 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( -- id=params['disk_uuid'], -- name=params['disk_name'], -- description="Uploaded by virt-v2v", -- format=disk_format, -- # XXX For qcow2 disk on block storage, we should use the estimated -- # size, based on qemu-img measure of the overlay. -- initial_size=params['disk_size'], -- provisioned_size=params['disk_size'], -- # 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'], -- ) -- ], -- ) -- ) -- -- debug("disk.id = %r" % disk.id) -- -- # Wait till the disk moved from LOCKED state to OK state, as the transfer -- # can't start if the disk is locked. -- -- disk_service = disks_service.disk_service(disk.id) -- endt = time.monotonic() + timeout -- while True: -- time.sleep(1) -- disk = disk_service.get() -- if disk.status == types.DiskStatus.OK: -- break -- if time.monotonic() > endt: -- raise RuntimeError( -- "timed out waiting for disk %s to become unlocked" % disk.id) -- -- return disk -- -- --def create_transfer(connection, disk, host): -- """ -- Create image transfer and wait until the transfer is ready. -- -- Returns a transfer object. -- """ -- system_service = connection.system_service() -- transfers_service = system_service.image_transfers_service() -- -- extra = {} -- if transfer_supports_format(): -- extra["format"] = types.DiskFormat.RAW -- -- transfer = transfers_service.add( -- types.ImageTransfer( -- disk=types.Disk(id=disk.id), -- host=host, -- inactivity_timeout=3600, -- **extra, -- ) -- ) -- -- # At this point the transfer owns the disk and will delete the disk if the -- # transfer is canceled, or if finalizing the transfer fails. -- -- debug("transfer.id = %r" % transfer.id) -- -- # Get a reference to the created transfer service. -- transfer_service = transfers_service.image_transfer_service(transfer.id) -- -- # Wait until transfer's phase change from INITIALIZING to TRANSFERRING. On -- # errors transfer's phase can change to PAUSED_SYSTEM or FINISHED_FAILURE. -- # If the transfer was paused, we need to cancel it to remove the disk, -- # otherwise the system will remove the disk and transfer shortly after. -- -- endt = time.monotonic() + timeout -- while True: -- time.sleep(1) -- try: -- transfer = transfer_service.get() -- except sdk.NotFoundError: -- # The system has removed the disk and the transfer. -- raise RuntimeError("transfer %s was removed" % transfer.id) -- -- if transfer.phase == types.ImageTransferPhase.FINISHED_FAILURE: -- # The system will remove the disk and the transfer soon. -- raise RuntimeError( -- "transfer %s has failed" % transfer.id) -- -- if transfer.phase == types.ImageTransferPhase.PAUSED_SYSTEM: -- transfer_service.cancel() -- raise RuntimeError( -- "transfer %s was paused by system" % transfer.id) -- -- if transfer.phase == types.ImageTransferPhase.TRANSFERRING: -- break -- -- if transfer.phase != types.ImageTransferPhase.INITIALIZING: -- transfer_service.cancel() -- raise RuntimeError( -- "unexpected transfer %s phase %s" -- % (transfer.id, transfer.phase)) -- -- if time.monotonic() > endt: -- transfer_service.cancel() -- raise RuntimeError( -- "timed out waiting for transfer %s" % transfer.id) -- -- return transfer -- -- --def transfer_supports_format(): -- """ -- Return True if transfer supports the "format" argument, enabling the NBD -- backend on imageio side, which allows uploading to qcow2 images. -- -- This feature was added in ovirt 4.3. We assume that the SDK version matches -- engine version. -- """ -- sig = inspect.signature(types.ImageTransfer) -- return "format" in sig.parameters -- -- --def get_transfer_url(transfer): -- """ -- Returns the transfer url, preferring direct transfer if possible. -- """ -- if params['ovirt_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 " -- "environment, eg. on an oVirt node.") -- return transfer.transfer_url -- else: -- return transfer.proxy_url -- -- --# 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: -- data = fp.read() -- --try: -- params = json.loads(data) --except ValueError as e: -- raise RuntimeError(f"Cannot parse params {data!r}: {e}").with_traceback( -- e.__traceback__ -- ) from None -- --# 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" --netloc = f"{parsed.hostname:parsed.port}" if parsed.port else parsed.hostname -- --connection = sdk.Connection( -- url=urlunparse(parsed._replace(netloc=netloc)), -- username=username, -- password=output_password, -- ca_file=params['ovirt_cafile'], -- log=logging.getLogger(), -- insecure=params['insecure'], --) -- --with closing(connection): -- # Use the local host if possible. -- host = find_host(connection) if params['ovirt_direct'] else None -- disk = create_disk(connection) -- -- transfer = create_transfer(connection, disk, host) -- destination_url = get_transfer_url(transfer) -- --# Send the destination URL, transfer ID, and host flag back to OCaml code. --results = { -- "transfer_id": transfer.id, -- "destination_url": destination_url, -- "is_ovirt_host": host is not None, --} --json.dump(results, sys.stdout) -diff --git a/output/ovirt-upload-vmcheck.py b/output/ovirt-upload-vmcheck.py -deleted file mode 100644 -index 6240046e..00000000 ---- a/output/ovirt-upload-vmcheck.py -+++ /dev/null -@@ -1,72 +0,0 @@ --# -*- python -*- --# oVirt VM existence check used by ‘virt-v2v -o ovirt-upload’ --# Copyright (C) 2018-2025 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 -- --from urllib.parse import urlparse, urlunparse -- --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" --netloc = f"{parsed.hostname:parsed.port}" if parsed.port else parsed.hostname -- --# Connect to the server. --connection = sdk.Connection( -- url=urlunparse(parsed._replace(netloc=netloc)), -- username=username, -- password=output_password, -- ca_file=params['ovirt_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/output/select_output.ml b/output/select_output.ml -index b1f7d0ab..7c01b50b 100644 ---- a/output/select_output.ml -+++ b/output/select_output.ml -@@ -25,10 +25,7 @@ type output_mode = - | Libvirt - | Null - | Openstack -- | OVirt -- | OVirt_Upload - | QEmu -- | VDSM - - let output_modes = [ - Disk; -@@ -36,10 +33,7 @@ let output_modes = [ - Libvirt; - Null; - Openstack; -- OVirt; -- OVirt_Upload; - QEmu; -- VDSM; - ] - - let string_of_output_mode = function -@@ -48,10 +42,7 @@ let string_of_output_mode = function - | Libvirt -> "libvirt" - | Null -> "null" - | Openstack -> "openstack" -- | OVirt -> "ovirt" -- | OVirt_Upload -> "ovirt-upload" - | QEmu -> "qemu" -- | VDSM -> "vdsm" - - let output_mode_of_string = function - | "kubevirt" -> Kubevirt -@@ -59,11 +50,7 @@ let output_mode_of_string = function - | "disk" | "local" -> Disk - | "null" -> Null - | "openstack" | "osp" | "rhosp" -> Openstack -- | "ovirt" | "rhv" | "rhev" -> OVirt -- | "ovirt-upload" | "ovirt_upload" | "rhv-upload" | "rhv_upload" -> -- OVirt_Upload - | "qemu" -> QEmu -- | "vdsm" -> VDSM - | s -> error (f_"unknown -o option: %s") s - - let select_output = function -@@ -73,6 +60,3 @@ let select_output = function - | Some QEmu -> (module Output_qemu.QEMU) - | Some Kubevirt -> (module Output_kubevirt.Kubevirt) - | Some Openstack -> (module Output_openstack.Openstack) -- | Some OVirt_Upload -> (module Output_ovirt_upload.OVirtUpload) -- | Some OVirt -> (module Output_ovirt.OVirt) -- | Some VDSM -> (module Output_vdsm.VDSM) -diff --git a/output/select_output.mli b/output/select_output.mli -index 093c9b9a..1f8259e3 100644 ---- a/output/select_output.mli -+++ b/output/select_output.mli -@@ -22,10 +22,7 @@ type output_mode = - | Libvirt - | Null - | Openstack -- | OVirt -- | OVirt_Upload - | QEmu -- | VDSM - (** [-o] option on the command line *) - - val output_modes : output_mode list -diff --git a/tests/Makefile.am b/tests/Makefile.am -index c0aa8498..df221b73 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -99,12 +99,7 @@ TESTS = \ - test-o-local-qcow2-compressed.sh \ - test-o-null.sh \ - test-o-openstack.sh \ -- test-o-ovirt-upload-oo-query.sh \ -- test-o-ovirt-upload.sh \ -- test-o-ovirt.sh \ - test-o-qemu.sh \ -- test-o-vdsm-oo-query.sh \ -- test-o-vdsm-options.sh \ - test-oa-option-qcow2.sh \ - test-oa-option-raw.sh \ - test-of-option.sh \ -@@ -294,17 +289,7 @@ EXTRA_DIST += \ - test-o-local-qcow2-compressed.sh \ - test-o-null.sh \ - test-o-openstack.sh \ -- test-o-ovirt-upload-module/imageio.py \ -- test-o-ovirt-upload-module/ovirtsdk4/__init__.py \ -- test-o-ovirt-upload-module/ovirtsdk4/types.py \ -- test-o-ovirt-upload-oo-query.sh \ -- test-o-ovirt-upload.sh \ -- test-o-ovirt.ovf.expected \ -- test-o-ovirt.sh \ - test-o-qemu.sh \ -- test-o-vdsm-oo-query.sh \ -- test-o-vdsm-options.ovf.expected \ -- test-o-vdsm-options.sh \ - test-oa-option-qcow2.sh \ - test-oa-option-raw.sh \ - test-of-option.sh \ -diff --git a/tests/test-o-ovirt-upload-module/imageio.py b/tests/test-o-ovirt-upload-module/imageio.py -deleted file mode 100755 -index f832f8dc..00000000 ---- a/tests/test-o-ovirt-upload-module/imageio.py -+++ /dev/null -@@ -1,71 +0,0 @@ --#!/usr/bin/env python3 --# -*- python -*- --# Copyright (C) 2018-2025 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. -- --# Fake imageio web server used as a test harness. --# See v2v/test-o-ovirt-upload.sh -- --import sys --import threading --from http.server import HTTPServer, BaseHTTPRequestHandler -- --class RequestHandler(BaseHTTPRequestHandler): -- protocol_version = 'HTTP/1.1' -- -- def do_OPTIONS(self): -- self.discard_request() -- -- # Advertise only flush and zero support. -- content = b'''{ "features": [ "flush", "zero" ] }''' -- length = len(content) -- -- self.send_response(200) -- self.send_header("Content-type", "application/json; charset=UTF-8") -- self.send_header("Content-Length", length) -- self.end_headers() -- self.wfile.write(content) -- -- # eg. zero request. Just ignore it. -- def do_PATCH(self): -- self.discard_request() -- self.send_response(200) -- self.send_header("Content-Length", "0") -- self.end_headers() -- -- # Flush request. Ignore it. -- def do_PUT(self): -- self.discard_request() -- self.send_response(200) -- self.send_header("Content-Length", "0") -- self.end_headers() -- -- def discard_request(self): -- length = self.headers.get('Content-Length') -- if length: -- length = int(length) -- content = self.rfile.read(length) -- --server_address = ("", 0) --# XXX This should test HTTPS, not HTTP, because we are testing a --# different path through the main code. --httpd = HTTPServer(server_address, RequestHandler) --imageio_port = httpd.server_address[1] -- --print("port: %d" % imageio_port) --sys.stdout.flush() -- --httpd.serve_forever() -diff --git a/tests/test-o-ovirt-upload-module/ovirtsdk4/__init__.py b/tests/test-o-ovirt-upload-module/ovirtsdk4/__init__.py -deleted file mode 100644 -index 3236b0fa..00000000 ---- a/tests/test-o-ovirt-upload-module/ovirtsdk4/__init__.py -+++ /dev/null -@@ -1,150 +0,0 @@ --# -*- python -*- --# 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. -- --# Fake ovirtsdk4 module used as a test harness. --# See v2v/test-o-ovirt-upload.sh -- --class Error(Exception): -- pass -- -- --class NotFoundError(Error): -- pass -- -- --class Connection(object): -- def __init__( -- self, -- url=None, -- username=None, -- password=None, -- ca_file=None, -- log=None, -- insecure=False, -- debug=True, -- ): -- pass -- -- def close(self): -- pass -- -- def follow_link(self, objs): -- return objs -- -- def system_service(self): -- return SystemService() -- -- --class SystemService(object): -- def clusters_service(self): -- return ClustersService() -- -- def data_centers_service(self): -- return DataCentersService() -- -- def disks_service(self): -- return DisksService() -- -- def jobs_service(self): -- return JobsService() -- -- def image_transfers_service(self): -- return ImageTransfersService() -- -- def storage_domains_service(self): -- return StorageDomainsService() -- -- def vms_service(self): -- return VmsService() -- -- --class ClusterService(object): -- def get(self): -- return types.Cluster() -- -- --class ClustersService(object): -- def cluster_service(self, id): -- return ClusterService() -- -- --class DataCentersService(object): -- def list(self, search=None, case_sensitive=False): -- return [types.DataCenter()] -- -- --class DiskService(object): -- def __init__(self, disk_id): -- self._disk_id = disk_id -- -- def get(self): -- return types.Disk(id=self._disk_id) -- -- def remove(self): -- pass -- -- --class DisksService(object): -- def add(self, disk=None): -- disk.id = "756d81b0-d5c0-41bc-9bbe-b343c3fa3490" -- return disk -- -- def disk_service(self, disk_id): -- return DiskService(disk_id) -- -- --class JobsService(object): -- def list(self, search=None): -- return [types.Job()] -- -- --class ImageTransferService(object): -- def __init__(self): -- self._finalized = False -- -- def cancel(self): -- pass -- -- def get(self): -- if self._finalized: -- raise NotFoundError -- else: -- return types.ImageTransfer() -- -- def finalize(self): -- self._finalized = True -- -- --class ImageTransfersService(object): -- def add(self, transfer): -- return transfer -- -- def image_transfer_service(self, id): -- return ImageTransferService() -- -- --class StorageDomainsService(object): -- def list(self, search=None, case_sensitive=False): -- return [StorageDomain()] -- -- --class VmsService(object): -- def add(self, vm, query=None): -- return vm -- -- def list(self, search=None): -- return [] -diff --git a/tests/test-o-ovirt-upload-module/ovirtsdk4/types.py b/tests/test-o-ovirt-upload-module/ovirtsdk4/types.py -deleted file mode 100644 -index ca2a0562..00000000 ---- a/tests/test-o-ovirt-upload-module/ovirtsdk4/types.py -+++ /dev/null -@@ -1,184 +0,0 @@ --# -*- python -*- --# 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. -- --# Fake ovirtsdk4 module used as a test harness. --# See v2v/test-o-ovirt-upload.sh -- --import os --from enum import Enum -- --imageio_port = os.getenv("IMAGEIO_PORT") --assert imageio_port is not None -- -- --class Architecture(Enum): -- UNDEFINED = "undefined" -- X86_64 = "x86_64" -- -- def __init__(self, arch): -- self._arch = arch -- -- def __str__(self): -- return self._arch -- -- --class Cpu(object): -- architecture = Architecture.X86_64 -- -- --class Cluster(object): -- id = "2e97537b-a783-4706-af9e-75cb2e032dcd" -- name = "Default" -- cpu = Cpu() -- -- --class Configuration(object): -- def __init__(self, type=None, data=None): -- pass -- -- --class ConfigurationType(Enum): -- OVA = 'ova' -- OVF = 'ovf' -- -- def __init__(self, image): -- self._image = image -- -- def __str__(self): -- return self._image -- -- --class DiskFormat(Enum): -- COW = "cow" -- RAW = "raw" -- -- def __init__(self, image): -- self._image = image -- -- def __str__(self): -- return self._image -- -- --class DiskStatus(Enum): -- ILLEGAL = "illegal" -- LOCKED = "locked" -- OK = "ok" -- -- def __init__(self, image): -- self._image = image -- -- def __str__(self): -- return self._image -- -- --class Disk(object): -- def __init__( -- self, -- id=None, -- name=None, -- description=None, -- format=None, -- initial_size=None, -- provisioned_size=None, -- sparse=False, -- storage_domains=None -- ): -- self.id = id -- -- status = DiskStatus.OK -- -- --class ImageTransferPhase(Enum): -- CANCELLED = 'cancelled' -- FINALIZING_FAILURE = 'finalizing_failure' -- FINALIZING_SUCCESS = 'finalizing_success' -- FINISHED_FAILURE = 'finished_failure' -- FINISHED_SUCCESS = 'finished_success' -- INITIALIZING = 'initializing' -- PAUSED_SYSTEM = 'paused_system' -- PAUSED_USER = 'paused_user' -- RESUMING = 'resuming' -- TRANSFERRING = 'transferring' -- UNKNOWN = 'unknown' -- -- def __init__(self, image): -- self._image = image -- -- def __str__(self): -- return self._image -- -- --class ImageTransfer(object): -- def __init__( -- self, -- disk=None, -- host=None, -- inactivity_timeout=None, -- ): -- pass -- -- id = "e26ac8ab-7090-4d5e-95ad-e707b511a359" -- phase = ImageTransferPhase.TRANSFERRING -- transfer_url = "http://localhost:" + imageio_port + "/" -- -- --class Initialization(object): -- def __init__(self, configuration): -- pass -- -- --class JobStatus(Enum): -- ABORTED = "aborted" -- FAILED = "failed" -- FINISHED = "finished" -- STARTED = "started" -- UNKNOWN = "unknown" -- -- def __init__(self, image): -- self._image = image -- -- def __str__(self): -- return self._image -- -- --class Job(object): -- description = "Fake job" -- status = JobStatus.FINISHED -- -- --class StorageDomain(object): -- def __init__(self, name=None): -- pass -- -- id = "ba87af68-b630-4211-a73a-694c1a689405" -- name = "Storage" -- -- --class Vm(object): -- def __init__( -- self, -- cluster=None, -- initialization=None -- ): -- pass -- -- --class DataCenter(object): -- id = "31d8c73b-554b-4958-bb04-9ce97f0849e1" -- name = "DC" -- storage_domains = [StorageDomain()] -- clusters = [Cluster()] -diff --git a/tests/test-o-ovirt-upload-oo-query.sh b/tests/test-o-ovirt-upload-oo-query.sh -deleted file mode 100755 -index 771f0613..00000000 ---- a/tests/test-o-ovirt-upload-oo-query.sh -+++ /dev/null -@@ -1,41 +0,0 @@ --#!/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 -- --source ./functions.sh --set -e --set -x -- --skip_if_skipped -- --export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools" --export VIRTIO_WIN="$srcdir/../test-data/fake-virtio-win/drivers" -- --f=test-o-ovirt-upload-oo-query.actual --rm -f $f -- --$VG virt-v2v --debug-gc \ -- -o ovirt-upload -oo "?" > $f -- --grep -- "-oo ovirt-cafile" $f --grep -- "-oo ovirt-verifypeer" $f -- --rm $f -diff --git a/tests/test-o-ovirt-upload.sh b/tests/test-o-ovirt-upload.sh -deleted file mode 100755 -index c4a1fc92..00000000 ---- a/tests/test-o-ovirt-upload.sh -+++ /dev/null -@@ -1,74 +0,0 @@ --#!/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 -o ovirt-upload. --# --# These uses a test harness (see --# tests/test-o-ovirt-upload-module/ovirtsdk4) to fake responses from --# oVirt. -- --set -e --set -x -- --source ./functions.sh --set -e --set -x -- --skip_if_skipped --requires python3 --version --requires nbdkit python --version --requires test -s ../test-data/phony-guests/windows.img -- --libvirt_uri="test://$abs_top_builddir/test-data/phony-guests/guests.xml" --f=../test-data/phony-guests/windows.img -- --export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools" --export VIRTIO_WIN="$srcdir/../test-data/fake-virtio-win/drivers" --export PYTHONPATH=$srcdir/test-o-ovirt-upload-module:$PYTHONPATH -- --# Run the imageio process and get the port number. --log=test-o-ovirt-upload.webserver.log --rm -f $log --cleanup_fn rm -f $log --$srcdir/test-o-ovirt-upload-module/imageio.py >$log 2>&1 & --pid=$! --cleanup_fn kill $pid --export IMAGEIO_PORT= --for i in {1..5}; do -- IMAGEIO_PORT=$( grep "^port:" $log | awk '{print $2}' ) -- if [ -n "$IMAGEIO_PORT" ]; then break; fi -- sleep 3 --done --if [ ! -n "$IMAGEIO_PORT" ]; then -- echo "$0: imageio process did not start up" -- cat $log -- exit 1 --fi --echo IMAGEIO_PORT=$IMAGEIO_PORT -- --# Run virt-v2v -o ovirt-upload. --# --# The fake ovirtsdk4 module doesn't care about most of the options --# like -oc, -oo ovirt-cafile, -op etc. Any values may be used. --$VG virt-v2v --debug-gc -v -x \ -- -i libvirt -ic "$libvirt_uri" windows \ -- -o ovirt-upload \ -- -oc https://example.com/ovirt-engine/api \ -- -oo ovirt-cafile=/dev/null \ -- -op /dev/null \ -- -os Storage -diff --git a/tests/test-o-ovirt.ovf.expected b/tests/test-o-ovirt.ovf.expected -deleted file mode 100644 -index 4f437d88..00000000 ---- a/tests/test-o-ovirt.ovf.expected -+++ /dev/null -@@ -1,113 +0,0 @@ -- -- -- -- -- -- --
-- List of networks -- --
--
-- List of Virtual Disks -- --
-- -- windows -- 00000000-0000-0000-0000-000000000000 -- Blank -- generated by virt-v2v -- -- #DATE# -- True -- False -- -- False -- 1 -- 2 -- 1 --
-- Windows Server 2022 Phony Edition -- windows_2022 --
--
-- 1 CPU, 1024 Memory -- -- 1 virtual cpu -- Number of virtual CPU -- 1 -- 3 -- 1 -- 1 -- -- -- 1024 MB of memory -- Memory Size -- 2 -- 4 -- MegaBytes -- 1024 -- -- -- USB Controller -- 3 -- 23 -- Disabled -- -- -- Graphical Controller -- #UUID# -- 20 -- video -- 1 -- vga -- -- -- RNG Device -- #UUID# -- 0 -- rng -- virtio -- -- urandom -- -- -- -- Memory Ballooning Device -- #UUID# -- 0 -- balloon -- memballoon -- -- virtio -- -- -- -- Drive 1 -- #VOL_ID# -- 17 -- disk -- #DISK_ID#/#VOL_ID# -- 00000000-0000-0000-0000-000000000000 -- 00000000-0000-0000-0000-000000000000 -- -- 12345678-1234-1234-1234-123456789abc -- 00000000-0000-0000-0000-000000000000 -- #DATE# -- #DATE# -- #DATE# -- 1 -- -- -- #UUID# -- Ethernet adapter on default -- 10 -- 3 -- interface -- default -- eth0 -- 00:11:22:33:44:55 -- --
--
--
-diff --git a/tests/test-o-ovirt.sh b/tests/test-o-ovirt.sh -deleted file mode 100755 -index cb0d2ccf..00000000 ---- a/tests/test-o-ovirt.sh -+++ /dev/null -@@ -1,87 +0,0 @@ --#!/bin/bash - --# libguestfs virt-v2v test script --# Copyright (C) 2014 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 -o ovirt. -- --set -e -- --source ./functions.sh --set -e --set -x -- --skip_if_skipped --requires test -s ../test-data/phony-guests/windows.img -- --libvirt_uri="test://$abs_top_builddir/test-data/phony-guests/guests.xml" --f=../test-data/phony-guests/windows.img -- --export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools" --export VIRTIO_WIN="$srcdir/../test-data/fake-virtio-win/drivers" -- --d=test-o-ovirt.d --rm -rf $d --cleanup_fn rm -r $d --mkdir $d -- --# Create a dummy Export Storage Domain. --mkdir $d/12345678-1234-1234-1234-123456789abc --mkdir $d/12345678-1234-1234-1234-123456789abc/images --mkdir $d/12345678-1234-1234-1234-123456789abc/master --mkdir $d/12345678-1234-1234-1234-123456789abc/master/vms -- --# $VG - XXX Disabled because the forking used to write files in -o ovirt --# mode confuses valgrind. --virt-v2v --debug-gc -v -x \ -- -i libvirt -ic "$libvirt_uri" windows \ -- -o ovirt -os $d -- --# Test the OVF metadata was created. --test -f $d/12345678-1234-1234-1234-123456789abc/master/vms/*/*.ovf -- --pushd $d/12345678-1234-1234-1234-123456789abc/images/* -- --# Test the disk .meta was created. --test -f *.meta -- --# Test the disk file was created. --vol=`basename *.meta .meta` --test -f $vol -- --popd -- --# Compare resulting OVF --VM_ID=$(basename $(ls -1d $d/12345678-1234-1234-1234-123456789abc/master/vms/*)) --DISK_ID=$(basename $(ls -1d $d/12345678-1234-1234-1234-123456789abc/images/*)) --VOL_ID=$(basename $(ls -1d $d/12345678-1234-1234-1234-123456789abc/images/$DISK_ID/*.meta) .meta) --OVF=$(ls -1d $d/12345678-1234-1234-1234-123456789abc/master/vms/$VM_ID/$VM_ID.ovf) -- --RE_UUID='\<[0-9a-fA-F]\{8\}-[0-9a-fA-F]\{4\}-[0-9a-fA-F]\{4\}-[0-9a-fA-F]\{4\}-[0-9a-fA-F]\{12\}\>' -- --# Filter variable strings --sed -i \ -- -e "s/$DISK_ID/#DISK_ID#/g" \ -- -e "s/$VM_ID/#VM_ID#/g" \ -- -e "s/$VOL_ID/#VOL_ID#/g" \ -- -e "s/\('"$RE_UUID"'#UUID#[^<]*#DATE# $f -- --grep -- "-oo vdsm-compat" $f --grep -- "-oo vdsm-image-uuid" $f -- --rm $f -diff --git a/tests/test-o-vdsm-options.ovf.expected b/tests/test-o-vdsm-options.ovf.expected -deleted file mode 100644 -index 9f71a44e..00000000 ---- a/tests/test-o-vdsm-options.ovf.expected -+++ /dev/null -@@ -1,113 +0,0 @@ -- -- -- -- -- -- -- -- List of networks -- -- -- -- List of Virtual Disks -- -- -- -- windows -- 00000000-0000-0000-0000-000000000000 -- Blank -- generated by virt-v2v -- -- #DATE# -- True -- False -- -- False -- 1 -- 2 -- 1 -- -- Windows Server 2022 Phony Edition -- windows_2022 -- -- -- 1 CPU, 1024 Memory -- -- 1 virtual cpu -- Number of virtual CPU -- 1 -- 3 -- 1 -- 1 -- -- -- 1024 MB of memory -- Memory Size -- 2 -- 4 -- MegaBytes -- 1024 -- -- -- USB Controller -- 3 -- 23 -- Disabled -- -- -- Graphical Controller -- #UUID# -- 32768 -- video -- 1 -- vga -- -- -- RNG Device -- #UUID# -- 0 -- rng -- virtio -- -- urandom -- -- -- -- Memory Ballooning Device -- #UUID# -- 0 -- balloon -- memballoon -- -- virtio -- -- -- -- Drive 1 -- VOL -- 17 -- disk -- VOL -- 00000000-0000-0000-0000-000000000000 -- 00000000-0000-0000-0000-000000000000 -- -- 12345678-1234-1234-1234-123456789abc -- 00000000-0000-0000-0000-000000000000 -- #DATE# -- #DATE# -- #DATE# -- 1 -- -- -- #UUID# -- Ethernet adapter on default -- 10 -- 3 -- interface -- default -- eth0 -- 00:11:22:33:44:55 -- -- -- -- -diff --git a/tests/test-o-vdsm-options.sh b/tests/test-o-vdsm-options.sh -deleted file mode 100755 -index a8c5b208..00000000 ---- a/tests/test-o-vdsm-options.sh -+++ /dev/null -@@ -1,96 +0,0 @@ --#!/bin/bash - --# libguestfs virt-v2v test script --# Copyright (C) 2014-2025 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 -o vdsm options -oo vdsm-*-uuid -- --set -e --set -x -- --source ./functions.sh --set -e --set -x -- --skip_if_skipped --requires test -s ../test-data/phony-guests/windows.img -- --libvirt_uri="test://$abs_top_builddir/test-data/phony-guests/guests.xml" --f=../test-data/phony-guests/windows.img -- --export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools" --export VIRTIO_WIN="$srcdir/../test-data/fake-virtio-win/drivers" -- --d=test-o-vdsm-options.d --rm -rf $d --cleanup_fn rm -r $d --mkdir $d -- --# Create a dummy Export Storage Domain. --mkdir $d/12345678-1234-1234-1234-123456789abc --mkdir $d/12345678-1234-1234-1234-123456789abc/images --mkdir $d/12345678-1234-1234-1234-123456789abc/images/IMAGE --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 -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 \ -- -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 -- --pushd $d/12345678-1234-1234-1234-123456789abc/images/IMAGE -- --# Test the disk .meta was created. --test -f VOL.meta -- --# Test the disk file was created. --test -f VOL -- --# Test that a qcow2 file with compat=1.1 was generated. --test "$(guestfish disk-format VOL)" = "qcow2" --qemu-img info VOL | grep 'compat: 1.1' -- --popd -- --# Compare resulting OVF --OVF="$d/12345678-1234-1234-1234-123456789abc/master/vms/VM/VM.ovf" -- --RE_UUID='\<[0-9a-fA-F]\{8\}-[0-9a-fA-F]\{4\}-[0-9a-fA-F]\{4\}-[0-9a-fA-F]\{4\}-[0-9a-fA-F]\{12\}\>' -- --# Filter variable strings --sed -i \ -- -e "s/\('"$RE_UUID"'#UUID#[^<]*#DATE# true - | _ -> false in - - (* Get the conversion options. *) diff --git a/0024-remove-timeout-before-installing-virtio-win-drivers.patch b/0024-remove-timeout-before-installing-virtio-win-drivers.patch deleted file mode 100644 index 6de9818..0000000 --- a/0024-remove-timeout-before-installing-virtio-win-drivers.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 74cbf6c5f6c65736a5b5e70aa8876564948645fa Mon Sep 17 00:00:00 2001 -From: Vadim Rozenfeld -Date: Fri, 18 Jul 2025 19:31:34 +1000 -Subject: [PATCH] remove timeout before installing virtio-win drivers - -Signed-off-by: Vadim Rozenfeld -(cherry picked from commit 07192e2bf5e73dd4d3d7d3c1faa940c7a67e2d72) ---- - convert/convert_windows.ml | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml -index 2ff9bcfa..f416b3ad 100644 ---- a/convert/convert_windows.ml -+++ b/convert/convert_windows.ml -@@ -401,8 +401,6 @@ let convert (g : G.guestfs) source inspect i_firmware - echo Installing drivers from %inf_dir%\n\ - set REBOOT_PENDING=0\n\ - \n\ -- timeout /t 10 /nobreak\n\ -- \n\ - reg query \"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update\\RebootRequired\"\n\ - if %errorlevel%==0 (\n\ - echo Windows Update: Reboot required.\n\ diff --git a/0025-v2v-Fix-SELinux-relabelling.patch b/0025-v2v-Fix-SELinux-relabelling.patch deleted file mode 100644 index fb79cfb..0000000 --- a/0025-v2v-Fix-SELinux-relabelling.patch +++ /dev/null @@ -1,81 +0,0 @@ -From c674bb5596460fddea5478208dc2cec17993189e Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 13 Aug 2025 16:55:27 +0100 -Subject: [PATCH] v2v: Fix SELinux relabelling - -Update the common submodule to pick up: - - Richard W.M. Jones (3): - mlcustomize/SELinux_relabel.ml: Add comment - mlcustomize/SELinux_relabel.ml: Use new guestfs_setfiles API - mlcustomize/SELinux_relabel.ml: Relabel every mountpoint - -This allows SELinux relabelling to work for Linux guests that have a -split-/usr configuration. - -This requires libguestfs >= 1.57.1, for the new guestfs_setfiles API. - -Fixes: https://issues.redhat.com/browse/RHEL-108174 -Reported-by: Germano Veit Michel -Thanks: Ming Xie -(cherry picked from commit e4c53263d08e8aa40b0d911d470ea2930dbb27c7) ---- - common | 2 +- - m4/guestfs-libraries.m4 | 6 ++---- - 2 files changed, 3 insertions(+), 5 deletions(-) - -Submodule common 10d2b626..89f1eb2d: -diff --git a/common/mlcustomize/SELinux_relabel.ml b/common/mlcustomize/SELinux_relabel.ml -index 2f3a09bf..f1729e3f 100644 ---- a/common/mlcustomize/SELinux_relabel.ml -+++ b/common/mlcustomize/SELinux_relabel.ml -@@ -1,5 +1,5 @@ - (* virt-customize -- * Copyright (C) 2016 Red Hat Inc. -+ * Copyright (C) 2016-2025 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 -@@ -24,6 +24,10 @@ open Printf - - module G = Guestfs - -+(* XXX A lot of this code could usefully be moved into -+ * [libguestfs.git/daemon/selinux.ml]. -+ *) -+ - let rec relabel (g : G.guestfs) = - (* Is the guest using SELinux? (Otherwise this is a no-op). *) - if is_selinux_guest g then ( -@@ -109,5 +113,13 @@ and use_setfiles g = - g#copy_attributes ~all:true old_specfile specfile - ); - -+ (* Get the list of mountpoints, since setfiles does not cross -+ * filesystems (RHEL-108174). -+ *) -+ let mps = g#mountpoints () |> -+ List.map snd |> (* the list of directories *) -+ List.sort compare |> (* sort them for consistency *) -+ Array.of_list in -+ - (* Relabel everything. *) -- g#selinux_relabel ~force:true specfile "/" -+ g#setfiles ~force:true specfile mps -diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4 -index fa13e0f6..f1d5d127 100644 ---- a/m4/guestfs-libraries.m4 -+++ b/m4/guestfs-libraries.m4 -@@ -19,10 +19,8 @@ dnl Any C libraries required by virt-v2v. - - dnl Of course we need libguestfs. - dnl --dnl We need libguestfs 1.55.6 for guestfs_sh_out. --dnl We need libguestfs 1.55.12 for guestfs_btrfs_scrub_full. --dnl We need libguestfs 1.55.13 for guestfs_e2fsck FORCENO flag. --PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.55.13]) -+dnl We need libguestfs 1.57.1 for guestfs_setfiles. -+PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.57.1]) - printf "libguestfs version is "; $PKG_CONFIG --modversion libguestfs - - dnl And libnbd. diff --git a/0027-convert-Model-target-boot-device.patch b/0027-convert-Model-target-boot-device.patch deleted file mode 100644 index aa0c851..0000000 --- a/0027-convert-Model-target-boot-device.patch +++ /dev/null @@ -1,98 +0,0 @@ -From c00234c61eb2a49b2961b24672e41f15d8d734b8 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 21 Aug 2025 09:45:44 +0100 -Subject: [PATCH] convert: Model target boot device - -SeaBIOS recently changed how it works so it no longer initializes all -disks at boot. To get around this, for some Linux BIOS guests, we -will have to assign a boot order to the disks, with -for the disk that contains the GRUB bootloader, and higher boot orders -assigned to the other disks. - -As the first step, model the target boot device. - -In the current commit this is always unset (set to 'None'), so this -does nothing. - -(cherry picked from commit e512d84bc8e18734aac7659e839f32c960f6fb0a) ---- - convert/convert.ml | 8 ++++++-- - lib/types.ml | 3 ++- - lib/types.mli | 15 ++++++++++++++- - 3 files changed, 22 insertions(+), 4 deletions(-) - -diff --git a/convert/convert.ml b/convert/convert.ml -index 45d48a95..f8a35506 100644 ---- a/convert/convert.ml -+++ b/convert/convert.ml -@@ -136,7 +136,8 @@ let rec convert input_disks options source = - get_target_firmware i_firmware guestcaps source output in - - (* Create target metadata file. *) -- let target_meta = { guestcaps; target_buses; target_firmware; target_nics } in -+ let target_meta = { guestcaps; target_buses; target_nics; -+ target_firmware; target_boot_device = None } in - - (* This is a good place to dump everything we know about the guest. *) - if verbose () then debug_info source inspect target_meta mpstats; -@@ -366,7 +367,8 @@ and get_target_firmware i_firmware guestcaps source output = - * is enabled. - *) - and debug_info source inspect -- { guestcaps; target_buses; target_firmware; target_nics } -+ { guestcaps; target_buses; target_nics; -+ target_firmware; target_boot_device } - mpstats = - eprintf "info:\n"; - eprintf "%s\n" (string_of_source source); -@@ -374,6 +376,8 @@ and debug_info source inspect - eprintf "%s\n" (string_of_guestcaps guestcaps); - eprintf "%s\n" (string_of_target_buses target_buses); - eprintf "target firmware: %s\n" (string_of_target_firmware target_firmware); -+ eprintf "target boot device: %s\n" -+ (match target_boot_device with None -> "" | Some i -> string_of_int i); - eprintf "target NICs:\n"; - List.iter (fun nic -> eprintf "%s\n" (string_of_source_nic nic)) - target_nics; -diff --git a/lib/types.ml b/lib/types.ml -index 0196a3fd..bd4ab31c 100644 ---- a/lib/types.ml -+++ b/lib/types.ml -@@ -485,8 +485,9 @@ let string_of_target_buses buses = - type target_meta = { - guestcaps : guestcaps; - target_buses : target_buses; -+ target_nics : target_nics; - target_firmware : target_firmware; -- target_nics : target_nics -+ target_boot_device : int option; - } - - type root_choice = AskRoot | SingleRoot | FirstRoot | RootDev of string -diff --git a/lib/types.mli b/lib/types.mli -index b3815c8e..0c43b149 100644 ---- a/lib/types.mli -+++ b/lib/types.mli -@@ -367,8 +367,21 @@ val string_of_target_buses : target_buses -> string - type target_meta = { - guestcaps : guestcaps; - target_buses : target_buses; -+ target_nics : target_nics; -+ - target_firmware : target_firmware; -- target_nics : target_nics -+ -+ target_boot_device : int option; -+ (** The disk index of the device containing the bootloader (index -+ starting from 0). -+ -+ For libvirt guests this should usually be mapped to -+ [] for this disk, and [] -+ where N > 1 for each other disk (order does not matter -+ for the other disks). -+ -+ This is only necessary for SeaBIOS so only collected for -+ a subset of BIOS guests (RHEL-108991). *) - } - - (** {2 Command line parameters} *) diff --git a/0028-output-Add-boot-order-depending-on-target-boot-devic.patch b/0028-output-Add-boot-order-depending-on-target-boot-devic.patch deleted file mode 100644 index 074ec39..0000000 --- a/0028-output-Add-boot-order-depending-on-target-boot-devic.patch +++ /dev/null @@ -1,184 +0,0 @@ -From e7abf2e39ed17e324b54c00f2386f56152660522 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 21 Aug 2025 09:53:42 +0100 -Subject: [PATCH] output: Add boot order depending on target boot device - -If no target boot device was specified, we number them -through for each disk. - -If a target boot device was specified, then that disk has -, and the remaining disks are numbered sequentially -starting at 2. - -(cherry picked from commit 08e57a392aa5e0720e8787968a562808cb0a31fe) ---- - lib/create_ovf.ml | 19 ++++++++----------- - output/create_libvirt_xml.ml | 16 +++++++++++++++- - output/output_qemu.ml | 16 +++++++++++++--- - tests/test-cdrom.expected | 1 + - tests/test-floppy.expected | 1 + - tests/test-i-ova.xml | 1 + - 6 files changed, 39 insertions(+), 15 deletions(-) - -diff --git a/lib/create_ovf.ml b/lib/create_ovf.ml -index 0af62c88..f74ba3a7 100644 ---- a/lib/create_ovf.ml -+++ b/lib/create_ovf.ml -@@ -544,7 +544,7 @@ let create_meta_files output_alloc output_format sd_uuid image_uuids sizes = - - (* Create the OVF file. *) - let rec create_ovf source inspect -- { guestcaps; target_firmware; target_nics } -+ { guestcaps; target_nics; target_firmware; target_boot_device } - sizes - output_alloc output_format - output_name -@@ -763,7 +763,7 @@ let rec create_ovf source inspect - ] in - - (* Add disks to the OVF XML. *) -- add_disks sizes guestcaps output_alloc output_format -+ add_disks sizes guestcaps target_boot_device output_alloc output_format - sd_uuid image_uuids vol_uuids need_actual_sizes output_disks - ovf_flavour ovf; - -@@ -813,7 +813,7 @@ and get_flavoured_section ovf ovirt_path esd_path esd_path_attr = function - with Not_found -> assert false - - (* This modifies the OVF DOM, adding a section for each disk. *) --and add_disks sizes guestcaps output_alloc output_format -+and add_disks sizes guestcaps target_boot_device output_alloc output_format - sd_uuid image_uuids vol_uuids need_actual_sizes output_disks - ovf_flavour ovf = - let references = -@@ -838,14 +838,11 @@ and add_disks sizes guestcaps output_alloc output_format - (* Iterate over the disks, adding them to the OVF document. *) - List.iteri ( - fun i (size, image_uuid, vol_uuid, output_uri) -> -- (* This sets the boot order to boot the first disk first. This -- * isn't generally correct. We should copy over the boot order -- * from the source hypervisor. See long discussion in -- * https://bugzilla.redhat.com/show_bug.cgi?id=1308535 for -- * what we should be doing. (XXX) -- *) -- let is_bootable_drive = i == 0 in -- let boot_order = i+1 in -+ let is_bootable_drive, boot_order = -+ match target_boot_device with -+ | None -> i = 0, i+1 -+ | Some disk_index when disk_index = i -> true, 1 -+ | Some _ -> false, i+2 in - - let fileref = - match ovf_flavour with -diff --git a/output/create_libvirt_xml.ml b/output/create_libvirt_xml.ml -index 7ab8d34c..59f2f1f8 100644 ---- a/output/create_libvirt_xml.ml -+++ b/output/create_libvirt_xml.ml -@@ -41,7 +41,8 @@ let get_osinfo_id inspect = - None - - let create_libvirt_xml ?pool source inspect -- { guestcaps; target_buses; target_firmware; target_nics } -+ { guestcaps; target_buses; target_nics; target_firmware; -+ target_boot_device } - target_features outdisk_name output_format output_name = - (* The main body of the libvirt XML document. *) - let body = ref [] in -@@ -206,6 +207,18 @@ let create_libvirt_xml ?pool source inspect - | BusSlotDisk d -> - let outdisk = outdisk_name d.s_disk_id in - -+ let boot_order = -+ match target_boot_device with -+ | None -> -+ (* No known boot device, just number them sequentially. *) -+ i+1 -+ | Some disk_index when disk_index = i -> -+ (* For the boot disk, use order 1. *) -+ 1 -+ | Some _ -> -+ (* For the others number them sequentially starting at 2. *) -+ i+2 in -+ - e "disk" ( - [ - "type", if pool = None then "file" else "volume"; -@@ -231,6 +244,7 @@ let create_libvirt_xml ?pool source inspect - "dev", drive_prefix ^ drive_name i; - "bus", bus_name; - ] []; -+ e "boot" [ "order", string_of_int boot_order ] []; - ] - - | BusSlotRemovable { s_removable_type = CDROM } -> -diff --git a/output/output_qemu.ml b/output/output_qemu.ml -index 37371aad..dff08b66 100644 ---- a/output/output_qemu.ml -+++ b/output/output_qemu.ml -@@ -108,7 +108,8 @@ module QEMU = struct - let _, qemu_boot, output_alloc, output_format, - output_name, output_storage = options in - -- let { guestcaps; target_buses; target_firmware } = target_meta in -+ let { guestcaps; target_buses; -+ target_firmware; target_boot_device } = target_meta in - - (* Start the shell script. Write it to a temporary file - * which we rename at the end. -@@ -282,8 +283,17 @@ module QEMU = struct - * "disk_id". - *) - let outdisk = disk_path output_storage output_name disk_id in -- arg_list "-drive" [ "file=" ^ outdisk; "format=" ^ output_format; -- "if=none"; "id=" ^ backend_name; "media=disk" ] -+ let bootindex = -+ match target_boot_device with -+ | None -> disk_id+1 -+ | Some disk_index when disk_index = disk_id -> 1 -+ | Some _ -> disk_id+2 in -+ arg_list "-drive" [ "file=" ^ outdisk; -+ "format=" ^ output_format; -+ "if=none"; -+ "id=" ^ backend_name; -+ "media=disk"; -+ sprintf "bootindex=%d" bootindex ] - - and add_cdrom_backend backend_name = - (* Add a drive (back-end) for an "ide-cd" or "scsi-cd" device (front-end). -diff --git a/tests/test-cdrom.expected b/tests/test-cdrom.expected -index 17bd152d..806461e7 100644 ---- a/tests/test-cdrom.expected -+++ b/tests/test-cdrom.expected -@@ -1,6 +1,7 @@ - - - -+ - - - -diff --git a/tests/test-floppy.expected b/tests/test-floppy.expected -index a718c21f..c5bd913b 100644 ---- a/tests/test-floppy.expected -+++ b/tests/test-floppy.expected -@@ -1,6 +1,7 @@ - - - -+ - - - -diff --git a/tests/test-i-ova.xml b/tests/test-i-ova.xml -index f1d8f2e3..08b5b9f2 100644 ---- a/tests/test-i-ova.xml -+++ b/tests/test-i-ova.xml -@@ -27,6 +27,7 @@ - - - -+ - - - diff --git a/0029-convert-Detect-target-boot-device-for-Linux-guests.patch b/0029-convert-Detect-target-boot-device-for-Linux-guests.patch deleted file mode 100644 index 5905242..0000000 --- a/0029-convert-Detect-target-boot-device-for-Linux-guests.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 46af95ecd11c9eda5fd4195b62528b1eea214550 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 21 Aug 2025 10:27:41 +0100 -Subject: [PATCH] convert: Detect target boot device for Linux guests - -If the guest is Linux, try to detect the boot device, so we can set - appropriately. We do this for BIOS or UEFI here, but -this only really matters for SeaBIOS. - -Suggested-by: Gerd Hoffmann -Fixes: https://issues.redhat.com/browse/RHEL-108991 -(cherry picked from commit ca6ec6317e20a633315f783a8ba4ece3c2fc01f2) ---- - convert/convert.ml | 37 ++++++++++++++++++++++++++++++++++++- - 1 file changed, 36 insertions(+), 1 deletion(-) - -diff --git a/convert/convert.ml b/convert/convert.ml -index f8a35506..728ea5a1 100644 ---- a/convert/convert.ml -+++ b/convert/convert.ml -@@ -95,6 +95,10 @@ let rec convert input_disks options source = - let root = Choose_root.choose_root options.root_choice g in - let inspect = Mount_filesystems.mount_filesystems g root in - -+ (* Detect boot device. *) -+ message (f_"Detecting the boot device"); -+ let target_boot_device = get_target_boot_device g inspect in -+ - let mpstats = get_mpstats g in - check_guest_free_space inspect mpstats; - -@@ -137,7 +141,7 @@ let rec convert input_disks options source = - - (* Create target metadata file. *) - let target_meta = { guestcaps; target_buses; target_nics; -- target_firmware; target_boot_device = None } in -+ target_firmware; target_boot_device } in - - (* This is a good place to dump everything we know about the guest. *) - if verbose () then debug_info source inspect target_meta mpstats; -@@ -362,6 +366,37 @@ and get_target_firmware i_firmware guestcaps source output = - - target_firmware - -+and get_target_boot_device g inspect = -+ (* We only do it for Linux, as most likely Windows never(?) boots -+ * from any drive other than C:. We can revisit this decision -+ * if someone reports a bug. -+ *) -+ match inspect.i_type with -+ | "linux" -> -+ (try -+ (* In sane cases, the Grub stage1/boot.img (ie. the boot sector) is -+ * always on the same drive as /boot. So we can just find out -+ * where /boot is mounted and use that. -+ *) -+ let boot_mountpoint = List.assoc "/boot" inspect.i_mountpoints in -+ let boot_device = g#part_to_dev boot_mountpoint in -+ let boot_device = g#device_index boot_device in -+ Some boot_device -+ with -+ | Not_found -> None -+ | G.Error msg -+ (* Returned by part_to_dev if the /boot mountpoint is not -+ * a partition name. -+ *) -+ when String.find msg "device name is not a partition" >= 0 -> None -+ | G.Error msg -+ (* Returned by device_index if the /boot device is not -+ * a normal drive name (eg. /dev/mdX). -+ *) -+ when String.find msg "device not found" >= 0 -> None -+ ) -+ | _ -> None -+ - (* After conversion we dump as much information about the guest - * as we can in one place. Note this is only called when verbose - * is enabled. diff --git a/copy-patches.sh b/copy-patches.sh index 6fb8369..8a585f9 100755 --- a/copy-patches.sh +++ b/copy-patches.sh @@ -7,7 +7,7 @@ set -e # ./copy-patches.sh project=virt-v2v -rhel_version=10.1 +rhel_version=10.2 # Check we're in the right directory. if [ ! -f $project.spec ]; then diff --git a/sources b/sources index 55ec579..a005b1c 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (virt-v2v-2.8.1.tar.gz) = 70da68563e870955ca013e6d55be8f56ad65dde6f84909f06fae7ab928227a566e8949bb90e839fffce2ad4ebc604b2cfa1c5547394c8d1bd092bb95f9e6435c -SHA512 (virt-v2v-2.8.1.tar.gz.sig) = 1236dd21272c53dbafb4cd0ac4177bcf73600ff52ea8949b878793eafb1829a67880043c6e03c2d82c691d986ea8a7daa60508f4ae22345c961a939b3b6a43b0 +SHA512 (virt-v2v-2.9.5.tar.gz) = 035a9bcbae6143364bd5b0c5236520a89e1d2543e46c4fdfaba1fe0f71db09af8899e75f67669f77318340dce54bcdc4810462e97c2913ef2663f9bc0264398d +SHA512 (virt-v2v-2.9.5.tar.gz.sig) = bc7963e14432b945b688d3efc88d8df13a7a3960c949add5a4de6c128a5db9b2f769333b12e9a255e96663a932d1789de8a1253d6934610d81f376205941b3a5 diff --git a/virt-v2v.spec b/virt-v2v.spec index 8a5ca54..b52ed03 100644 --- a/virt-v2v.spec +++ b/virt-v2v.spec @@ -2,12 +2,50 @@ %global verify_tarball_signature 1 # The source directory. -%global source_directory 2.8-stable +%global source_directory 2.9-development + +%if !0%{?rhel} +# Optional features enabled in this build for Fedora. +%global with_block_driver 1 +%global with_glance 1 +%global with_ovirt 1 +%global with_xen 1 + +# libguestfs hasn't been built on i686 for a while since there is no +# kernel built for this architecture any longer and libguestfs rather +# fundamentally depends on the kernel. Therefore we must exclude this +# arch. Note there is no bug filed for this because we do not ever +# expect that libguestfs or virt-v2v will be available on i686 so +# there is nothing that needs fixing. +ExcludeArch: %{ix86} + +# Version extra string for Fedora. +%global version_extra fedora=%{fedora},release=%{release} + +%else + +# Optional features enabled in this build for RHEL. +%global with_block_driver 0 +%global with_glance 0 +%global with_ovirt 0 +%global with_xen 0 + +# Architectures where virt-v2v is shipped on RHEL: +# +# not on aarch64 because it is not useful there +# not on %%{power64} because of RHBZ#1287826 +# not on s390x because it is not useful there +ExclusiveArch: x86_64 + +# Version extra string for RHEL. +%global version_extra rhel=%{rhel},release=%{release} + +%endif Name: virt-v2v Epoch: 1 -Version: 2.8.1 -Release: 9%{?dist} +Version: 2.9.5 +Release: 1%{?dist} Summary: Convert a virtual machine to run on KVM License: GPL-2.0-or-later AND LGPL-2.0-or-later @@ -24,69 +62,39 @@ Source2: libguestfs.keyring Source3: copy-patches.sh # Patches are maintained in the following repository: -# https://github.com/libguestfs/virt-v2v/commits/rhel-10.1 +# https://github.com/libguestfs/virt-v2v/commits/rhel-10.2 # Patches. -Patch0001: 0001-docs-Move-oo-verify-server-certificate-docs-to-alpha.patch -Patch0002: 0002-input-input_vddk.ml-Fix-escaping-of-export-.-paramet.patch -Patch0003: 0003-Modify-configure_pnputil_install-script-to-check.patch -Patch0004: 0004-Update-the-common-submodule.patch -Patch0005: 0005-Ignore-ERROR_NO_MORE_ITEMS-status-from-PnPUtil.patch -Patch0006: 0006-v2v-Print-the-version-of-libnbd-nbdcopy-in-debug-out.patch -Patch0007: 0007-vddk-Remove-io-vddk-noextents-option.patch -Patch0008: 0008-curl-ssh-vddk-file-Add-nbdkit-count-filter.patch -Patch0009: 0009-o-kubevirt-Add-oo-disk-to-allow-disk-names-to-be-ove.patch -Patch0010: 0010-output-Add-optional-create-parameter.patch -Patch0011: 0011-o-kubevirt-Add-oo-create-false-to-avoid-disk-creatio.patch -Patch0012: 0012-RHEL-Fixes-for-libguestfs-winsupport.patch -Patch0013: 0013-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch -Patch0014: 0014-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch -Patch0015: 0015-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch -Patch0016: 0016-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch -Patch0017: 0017-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch -Patch0018: 0018-RHEL-Remove-input-from-Xen.patch -Patch0019: 0019-RHEL-Remove-o-glance.patch -Patch0020: 0020-RHEL-tests-Remove-btrfs-test.patch -Patch0021: 0021-RHEL-Remove-block-driver-option.patch -Patch0022: 0022-RHEL-Remove-o-ovirt-o-ovirt-upload-and-o-vdsm-modes.patch -Patch0023: 0023-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch -Patch0024: 0024-remove-timeout-before-installing-virtio-win-drivers.patch -Patch0025: 0025-v2v-Fix-SELinux-relabelling.patch -Patch0026: 0026-RHEL-10-m4-Depend-on-libguestfs-1.56.1-2.el10-for-gu.patch -Patch0027: 0027-convert-Model-target-boot-device.patch -Patch0028: 0028-output-Add-boot-order-depending-on-target-boot-devic.patch -Patch0029: 0029-convert-Detect-target-boot-device-for-Linux-guests.patch - -%if !0%{?rhel} -# libguestfs hasn't been built on i686 for a while since there is no -# kernel built for this architecture any longer and libguestfs rather -# fundamentally depends on the kernel. Therefore we must exclude this -# arch. Note there is no bug filed for this because we do not ever -# expect that libguestfs or virt-v2v will be available on i686 so -# there is nothing that needs fixing. -ExcludeArch: %{ix86} -%else -# Architectures where virt-v2v is shipped on RHEL: -# -# not on aarch64 because it is not useful there -# not on %%{power64} because of RHBZ#1287826 -# not on s390x because it is not useful there -ExclusiveArch: x86_64 -%endif +Patch0001: 0001-m4-guestfs-perl.m4-IPC-Run3-is-now-required-by-podwr.patch +Patch0002: 0002-RHEL-Fixes-for-libguestfs-winsupport.patch +Patch0003: 0003-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch +Patch0004: 0004-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch +Patch0005: 0005-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch +Patch0006: 0006-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch +Patch0007: 0007-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch +Patch0008: 0008-RHEL-tests-Remove-btrfs-test.patch +Patch0009: 0009-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch +Patch0010: 0010-RHEL-10-m4-Depend-on-libguestfs-1.56.1-2.el10-for-gu.patch BuildRequires: autoconf, automake, libtool BuildRequires: make BuildRequires: /usr/bin/pod2man +BuildRequires: perl(Pod::Usage) +BuildRequires: perl(Getopt::Long) +BuildRequires: perl(IPC::Run3) BuildRequires: gcc BuildRequires: ocaml >= 4.08 BuildRequires: libguestfs-devel >= 1:1.56.1-2.el10 BuildRequires: augeas-devel BuildRequires: bash-completion +%if !0%{?rhel} +BuildRequires: bash-completion-devel +%endif BuildRequires: file BuildRequires: gettext-devel BuildRequires: json-c-devel -BuildRequires: libnbd-devel >= 1.14 +BuildRequires: libnbd-devel >= 1.22 BuildRequires: libosinfo-devel BuildRequires: libvirt-daemon-kvm BuildRequires: libvirt-devel @@ -110,12 +118,10 @@ BuildRequires: glibc-utils BuildRequires: %{_bindir}/qemu-nbd BuildRequires: %{_bindir}/nbdcopy BuildRequires: %{_bindir}/nbdinfo +BuildRequires: nbdkit-server >= 1.44 BuildRequires: nbdkit-file-plugin BuildRequires: nbdkit-null-plugin -%if !0%{?rhel} -BuildRequires: nbdkit-python-plugin -%endif -BuildRequires: nbdkit-cow-filter >= 1.28.3-1.el9 +BuildRequires: nbdkit-cow-filter BuildRequires: mingw-srvany-redistributable >= 1.1-6 %ifarch x86_64 BuildRequires: glibc-static @@ -152,24 +158,19 @@ Requires: edk2-ovmf Requires: edk2-aarch64 %endif -%if !0%{?rhel} +%if !%{with_ovirt} Requires: /usr/bin/python3 -%else -%if 0%{?rhel} == 9 -Requires: platform-python -# Python is not needed by RHEL 10. %endif -%endif -Requires: libnbd >= 1.10 +Requires: libnbd >= 1.22 Requires: %{_bindir}/qemu-nbd Requires: %{_bindir}/nbdcopy Requires: %{_bindir}/nbdinfo -Requires: nbdkit-server >= 1.28.3-1.el9 +Requires: nbdkit-server >= 1.44 Requires: nbdkit-curl-plugin Requires: nbdkit-file-plugin Requires: nbdkit-nbd-plugin Requires: nbdkit-null-plugin -%if !0%{?rhel} +%if !%{with_ovirt} Requires: nbdkit-python-plugin %endif Requires: nbdkit-ssh-plugin @@ -177,9 +178,9 @@ Requires: nbdkit-ssh-plugin Requires: nbdkit-vddk-plugin %endif Requires: nbdkit-blocksize-filter -Requires: nbdkit-cow-filter >= 1.28.3-1.el9 +Requires: nbdkit-count-filter +Requires: nbdkit-cow-filter Requires: nbdkit-multi-conn-filter -Requires: nbdkit-noextents-filter Requires: nbdkit-rate-filter Requires: nbdkit-retry-filter @@ -245,11 +246,27 @@ autoreconf -fiv %build %configure \ -%if !0%{?rhel} - --with-extra="fedora=%{fedora},release=%{release}" \ +%if %{with_block_driver} + --enable-block-driver \ %else - --with-extra="rhel=%{rhel},release=%{release}" \ + --disable-block-driver \ %endif +%if %{with_glance} + --enable-glance \ +%else + --disable-glance \ +%endif +%if %{with_ovirt} + --enable-ovirt \ +%else + --disable-ovirt \ +%endif +%if %{with_xen} + --enable-xen \ +%else + --disable-xen \ +%endif + --with-extra="%{version_extra}" make V=1 %{?_smp_mflags} @@ -276,6 +293,23 @@ rm -f $RPM_BUILD_ROOT%{_mandir}/man1/virt-v2v-output-ovirt.1* %check +# Check that the binary runs and the features match those configured. +./run virt-v2v --version +./run virt-v2v --machine-readable | tee machine-readable.out +grep "virt-v2v-2.0" machine-readable.out +grep "input:disk" machine-readable.out +%if %{with_block_driver} +grep "block-driver-option" machine-readable.out +%endif +%if %{with_glance} +grep "output:glance" machine-readable.out +%endif +%if %{with_ovirt} +grep "output:ovirt$" machine-readable.out +grep "output:ovirt-upload" machine-readable.out +grep "output:vdsm" machine-readable.out +%endif + %ifarch x86_64 # Only run the tests with non-debug (ie. non-Rawhide) kernels. # XXX This tests for any debug kernel installed. @@ -314,15 +348,17 @@ done %{_mandir}/man1/virt-v2v.1* %{_mandir}/man1/virt-v2v-hacking.1* %{_mandir}/man1/virt-v2v-input-vmware.1* -%if !0%{?rhel} +%if %{with_xen} %{_mandir}/man1/virt-v2v-input-xen.1* +%endif +%if !0%{?rhel} %{_mandir}/man1/virt-v2v-in-place.1* %endif %{_mandir}/man1/virt-v2v-inspector.1* %{_mandir}/man1/virt-v2v-open.1* %{_mandir}/man1/virt-v2v-output-local.1* %{_mandir}/man1/virt-v2v-output-openstack.1* -%if !0%{?rhel} +%if %{with_ovirt} %{_mandir}/man1/virt-v2v-output-ovirt.1* %endif %{_mandir}/man1/virt-v2v-release-notes-1.42.1* @@ -346,7 +382,11 @@ done %changelog -* Aug 21 2025 Richard W.M. Jones - 1:2.8.1-9 +* Fri Aug 29 2025 Richard W.M. Jones - 1:2.9.5-1 +- Rebase to virt-v2v 2.9.5 + resolves: RHEL-111241 + +* Thu Aug 21 2025 Richard W.M. Jones - 1:2.8.1-9 - Rebase to virt-v2v 2.8.1 related: RHEL-81735 - Fix virt-v2v -v --install dnf5 error