From 44d1d2a53b99370749c2a9820420a27928783e55 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 13 Jun 2022 14:27:58 +0100 Subject: [PATCH] Refactor virt-customize --install, --update options in common submodule related: rhbz#2059286 --- ...-to-the-common-mlcustomize-Guest_pac.patch | 378 ++++++++++++++++++ guestfs-tools.spec | 7 +- 2 files changed, 382 insertions(+), 3 deletions(-) create mode 100644 0005-customize-rebase-to-the-common-mlcustomize-Guest_pac.patch diff --git a/0005-customize-rebase-to-the-common-mlcustomize-Guest_pac.patch b/0005-customize-rebase-to-the-common-mlcustomize-Guest_pac.patch new file mode 100644 index 0000000..f194d3d --- /dev/null +++ b/0005-customize-rebase-to-the-common-mlcustomize-Guest_pac.patch @@ -0,0 +1,378 @@ +From 2014844107fc356e945fb637ef9179bc29656864 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +Date: Mon, 6 Jun 2022 16:20:42 +0200 +Subject: [PATCH] customize: rebase to the common/mlcustomize/Guest_packages + interface + +Replace the "guest_install_command", "guest_update_command" and +"guest_uninstall_command" helper functions with the corresponding +functions from libguestfs-common, interface mlcustomize/Guest_packages. + +Add a wrapper function for (a) dealing with the exceptions uniformly +(keeping the original behavior of virt-customize), (b) centralizing the +[g#inspect_get_package_management root] call. Regarding (b), the wrapper +function fills in the last argument [package_management] of the +Guest_packages functions; thus, pass partially applied functions to the +wrapper at the original call sites. + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2028764 +Signed-off-by: Laszlo Ersek +Message-Id: <20220606142042.16680-1-lersek@redhat.com> +Reviewed-by: Richard W.M. Jones +(cherry picked from commit 7eb1ecf467e86374d72b23994d435139e302bca5) +--- + common | 2 +- + customize/customize_run.ml | 106 ++++--------------------------------- + 2 files changed, 10 insertions(+), 98 deletions(-) + +Submodule common f8de5508f..9e990f3e4: +diff --git a/common/mlcustomize/Makefile.am b/common/mlcustomize/Makefile.am +index cd7d897..4e26064 100644 +--- a/common/mlcustomize/Makefile.am ++++ b/common/mlcustomize/Makefile.am +@@ -38,10 +38,12 @@ generator_built = \ + + SOURCES_MLI = \ + firstboot.mli \ ++ guest_packages.mli \ + SELinux_relabel.mli + + SOURCES_ML = \ + firstboot.ml \ ++ guest_packages.ml \ + SELinux_relabel.ml + + if HAVE_OCAML +diff --git a/common/mlcustomize/guest_packages.ml b/common/mlcustomize/guest_packages.ml +new file mode 100644 +index 0000000..4c3c34e +--- /dev/null ++++ b/common/mlcustomize/guest_packages.ml +@@ -0,0 +1,132 @@ ++(* virt-customize ++ * Copyright (C) 2012-2021 Red Hat Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ *) ++ ++open Printf ++ ++open Common_gettext.Gettext ++open Std_utils ++ ++exception Unknown_package_manager of string ++exception Unimplemented_package_manager of string ++ ++(* Windows has package_management == "unknown". *) ++let error_unknown_package_manager flag = ++ let msg = sprintf (f_"cannot use ‘%s’ because no package manager has been \ ++ detected for this guest OS.\n\nIf this guest OS is a \ ++ common one with ordinary package management then this \ ++ may have been caused by a failure of libguestfs \ ++ inspection.\n\nFor OSes such as Windows that lack \ ++ package management, this is not possible. Try using \ ++ one of the ‘--firstboot*’ flags instead (described in \ ++ the virt-customize(1) manual).") flag in ++ raise (Unknown_package_manager msg) ++ ++let error_unimplemented_package_manager flag pm = ++ let msg = sprintf (f_"sorry, ‘%s’ with the ‘%s’ package manager has not \ ++ been implemented yet.\n\nYou can work around this by \ ++ using one of the ‘--run*’ or ‘--firstboot*’ options \ ++ instead (described in the virt-customize(1) manual).") ++ flag pm in ++ raise (Unimplemented_package_manager msg) ++ ++(* http://distrowatch.com/dwres.php?resource=package-management *) ++let install_command packages package_management = ++ let quoted_args = String.concat " " (List.map quote packages) in ++ match package_management with ++ | "apk" -> ++ sprintf " ++ apk update ++ apk add %s ++ " quoted_args ++ | "apt" -> ++ (* http://unix.stackexchange.com/questions/22820 *) ++ sprintf " ++ export DEBIAN_FRONTEND=noninteractive ++ apt_opts='-q -y -o Dpkg::Options::=--force-confnew' ++ apt-get $apt_opts update ++ apt-get $apt_opts install %s ++ " quoted_args ++ | "dnf" -> ++ sprintf "dnf%s -y install %s" ++ (if verbose () then " --verbose" else "") ++ 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 ++ ++ | "unknown" -> ++ error_unknown_package_manager (s_"--install") ++ | pm -> ++ error_unimplemented_package_manager (s_"--install") pm ++ ++let update_command package_management = ++ match package_management with ++ | "apk" -> ++ " ++ apk update ++ apk upgrade ++ " ++ | "apt" -> ++ (* http://unix.stackexchange.com/questions/22820 *) ++ " ++ export DEBIAN_FRONTEND=noninteractive ++ apt_opts='-q -y -o Dpkg::Options::=--force-confnew' ++ apt-get $apt_opts update ++ apt-get $apt_opts upgrade ++ " ++ | "dnf" -> ++ sprintf "dnf%s -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" ++ | "zypper" -> "zypper -n update -l" ++ ++ | "unknown" -> ++ error_unknown_package_manager (s_"--update") ++ | pm -> ++ error_unimplemented_package_manager (s_"--update") pm ++ ++let uninstall_command packages package_management = ++ let quoted_args = String.concat " " (List.map quote packages) in ++ match package_management with ++ | "apk" -> sprintf "apk del %s" quoted_args ++ | "apt" -> ++ (* http://unix.stackexchange.com/questions/22820 *) ++ sprintf " ++ export DEBIAN_FRONTEND=noninteractive ++ 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 ++ ++ | "unknown" -> ++ error_unknown_package_manager (s_"--uninstall") ++ | pm -> ++ error_unimplemented_package_manager (s_"--uninstall") pm +diff --git a/common/mlcustomize/guest_packages.mli b/common/mlcustomize/guest_packages.mli +new file mode 100644 +index 0000000..7504a6a +--- /dev/null ++++ b/common/mlcustomize/guest_packages.mli +@@ -0,0 +1,44 @@ ++(* virt-customize ++ * Copyright (C) 2012-2021 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. ++ *) ++ ++exception Unknown_package_manager of string ++exception Unimplemented_package_manager of string ++(** For all three functions below, [package_management] determines the package ++ management system in use by the guest; commonly it should be filled in from ++ [Guestfs.inspect_get_package_management], or the equivalent guestfs object ++ method. ++ ++ If [package_management] is unknown or unimplemented, the functions raise ++ [Unknown_package_manager "error message"] or [Unimplemented_package_manager ++ "error message"], correspondingly. *) ++ ++val install_command : string list -> string -> string ++(** [install_command packages package_management] produces a properly quoted ++ shell command string suitable for execution in the guest (directly or via a ++ Firstboot script) for installing the OS packages listed in [packages]. *) ++ ++val update_command : string -> string ++(** [update_command package_management] produces a properly quoted shell command ++ string suitable for execution in the guest (directly or via a Firstboot ++ script) for updating the OS packages that are currently installed in the ++ guest. *) ++ ++val uninstall_command : 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]. *) +diff --git a/customize/customize_run.ml b/customize/customize_run.ml +index 99b5fe14d..bb2ba2a03 100644 +--- a/customize/customize_run.ml ++++ b/customize/customize_run.ml +@@ -67,99 +67,11 @@ let run (g : G.guestfs) root (ops : ops) = + error (f_"%s: command exited with an error") display + in + +- (* http://distrowatch.com/dwres.php?resource=package-management *) +- let rec guest_install_command packages = +- let quoted_args = String.concat " " (List.map quote packages) in +- match g#inspect_get_package_management root with +- | "apk" -> +- sprintf " +- apk update +- apk add %s +- " quoted_args +- | "apt" -> +- (* http://unix.stackexchange.com/questions/22820 *) +- sprintf " +- export DEBIAN_FRONTEND=noninteractive +- apt_opts='-q -y -o Dpkg::Options::=--force-confnew' +- apt-get $apt_opts update +- apt-get $apt_opts install %s +- " quoted_args +- | "dnf" -> +- sprintf "dnf%s -y install %s" +- (if verbose () then " --verbose" else "") +- 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 +- +- | "unknown" -> +- error_unknown_package_manager (s_"--install") +- | pm -> +- error_unimplemented_package_manager (s_"--install") pm +- +- and guest_update_command () = +- match g#inspect_get_package_management root with +- | "apk" -> +- " +- apk update +- apk upgrade +- " +- | "apt" -> +- (* http://unix.stackexchange.com/questions/22820 *) +- " +- export DEBIAN_FRONTEND=noninteractive +- apt_opts='-q -y -o Dpkg::Options::=--force-confnew' +- apt-get $apt_opts update +- apt-get $apt_opts upgrade +- " +- | "dnf" -> +- sprintf "dnf%s -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" +- | "zypper" -> "zypper -n update -l" +- +- | "unknown" -> +- error_unknown_package_manager (s_"--update") +- | pm -> +- error_unimplemented_package_manager (s_"--update") pm +- +- and guest_uninstall_command packages = +- let quoted_args = String.concat " " (List.map quote packages) in +- match g#inspect_get_package_management root with +- | "apk" -> sprintf "apk del %s" quoted_args +- | "apt" -> +- (* http://unix.stackexchange.com/questions/22820 *) +- sprintf " +- export DEBIAN_FRONTEND=noninteractive +- 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 +- +- | "unknown" -> +- error_unknown_package_manager (s_"--uninstall") +- | pm -> +- error_unimplemented_package_manager (s_"--uninstall") pm +- +- (* Windows has package_management == "unknown". *) +- and error_unknown_package_manager flag = +- error (f_"cannot use ‘%s’ because no package manager has been detected for this guest OS.\n\nIf this guest OS is a common one with ordinary package management then this may have been caused by a failure of libguestfs inspection.\n\nFor OSes such as Windows that lack package management, this is not possible. Try using one of the ‘--firstboot*’ flags instead (described in the manual).") flag +- +- and error_unimplemented_package_manager flag pm = +- error (f_"sorry, ‘%s’ with the ‘%s’ package manager has not been implemented yet.\n\nYou can work around this by using one of the ‘--run*’ or ‘--firstboot*’ options instead (described in the manual).") flag pm ++ let guest_pkgs_command f = ++ try f (g#inspect_get_package_management root) with ++ | Guest_packages.Unknown_package_manager msg ++ | Guest_packages.Unimplemented_package_manager msg -> ++ error "%s" msg + in + + (* Set the random seed. *) +@@ -255,7 +167,7 @@ let run (g : G.guestfs) root (ops : ops) = + | `FirstbootPackages pkgs -> + message (f_"Installing firstboot packages: %s") + (String.concat " " pkgs); +- let cmd = guest_install_command pkgs in ++ let cmd = guest_pkgs_command (Guest_packages.install_command pkgs) in + let name = String.concat " " ("install" :: pkgs) in + Firstboot.add_firstboot_script g root name cmd + +@@ -271,7 +183,7 @@ let run (g : G.guestfs) root (ops : ops) = + + | `InstallPackages pkgs -> + message (f_"Installing packages: %s") (String.concat " " pkgs); +- let cmd = guest_install_command pkgs in ++ let cmd = guest_pkgs_command (Guest_packages.install_command pkgs) in + do_run ~display:cmd ~warn_failed_no_network:true cmd + + | `Link (target, links) -> +@@ -365,12 +277,12 @@ let run (g : G.guestfs) root (ops : ops) = + + | `UninstallPackages pkgs -> + message (f_"Uninstalling packages: %s") (String.concat " " pkgs); +- let cmd = guest_uninstall_command pkgs in ++ let cmd = guest_pkgs_command (Guest_packages.uninstall_command pkgs) in + do_run ~display:cmd cmd + + | `Update -> + message (f_"Updating packages"); +- let cmd = guest_update_command () in ++ let cmd = guest_pkgs_command Guest_packages.update_command in + do_run ~display:cmd ~warn_failed_no_network:true cmd + + | `Upload (path, dest) -> +-- +2.31.1 + diff --git a/guestfs-tools.spec b/guestfs-tools.spec index dec2421..928576c 100644 --- a/guestfs-tools.spec +++ b/guestfs-tools.spec @@ -26,7 +26,7 @@ Summary: Tools to access and modify virtual machine disk images Name: guestfs-tools Version: 1.48.2 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv2+ # Build only for architectures that have a kernel @@ -59,6 +59,7 @@ Patch0001: 0001-sysprep-remove-lvm2-s-default-system.devices-file.patch Patch0002: 0002-adopt-inversion-of-SELinux-relabeling-in-virt-custom.patch Patch0003: 0003-update-common-submodule.patch Patch0004: 0004-RHEL-Reject-use-of-libguestfs-winsupport-features-ex.patch +Patch0005: 0005-customize-rebase-to-the-common-mlcustomize-Guest_pac.patch %if 0%{patches_touch_autotools} BuildRequires: autoconf, automake, libtool, gettext-devel @@ -426,14 +427,14 @@ end %changelog -* Thu May 26 2022 Richard W.M. Jones - 1.48.2-1 +* Mon Jun 13 2022 Richard W.M. Jones - 1.48.2-2 - Rebase to guestfs-tools 1.48.2 resolves: rhbz#2059286 - Default to --selinux-relabel in various tools resolves: rhbz#2075718, rhbz#2089748 - Add lvm system.devices cleanup operation to virt-sysprep resolves: rhbz#2072493 - +- Refactor virt-customize --install, --update options in common submodule * Sat Dec 04 2021 Richard W.M. Jones - 1.46.1-6 - Clean up NetworkManager connection files