Fix missing libxslt library after VMware to OpenShift VM migration

resolves: RHEL-233944
Fix online-disks firstboot script under PowerShell Constrained Language Mode
  resolves: RHEL-210639
Fix delay during open-vm-tools removal when RHSM is unreachable
  resolves: RHEL-214049
Allow qemu-guest-agent install to skip unreachable guest repos
  resolves: RHEL-217581
Fix conversion pod crash during SELinux relabeling of large XFS filesystems
  resolves: RHEL-222316
Prevent multiple appliance launches for virtio-win.iso content
  resolves: RHEL-124850
This commit is contained in:
Srihari Parimi 2026-08-18 07:08:20 -04:00
parent 341c546f64
commit 7aef365762
6 changed files with 826 additions and 1 deletions

View File

@ -0,0 +1,38 @@
From 785e1f1782025a7fdb79a5cb663a806294a73350 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 7 Aug 2026 15:48:48 +0100
Subject: [PATCH] convert/convert_linux.ml: Use yum/dnf
clean_requirements_on_remove=False
When removing packages, use the yum or dnf option
--setopt=clean_requirements_on_remove=False (in dnf this is also known
as --no-autoremove). This removes only the named package, not
dependencies. This is in the interests of making the most minimal
change possible to the guest during conversion.
Update the common submodule:
Richard W.M. Jones (1):
mlcustomize/guest_packages.ml: Add clean_requirements_on_remove option
Fixes: https://redhat.atlassian.net/browse/RHEL-233944
(cherry picked from commit af8fbd3ea0e24cc8cfb4297724916db87a36ad04)
---
convert/convert_linux.ml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/convert/convert_linux.ml b/convert/convert_linux.ml
index 979b3581..72220830 100644
--- a/convert/convert_linux.ml
+++ b/convert/convert_linux.ml
@@ -1453,7 +1453,9 @@ fi
and uninstall_packages_nonfatal pkgs =
if pkgs <> [] then (
let cmd =
- try Guest_packages.uninstall_command pkgs inspect.i_package_management
+ try
+ Guest_packages.uninstall_command ~clean_requirements_on_remove:false
+ pkgs inspect.i_package_management
with
| Guest_packages.Unknown_package_manager msg
| Guest_packages.Unimplemented_package_manager msg ->

View File

@ -0,0 +1,455 @@
From ff3a5eace1a749e31d224ae5640f1c267c519ac5 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 8 Aug 2026 08:08:18 +0100
Subject: [PATCH] common: update submodule
Richard W.M. Jones (2):
mlcustomize/firstboot.ml: Print the version of Windows
mlcustomize/firstboot.ml: Use rem for comments (instead of '::')
(cherry picked from commit da0c19d25df40e31d6bf7c8f349478ddf616e02b)
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common f865077d..b3841fbc:
diff --git a/common/mlcustomize/SELinux_relabel.ml b/common/mlcustomize/SELinux_relabel.ml
index 62450e41..3fd97221 100644
--- a/common/mlcustomize/SELinux_relabel.ml
+++ b/common/mlcustomize/SELinux_relabel.ml
@@ -28,11 +28,11 @@ module G = Guestfs
* [libguestfs.git/daemon/selinux.ml].
*)
-let rec relabel (g : G.guestfs) =
+let rec relabel (g : G.guestfs) excludes =
(* Is the guest using SELinux? (Otherwise this is a no-op). *)
if is_selinux_guest g then (
try
- use_setfiles g;
+ use_setfiles g excludes;
(* That worked, so we don't need to autorelabel. *)
g#rm_f "/.autorelabel"
with Failure _ ->
@@ -47,7 +47,7 @@ and is_selinux_guest g =
g#is_file ~followsymlinks:true "/usr/sbin/load_policy" &&
g#is_file ~followsymlinks:true "/etc/selinux/config"
-and use_setfiles g =
+and use_setfiles g excludes =
(* Is setfiles / SELinux relabelling functionality available? *)
if not (g#feature_available [| "selinuxrelabel" |]) then
failwith "no selinux relabel feature";
@@ -121,5 +121,8 @@ and use_setfiles g =
List.sort compare |> (* sort them for consistency *)
Array.of_list in
+ (* Excludes is actually a string array, not string list. *)
+ let excludes = Array.of_list excludes in
+
(* Relabel everything. *)
- g#setfiles specfile mps
+ g#setfiles ~excludes specfile mps
diff --git a/common/mlcustomize/SELinux_relabel.mli b/common/mlcustomize/SELinux_relabel.mli
index 7b4f7ff2..5f1ae7ff 100644
--- a/common/mlcustomize/SELinux_relabel.mli
+++ b/common/mlcustomize/SELinux_relabel.mli
@@ -18,12 +18,19 @@
(** SELinux-relabel the filesystem. *)
-val relabel : Guestfs.guestfs -> unit
+val relabel : Guestfs.guestfs -> string list -> unit
(** Relabel the mounted guestfs filesystem using the current SELinux
policy that applies to the guest.
If the guest does not look like it uses SELinux, this does nothing.
+ The parameters are the guestfs handle and a list of directories
+ that may be excluded (by passing I<--selinux-relabel-exclude>
+ one or more times).
+
In case relabelling is not possible (since it is an optional
feature which requires the setfiles(8) program), instead we
- fall back to touching [/.autorelabel]. *)
+ fall back to touching [/.autorelabel].
+
+ The excludes list only affects setfiles relabelling,
+ not [/.autorelabel] since we do not control how that works. *)
diff --git a/common/mlcustomize/customize-options.pod b/common/mlcustomize/customize-options.pod
index 95767cc7..f6e68f1e 100644
--- a/common/mlcustomize/customize-options.pod
+++ b/common/mlcustomize/customize-options.pod
@@ -386,6 +386,22 @@ It cannot delete directories, only regular files.
This is a compatibility option that does nothing.
+=item B<--selinux-relabel-exclude> DIR
+
+Exclude directories from being relabelled.
+
+This advanced option lets you list directories in the guest which
+should not be relabelled, even when SELinux relabelling is
+enabled. Use this carefully, as any changes that are made
+inside these directories during customization will have incorrect
+SELinux labels, leading to potential failures later, so you must
+be sure that the directories do not need relabelling.
+
+If in doubt, do not use this option.
+
+You can pass the option multiple times, eg.
+I<--selinux-relabel-exclude=/foo> I<--selinux-relabel-exclude=/bar>
+
=item B<--ssh-inject> USER[:SELECTOR]
Inject an ssh key so the given C<USER> will be able to log in over
diff --git a/common/mlcustomize/customize-synopsis.pod b/common/mlcustomize/customize-synopsis.pod
index f5eeb69d..d6c4a280 100644
--- a/common/mlcustomize/customize-synopsis.pod
+++ b/common/mlcustomize/customize-synopsis.pod
@@ -14,4 +14,4 @@
[--truncate-recursive PATH] [--uninstall PKG,PKG..] [--update]
[--upload FILE:DEST] [--write FILE:CONTENT] [--no-logfile]
[--password-crypto md5|sha256|sha512] [--no-selinux-relabel]
- [--selinux-relabel]
+ [--selinux-relabel] [--selinux-relabel-exclude DIR]
diff --git a/common/mlcustomize/customize_cmdline.ml b/common/mlcustomize/customize_cmdline.ml
index b8eda519..24e05dc9 100644
--- a/common/mlcustomize/customize_cmdline.ml
+++ b/common/mlcustomize/customize_cmdline.ml
@@ -115,6 +115,8 @@ and flags = {
(* --no-selinux-relabel *)
selinux_relabel_ignored : bool;
(* --selinux-relabel *)
+ selinux_relabel_excludes : string list;
+ (* --selinux-relabel-exclude *)
}
type argspec = Getopt.keys * Getopt.spec * Getopt.doc
@@ -125,6 +127,7 @@ let rec argspec ?(v2v = false) () =
let password_crypto = ref None in
let no_selinux_relabel = ref false in
let selinux_relabel_ignored = ref false in
+ let selinux_relabel_excludes = ref [] in
let rec get_ops () = {
ops = List.rev !ops;
@@ -135,6 +138,7 @@ let rec argspec ?(v2v = false) () =
password_crypto = !password_crypto;
no_selinux_relabel = !no_selinux_relabel;
selinux_relabel_ignored = !selinux_relabel_ignored;
+ selinux_relabel_excludes = !selinux_relabel_excludes;
}
in
@@ -488,6 +492,15 @@ let rec argspec ?(v2v = false) () =
s_"Compatibility option doing nothing"
),
None, "This is a compatibility option that does nothing.", false;
+ (
+ [ L"selinux-relabel-exclude" ],
+ Getopt.String (
+ s_"DIR",
+ List.push_back selinux_relabel_excludes
+ ),
+ s_"Exclude directories from SELinux relabelling"
+ ),
+ Some "DIR", "Exclude directories from being relabelled.\n\nThis advanced option lets you list directories in the guest which\nshould not be relabelled, even when SELinux relabelling is\nenabled. Use this carefully, as any changes that are made\ninside these directories during customization will have incorrect\nSELinux labels, leading to potential failures later, so you must\nbe sure that the directories do not need relabelling.\n\nIf in doubt, do not use this option.\n\nYou can pass the option multiple times, eg.\nI<--selinux-relabel-exclude=/foo> I<--selinux-relabel-exclude=/bar>", false;
]
and customize_read_from_file filename =
let forbidden_commands = [
diff --git a/common/mlcustomize/customize_cmdline.mli b/common/mlcustomize/customize_cmdline.mli
index baacda9d..abe10953 100644
--- a/common/mlcustomize/customize_cmdline.mli
+++ b/common/mlcustomize/customize_cmdline.mli
@@ -107,17 +107,24 @@ and flags = {
(* --no-selinux-relabel *)
selinux_relabel_ignored : bool;
(* --selinux-relabel *)
+ selinux_relabel_excludes : string list;
+ (* --selinux-relabel-exclude *)
}
type argspec = Getopt.keys * Getopt.spec * Getopt.doc
val argspec : ?v2v:bool -> unit -> (argspec * string option * string) list * (unit -> ops)
-(** This returns a pair [(list, get_ops)].
+(** Return the argspec (a list of arguments, see {!Getopt} module)
+ with the full list of virt-customize options.
+
+ If the parameter [~v2v] is true then this excludes parameters
+ that should be excluded from virt-v2v. For example
+ [--inject-qemu-ga] is excluded from the list because virt-v2v
+ decides itself whether and how to inject the QEMU guest agent.
+
+ This returns a pair [(list, get_ops)].
[list] is a list of the command line arguments, plus some extra data.
[get_ops] is a function you can call {i after} command line parsing
which will return the actual operations specified by the user on the
- command line.
-
- If the parameter [~v2v] is true then this excludes parameters
- that should be excluded from virt-v2v. *)
\ No newline at end of file
+ command line. This can be passed to {!Customize_run.run} *)
\ No newline at end of file
diff --git a/common/mlcustomize/customize_run.ml b/common/mlcustomize/customize_run.ml
index 1baf0f3c..4878c00f 100644
--- a/common/mlcustomize/customize_run.ml
+++ b/common/mlcustomize/customize_run.ml
@@ -361,7 +361,7 @@ let run (g : G.guestfs) root (ops : ops) =
if not ops.flags.no_selinux_relabel then (
message (f_"SELinux relabelling");
- SELinux_relabel.relabel g
+ SELinux_relabel.relabel g ops.flags.selinux_relabel_excludes
);
(* Clean up the log file:
diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml
index 366beca9..74342be8 100644
--- a/common/mlcustomize/firstboot.ml
+++ b/common/mlcustomize/firstboot.ml
@@ -299,12 +299,13 @@ exit /b
:main
echo starting firstboot service
echo effective user: %%USERNAME%% domain: %%USERDOMAIN%%
+ver
if not exist "%%scripts_done%%" (
mkdir "%%scripts_done%%"
)
-:: Pick the next script to run.
+rem Pick the next script to run.
for %%%%f in ("%%scripts%%"\*.bat) do (
echo running "%%%%f"
pushd "%%scripts%%"
@@ -320,23 +321,23 @@ for %%%%f in ("%%scripts%%"\*.bat) do (
echo Script failed, will retry on next boot
)
- :: Reboot the computer only if exit code indicates.
- :: Exit code 250 means do not reboot, otherwise reboot
- :: Reboot is necessary to free any locked files which
- :: may prevent later scripts from running.
+ rem Reboot the computer only if exit code indicates.
+ rem Exit code 250 means do not reboot, otherwise reboot.
+ rem Reboot is necessary to free any locked files which
+ rem may prevent later scripts from running.
if !elvl! NEQ 250 (
shutdown /r /t 0 /y
- :: Exit the script (in case shutdown returns before rebooting).
- :: On next boot, the whole firstboot service will be called again.
-
+ rem Exit the script (in case shutdown returns before
+ rem rebooting). On next boot, the whole firstboot
+ rem service will be called again.
exit /b
)
)
-:: Fallthrough here if there are no scripts.
+rem Fallthrough here if there are no scripts.
-:: Touch a sentinel file to say we have finished.
+rem Touch a sentinel file to say we have finished.
type nul > "%%firstboot%%\complete"
echo uninstalling firstboot service
diff --git a/common/mlcustomize/guest_packages.ml b/common/mlcustomize/guest_packages.ml
index 5431811f..933b8c20 100644
--- a/common/mlcustomize/guest_packages.ml
+++ b/common/mlcustomize/guest_packages.ml
@@ -44,7 +44,13 @@ let error_unimplemented_package_manager flag pm =
flag pm in
raise (Unimplemented_package_manager msg)
-(* http://distrowatch.com/dwres.php?resource=package-management *)
+(* http://distrowatch.com/dwres.php?resource=package-management
+ *
+ * yum/dnf --setopt=skip_if_unavailable=True makes package installation
+ * a bit more reliable if an unrelated repo, or the network, are not
+ * available. The command will still fail if the package itself cannot
+ * be downloaded.
+ *)
let install_command packages package_management =
let quoted_args = String.concat " " (List.map quote packages) in
match package_management with
@@ -61,13 +67,20 @@ let install_command packages package_management =
apt-get $apt_opts update
apt-get $apt_opts install %s
" quoted_args
- | "dnf" -> sprintf "dnf -y install %s" quoted_args
- | "pisi" -> sprintf "pisi it %s" quoted_args
- | "pacman" -> sprintf "pacman -S --noconfirm %s" quoted_args
- | "urpmi" -> sprintf "urpmi %s" quoted_args
- | "xbps" -> sprintf "xbps-install -Sy %s" quoted_args
- | "yum" -> sprintf "yum -y install %s" quoted_args
- | "zypper" -> sprintf "zypper -n in -l %s" quoted_args
+ | "dnf" ->
+ sprintf "dnf --setopt=skip_if_unavailable=True -y install %s" quoted_args
+ | "pisi" ->
+ sprintf "pisi it %s" quoted_args
+ | "pacman" ->
+ sprintf "pacman -S --noconfirm %s" quoted_args
+ | "urpmi" ->
+ sprintf "urpmi %s" quoted_args
+ | "xbps" ->
+ sprintf "xbps-install -Sy %s" quoted_args
+ | "yum" ->
+ sprintf "yum --setopt=skip_if_unavailable=True -y install %s" quoted_args
+ | "zypper" ->
+ sprintf "zypper -n in -l %s" quoted_args
| "unknown" ->
error_unknown_package_manager "--install"
@@ -90,13 +103,18 @@ let update_command package_management =
apt-get $apt_opts upgrade
"
| "dnf" ->
- sprintf "dnf%s -y --best upgrade"
+ sprintf "dnf%s --setopt=skip_if_unavailable=True -y --best upgrade"
(if verbose () then " --verbose" else "")
- | "pisi" -> "pisi upgrade"
- | "pacman" -> "pacman -Su"
- | "urpmi" -> "urpmi --auto-select"
- | "xbps" -> "xbps-install -Suy"
- | "yum" -> "yum -y update"
+ | "pisi" ->
+ "pisi upgrade"
+ | "pacman" ->
+ "pacman -Su"
+ | "urpmi" ->
+ "urpmi --auto-select"
+ | "xbps" ->
+ "xbps-install -Suy"
+ | "yum" ->
+ "yum -y --setopt=skip_if_unavailable=True update"
| "zypper" -> "zypper -n dup -l"
| "unknown" ->
@@ -115,13 +133,21 @@ let uninstall_command packages package_management =
apt_opts='-q -y -o Dpkg::Options::=--force-confnew'
apt-get $apt_opts remove %s
" quoted_args
- | "dnf" -> sprintf "dnf -y remove %s" quoted_args
- | "pisi" -> sprintf "pisi rm %s" quoted_args
- | "pacman" -> sprintf "pacman -R %s" quoted_args
- | "urpmi" -> sprintf "urpme %s" quoted_args
- | "xbps" -> sprintf "xbps-remove -Sy %s" quoted_args
- | "yum" -> sprintf "yum -y remove %s" quoted_args
- | "zypper" -> sprintf "zypper -n rm %s" quoted_args
+ | "dnf" ->
+ sprintf "dnf -y --setopt=skip_if_unavailable=True --disableplugin=subscription-manager remove %s"
+ quoted_args
+ | "pisi" ->
+ sprintf "pisi rm %s" quoted_args
+ | "pacman" ->
+ sprintf "pacman -R %s" quoted_args
+ | "urpmi" ->
+ sprintf "urpme %s" quoted_args
+ | "xbps" ->
+ sprintf "xbps-remove -Sy %s" quoted_args
+ | "yum" ->
+ sprintf "yum -y --setopt=skip_if_unavailable=True remove %s" quoted_args
+ | "zypper" ->
+ sprintf "zypper -n rm %s" quoted_args
| "unknown" ->
error_unknown_package_manager "--uninstall"
diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml
index 0e5dcf05..6d7cf1a1 100644
--- a/common/mlcustomize/inject_virtio_win.ml
+++ b/common/mlcustomize/inject_virtio_win.ml
@@ -43,15 +43,6 @@ type t = {
virtio_win : string;
(** Path to the virtio-win ISO or directory. *)
- was_set : bool;
- (** If the virtio_win path was explicitly set, for example by
- the user setting an environment variable.
-
- This is used to "show intention" to use virtio-win instead
- of libosinfo. Although this behaviour is documented, IMHO it has
- always been a bad idea. We should change this in future to allow
- the user to select where they want to get drivers from. XXX *)
-
mutable block_driver_priority : string list
(** List of block drivers *)
}
@@ -74,20 +65,20 @@ type virtio_win_installed = {
let rec from_environment g root datadir =
let t = get_inspection g root in
- let virtio_win, was_set =
- try Sys.getenv "VIRTIO_WIN", true
+ let virtio_win =
+ try Sys.getenv "VIRTIO_WIN"
with Not_found ->
- try Sys.getenv "VIRTIO_WIN_DIR" (* old name for VIRTIO_WIN *), true
+ try Sys.getenv "VIRTIO_WIN_DIR" (* old name for VIRTIO_WIN *)
with Not_found ->
let iso = datadir // "virtio-win" // "virtio-win.iso" in
(if Sys.file_exists iso then iso
- else datadir // "virtio-win"), false in
+ else datadir // "virtio-win") in
- { t with virtio_win; was_set }
+ { t with virtio_win }
and from_path g root path =
let t = get_inspection g root in
- { t with virtio_win = path; was_set = true }
+ { t with virtio_win = path }
and get_inspection g root =
(* Fail hard if inspection hasn't been done or it's not a Windows
@@ -108,7 +99,7 @@ and get_inspection g root =
{ g; root;
i_arch; i_major_version; i_minor_version; i_osinfo;
i_product_variant; i_windows_current_control_set; i_windows_systemroot;
- virtio_win = ""; was_set = false;
+ virtio_win = "";
block_driver_priority = ["virtio_blk"; "vrtioblk"; "viostor"] }
let get_block_driver_priority t = t.block_driver_priority
diff --git a/common/mlcustomize/v2v-customize-options.pod b/common/mlcustomize/v2v-customize-options.pod
index 6252ffe9..fee5f984 100644
--- a/common/mlcustomize/v2v-customize-options.pod
+++ b/common/mlcustomize/v2v-customize-options.pod
@@ -332,6 +332,22 @@ It cannot delete directories, only regular files.
This is a compatibility option that does nothing.
+=item B<--selinux-relabel-exclude> DIR
+
+Exclude directories from being relabelled.
+
+This advanced option lets you list directories in the guest which
+should not be relabelled, even when SELinux relabelling is
+enabled. Use this carefully, as any changes that are made
+inside these directories during customization will have incorrect
+SELinux labels, leading to potential failures later, so you must
+be sure that the directories do not need relabelling.
+
+If in doubt, do not use this option.
+
+You can pass the option multiple times, eg.
+I<--selinux-relabel-exclude=/foo> I<--selinux-relabel-exclude=/bar>
+
=item B<--ssh-inject> USER[:SELECTOR]
Inject an ssh key so the given C<USER> will be able to log in over
diff --git a/common/mlcustomize/v2v-customize-synopsis.pod b/common/mlcustomize/v2v-customize-synopsis.pod
index 4c1a1547..5a1bc009 100644
--- a/common/mlcustomize/v2v-customize-synopsis.pod
+++ b/common/mlcustomize/v2v-customize-synopsis.pod
@@ -12,4 +12,4 @@
[--truncate-recursive PATH] [--uninstall PKG,PKG..] [--update]
[--upload FILE:DEST] [--write FILE:CONTENT] [--no-logfile]
[--password-crypto md5|sha256|sha512] [--no-selinux-relabel]
- [--selinux-relabel]
+ [--selinux-relabel] [--selinux-relabel-exclude DIR]

View File

@ -0,0 +1,38 @@
From 5f8b6a6a12809d8a72aec96b2cf7691385099aa9 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 3 Aug 2026 13:35:08 +0100
Subject: [PATCH] mlcustomize: Add new --selinux-relabel-excludes flag
https://github.com/libguestfs/libguestfs/commit/f5ad08415182cd7ecac376aad19ffaa81bec7503
Update m4/guestfs-libraries.m4 to make libguestfs 1.61.1 required.
This is for the new guestfs_setfiles 'excludes' parameter, added in:
https://github.com/libguestfs/libguestfs/commit/5364e6abbcd1ee42f23b26306225269329e7c663
Update the common submodule, bringing in:
Richard W.M. Jones (3):
mlcustomize/customize_cmdline.mli: Fix differences in generated code
mlcustomize: Update generated files
mlcustomize: Pass --selinux-relabel-excludes through to setfiles
(cherry picked from commit 4dcf8ea13ca2516005cdb64edbbb2534fe612d49)
---
m4/guestfs-libraries.m4 | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4
index 81f4ce98..14154724 100644
--- a/m4/guestfs-libraries.m4
+++ b/m4/guestfs-libraries.m4
@@ -21,7 +21,8 @@ dnl Of course we need libguestfs.
dnl
dnl We need libguestfs 1.59.2 for guestfs_xfs_info2.
dnl We need libguestfs 1.59.7 for text: and base64: prefix in LUKS funcs.
-PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.59.7])
+dnl We need libguestfs 1.61.1 for guestfs_setfiles excludes parameter.
+PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.61.1])
printf "libguestfs version is "; $PKG_CONFIG --modversion libguestfs
dnl And libnbd.

View File

@ -0,0 +1,275 @@
From 684c30d5e634e8914a82031f1979a1d73e709da9 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 11 Aug 2026 17:59:35 +0100
Subject: [PATCH] common: update submodule
Surya Gupta (1):
inject_virtio_win: use lazy handle to avoid 3 appliance launches
(cherry picked from commit c6ebad6a0d026b34483f295140edd9d98d71962a)
---
common | 2 +-
m4/guestfs-libraries.m4 | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
Submodule common b3841fbc..8d3f79ee:
diff --git a/common/mlcustomize/guest_packages.ml b/common/mlcustomize/guest_packages.ml
index 933b8c20..fba59a64 100644
--- a/common/mlcustomize/guest_packages.ml
+++ b/common/mlcustomize/guest_packages.ml
@@ -122,8 +122,14 @@ let update_command package_management =
| pm ->
error_unimplemented_package_manager "--update" pm
-let uninstall_command packages package_management =
+let uninstall_command ?clean_requirements_on_remove
+ packages package_management =
let quoted_args = String.concat " " (List.map quote packages) in
+ let dnf_yum_clean_requirements_on_remove =
+ match clean_requirements_on_remove with
+ | None -> ""
+ | Some true -> "--setopt=clean_requirements_on_remove=True"
+ | Some false -> "--setopt=clean_requirements_on_remove=False" in
match package_management with
| "apk" -> sprintf "apk del %s" quoted_args
| "apt" ->
@@ -134,8 +140,10 @@ let uninstall_command packages package_management =
apt-get $apt_opts remove %s
" quoted_args
| "dnf" ->
- sprintf "dnf -y --setopt=skip_if_unavailable=True --disableplugin=subscription-manager remove %s"
- quoted_args
+ sprintf "dnf -y --setopt=skip_if_unavailable=True %s \
+ --disableplugin=subscription-manager \
+ remove %s"
+ dnf_yum_clean_requirements_on_remove quoted_args
| "pisi" ->
sprintf "pisi rm %s" quoted_args
| "pacman" ->
@@ -145,7 +153,9 @@ let uninstall_command packages package_management =
| "xbps" ->
sprintf "xbps-remove -Sy %s" quoted_args
| "yum" ->
- sprintf "yum -y --setopt=skip_if_unavailable=True remove %s" quoted_args
+ sprintf "yum -y --setopt=skip_if_unavailable=True %s \
+ remove %s"
+ dnf_yum_clean_requirements_on_remove quoted_args
| "zypper" ->
sprintf "zypper -n rm %s" quoted_args
diff --git a/common/mlcustomize/guest_packages.mli b/common/mlcustomize/guest_packages.mli
index 5f0925a0..ee03ca88 100644
--- a/common/mlcustomize/guest_packages.mli
+++ b/common/mlcustomize/guest_packages.mli
@@ -38,7 +38,14 @@ val update_command : string -> string
script) for updating the OS packages that are currently installed in the
guest. *)
-val uninstall_command : string list -> string -> string
+val uninstall_command : ?clean_requirements_on_remove:bool ->
+ string list -> string -> string
(** [uninstall_command packages package_management] produces a properly quoted
shell command string suitable for execution in the guest (directly or via a
- Firstboot script) for uninstalling the OS packages listed in [packages]. *)
+ Firstboot script) for uninstalling the OS packages listed in [packages].
+
+ If used, [?clean_requirements_on_remove] will add
+ [--setopt=clean_requirements_on_remove=(True|False)] to the
+ command. This is used by virt-v2v to avoid removing
+ dependencies (ie behaving like "noautoremove"). It currently
+ only works for yum/dmf. *)
diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml
index 6d7cf1a1..3b52d4f0 100644
--- a/common/mlcustomize/inject_virtio_win.ml
+++ b/common/mlcustomize/inject_virtio_win.ml
@@ -40,12 +40,20 @@ type t = {
i_windows_systemroot : string;
(** Inspection data needed by this module. *)
- virtio_win : string;
- (** Path to the virtio-win ISO or directory. *)
+ virtio_win : virtio_win_t;
+ (** Source of virtio-win drivers: an ISO file or a directory. *)
mutable block_driver_priority : string list
(** List of block drivers *)
}
+and virtio_win_t = Virtio_win_iso of iso_t | Virtio_win_dir of dir_t
+and iso_t = {
+ iso_path : string;
+ g2_lazy : Guestfs.guestfs Lazy.t;
+}
+and dir_t = {
+ dir_path : string;
+}
type block_type = Virtio_blk | Virtio_SCSI | IDE
and net_type = Virtio_net | E1000 | RTL8139
@@ -62,10 +70,30 @@ type virtio_win_installed = {
virtio_1_0 : bool;
}
+let virtio_win_path = function
+ | Virtio_win_iso iso -> iso.iso_path
+ | Virtio_win_dir dir -> dir.dir_path
+
+let make_virtio_win path =
+ if is_directory path then
+ Virtio_win_dir { dir_path = path }
+ else
+ let g2_lazy = lazy (
+ try
+ let g2 = open_guestfs ~identifier:"virtio_win" () in
+ g2#add_drive_opts path ~readonly:true;
+ g2#launch ();
+ g2#mount_ro "/dev/sda" "/";
+ g2
+ with Guestfs.Error msg ->
+ error (f_"%s: cannot open virtio-win ISO file: %s") path msg
+ ) in
+ Virtio_win_iso { iso_path = path; g2_lazy }
+
let rec from_environment g root datadir =
let t = get_inspection g root in
- let virtio_win =
+ let path =
try Sys.getenv "VIRTIO_WIN"
with Not_found ->
try Sys.getenv "VIRTIO_WIN_DIR" (* old name for VIRTIO_WIN *)
@@ -74,11 +102,11 @@ let rec from_environment g root datadir =
(if Sys.file_exists iso then iso
else datadir // "virtio-win") in
- { t with virtio_win }
+ { t with virtio_win = make_virtio_win path }
and from_path g root path =
let t = get_inspection g root in
- { t with virtio_win = path }
+ { t with virtio_win = make_virtio_win path }
and get_inspection g root =
(* Fail hard if inspection hasn't been done or it's not a Windows
@@ -99,7 +127,7 @@ and get_inspection g root =
{ g; root;
i_arch; i_major_version; i_minor_version; i_osinfo;
i_product_variant; i_windows_current_control_set; i_windows_systemroot;
- virtio_win = "";
+ virtio_win = Virtio_win_dir { dir_path = "" };
block_driver_priority = ["virtio_blk"; "vrtioblk"; "viostor"] }
let get_block_driver_priority t = t.block_driver_priority
@@ -143,7 +171,7 @@ let rec inject_virtio_win_drivers ({ g } as t) reg =
if not (copy_drivers t driverdir) then (
warning (f_"there are no virtio drivers available for this version of Windows (%d.%d %s %s %s). virt-v2v looks for drivers in %s\n\nThe guest will be configured to use slower emulated devices.")
t.i_major_version t.i_minor_version t.i_arch
- t.i_product_variant t.i_osinfo t.virtio_win;
+ t.i_product_variant t.i_osinfo (virtio_win_path t.virtio_win);
{ block_driver = IDE; net_driver = RTL8139;
virtio_rng = false; virtio_balloon = false;
isa_pvpanic = false; virtio_socket = false;
@@ -165,7 +193,7 @@ let rec inject_virtio_win_drivers ({ g } as t) reg =
| None ->
warning (f_"there is no virtio block device driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
t.i_major_version t.i_minor_version
- t.i_arch t.virtio_win;
+ t.i_arch (virtio_win_path t.virtio_win);
IDE
| Some driver_name ->
@@ -196,7 +224,7 @@ let rec inject_virtio_win_drivers ({ g } as t) reg =
if not has_netkvm then (
warning (f_"there is no virtio network driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
t.i_major_version t.i_minor_version
- t.i_arch t.virtio_win;
+ t.i_arch (virtio_win_path t.virtio_win);
RTL8139
)
else
@@ -364,19 +392,20 @@ and copy_blnsvr t tempdir =
*)
and copy_from_virtio_win ({ g } as t) srcdir destdir filter missing =
let ret = ref [] in
- if is_directory t.virtio_win then (
+ (match t.virtio_win with
+ | Virtio_win_dir { dir_path } ->
debug "windows: copy_from_virtio_win: guest tools source directory %s"
- t.virtio_win;
+ dir_path;
- let dir = t.virtio_win // srcdir in
- if not (is_directory dir) then missing ()
+ let srcpath = dir_path // srcdir in
+ if not (is_directory srcpath) then missing ()
else (
- let cmd = sprintf "cd %s && find -L -type f" (quote dir) in
+ let cmd = sprintf "cd %s && find -L -type f" (quote srcpath) in
let paths = external_command cmd in
List.iter (
fun path ->
if filter path then (
- let source = dir // path in
+ let source = srcpath // path in
let target_name = String.lowercase_ascii (Filename.basename path) in
let target = destdir // target_name in
debug "windows: copying guest tools bits: 'host:%s' -> '%s'"
@@ -387,23 +416,12 @@ and copy_from_virtio_win ({ g } as t) srcdir destdir filter missing =
)
) paths
)
- )
- else if is_regular_file t.virtio_win || is_block_device t.virtio_win then (
+
+ | Virtio_win_iso { iso_path; g2_lazy } ->
debug "windows: copy_from_virtio_win: guest tools source ISO %s"
- t.virtio_win;
+ iso_path;
- let g2 =
- try
- let g2 = open_guestfs ~identifier:"virtio_win" () in
- g2#add_drive_opts t.virtio_win ~readonly:true;
- g2#launch ();
- g2
- with Guestfs.Error msg ->
- error (f_"%s: cannot open virtio-win ISO file: %s") t.virtio_win msg in
- (* Note we are mounting this as root on the *second*
- * handle, not the main handle containing the guest.
- *)
- g2#mount_ro "/dev/sda" "/";
+ let g2 = Lazy.force g2_lazy in
let srcdir = "/" ^ srcdir in
if not (g2#is_dir srcdir) then missing ()
else (
@@ -415,14 +433,13 @@ and copy_from_virtio_win ({ g } as t) srcdir destdir filter missing =
let target_name = String.lowercase_ascii (Filename.basename path) in
let target = destdir ^ "/" ^ target_name in
debug "windows: copying guest tools bits: '%s:%s' -> '%s'"
- t.virtio_win path target;
+ iso_path path target;
g#write target (g2#read_file source);
List.push_front target_name ret
)
) paths;
);
- g2#close()
);
!ret
diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4
index 14154724..250970e4 100644
--- a/m4/guestfs-libraries.m4
+++ b/m4/guestfs-libraries.m4
@@ -21,8 +21,8 @@ dnl Of course we need libguestfs.
dnl
dnl We need libguestfs 1.59.2 for guestfs_xfs_info2.
dnl We need libguestfs 1.59.7 for text: and base64: prefix in LUKS funcs.
-dnl We need libguestfs 1.61.1 for guestfs_setfiles excludes parameter.
-PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.61.1])
+dnl We need libguestfs 1.60.1 for guestfs_setfiles excludes parameter.
+PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.60.1])
printf "libguestfs version is "; $PKG_CONFIG --modversion libguestfs
dnl And libnbd.

View File

@ -18,6 +18,7 @@ fi
case `id -un` in
rjones) git_checkout=$HOME/d/$project-rhel-$rhel_version ;;
lacos) git_checkout=$HOME/src/v2v/$project ;;
sparimi) git_checkout=$HOME/rhel10.3/upstream/$project ;;
*) git_checkout=$HOME/d/$project-rhel-$rhel_version ;;
esac
if [ ! -d $git_checkout ]; then

View File

@ -45,7 +45,7 @@ ExclusiveArch: x86_64
Name: virt-v2v
Epoch: 1
Version: 2.12.0
Release: 1%{?dist}
Release: 2%{?dist}
Summary: Convert a virtual machine to run on KVM
License: GPL-2.0-or-later AND LGPL-2.0-or-later
@ -75,6 +75,10 @@ Patch0007: 0007-RHEL-tests-Remove-btrfs-test.patch
Patch0008: 0008-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch
Patch0009: 0009-RHEL-output-output.ml-Remove-reduce-memory-pressure-.patch
Patch0010: 0010-convert-windows-Fix-online-disks-script-for-PowerShe.patch
Patch0011: 0011-convert-convert_linux.ml-Use-yum-dnf-clean_requireme.patch
Patch0012: 0012-common-update-submodule.patch
Patch0013: 0013-mlcustomize-Add-new-selinux-relabel-excludes-flag.patch
Patch0014: 0014-common-update-submodule.patch
BuildRequires: autoconf, automake, libtool
BuildRequires: make
@ -380,6 +384,20 @@ done
%changelog
* Mon Aug 17 2026 Srihari Parimi <sparimi@redhat.com> - 1:2.12.0-2
- Fix missing libxslt library after VMware to OpenShift VM migration
resolves: RHEL-233944
- Fix online-disks firstboot script under PowerShell Constrained Language Mode
resolves: RHEL-210639
- Fix delay during open-vm-tools removal when RHSM is unreachable
resolves: RHEL-214049
- Allow qemu-guest-agent install to skip unreachable guest repos
resolves: RHEL-217581
- Fix conversion pod crash during SELinux relabeling of large XFS filesystems
resolves: RHEL-222316
- Prevent multiple appliance launches for virtio-win.iso content
resolves: RHEL-124850
* Tue Jul 14 2026 Richard W.M. Jones <rjones@redhat.com> - 1:2.12.0-1
- Rebase to virt-v2v 2.12.0
Synchronize spec file with Fedora