Blame SOURCES/0015-convert_linux-install-the-QEMU-guest-agent-with-a-fi.patch

c1a9fa
From e32a5ee7deb9a381ab285aba92c4de23e3c6ee2e Mon Sep 17 00:00:00 2001
c1a9fa
From: Laszlo Ersek <lersek@redhat.com>
c1a9fa
Date: Mon, 13 Jun 2022 19:01:35 +0200
c1a9fa
Subject: [PATCH] convert_linux: install the QEMU guest agent with a firstboot
c1a9fa
 script
c1a9fa
c1a9fa
Register a firstboot script, for installing the guest agent with the
c1a9fa
guest's own package manager -- that is, "Guest_packages.install_command".
c1a9fa
c1a9fa
For installing the package, network connectivity is required. Check it
c1a9fa
first with "nmcli" (also checking whether NetworkManager is running), then
c1a9fa
with "systemd-networkd-wait-online" (dependent on systemd-networkd). Note
c1a9fa
that NetworkManager and systemd-networkd are never supposed to be enabled
c1a9fa
at the same time.
c1a9fa
c1a9fa
The source domain's SELinux policy may not allow our firstboot service to
c1a9fa
execute the package's installation scripts (if any). For that reason,
c1a9fa
temporarily disable SELinux around package installation.
c1a9fa
c1a9fa
After installation, register another script for launching the agent.
c1a9fa
c1a9fa
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2028764
c1a9fa
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
c1a9fa
Message-Id: <20220613170135.12557-5-lersek@redhat.com>
c1a9fa
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
c1a9fa
(cherry picked from commit e64356896377af1ac75a03d6a4c6a4208910bbf4)
c1a9fa
---
c1a9fa
 convert/convert_linux.ml | 78 ++++++++++++++++++++++++++++++++++++++--
c1a9fa
 1 file changed, 76 insertions(+), 2 deletions(-)
c1a9fa
c1a9fa
diff --git a/convert/convert_linux.ml b/convert/convert_linux.ml
c1a9fa
index 2ddbc07a..59d143bd 100644
c1a9fa
--- a/convert/convert_linux.ml
c1a9fa
+++ b/convert/convert_linux.ml
c1a9fa
@@ -562,8 +562,82 @@ let convert (g : G.guestfs) source inspect keep_serial_console _ =
c1a9fa
               name = qga_pkg
c1a9fa
           ) inspect.i_apps in
c1a9fa
         if not has_qemu_guest_agent then
c1a9fa
-          (* FIXME -- install qemu-guest-agent here *)
c1a9fa
-          ()
c1a9fa
+          try
c1a9fa
+            let inst_cmd = Guest_packages.install_command [qga_pkg]
c1a9fa
+                             inspect.i_package_management in
c1a9fa
+
c1a9fa
+            (* Use only the portable filename character set in this. *)
c1a9fa
+            let selinux_enforcing = "/root/virt-v2v-fb-selinux-enforcing"
c1a9fa
+            and timeout = 30 in
c1a9fa
+            let fbs =
c1a9fa
+              Firstboot.add_firstboot_script g inspect.i_root
c1a9fa
+            in
c1a9fa
+            info (f_"The QEMU Guest Agent will be installed for this guest at \
c1a9fa
+                     first boot.");
c1a9fa
+
c1a9fa
+            (* Wait for the network to come online in the guest (best effort).
c1a9fa
+             *)
c1a9fa
+            fbs "wait online"
c1a9fa
+              (sprintf "#!/bin/sh\n\
c1a9fa
+                        if conn=$(nmcli networking connectivity); then\n\
c1a9fa
+                        \ \ tries=0\n\
c1a9fa
+                        \ \ while\n\
c1a9fa
+                        \ \ \ \ test $tries -lt %d &&\n\
c1a9fa
+                        \ \ \ \ test full != \"$conn\"\n\
c1a9fa
+                        \ \ do\n\
c1a9fa
+                        \ \ \ \ sleep 1\n\
c1a9fa
+                        \ \ \ \ tries=$((tries + 1))\n\
c1a9fa
+                        \ \ \ \ conn=$(nmcli networking connectivity)\n\
c1a9fa
+                        \ \ done\n\
c1a9fa
+                        elif systemctl -q is-active systemd-networkd; then\n\
c1a9fa
+                        \ \ /usr/lib/systemd/systemd-networkd-wait-online \\\n\
c1a9fa
+                        \ \ \ \ -q --timeout=%d\n\
c1a9fa
+                        fi\n" timeout timeout);
c1a9fa
+
c1a9fa
+            (* Disable SELinux temporarily around package installation. Refer to
c1a9fa
+             * <https://bugzilla.redhat.com/show_bug.cgi?id=2028764#c7> and
c1a9fa
+             * <https://bugzilla.redhat.com/show_bug.cgi?id=2028764#c8>.
c1a9fa
+             *)
c1a9fa
+            fbs "setenforce 0"
c1a9fa
+              (sprintf "#!/bin/sh\n\
c1a9fa
+                        rm -f %s\n\
c1a9fa
+                        if command -v getenforce >/dev/null &&\n\
c1a9fa
+                        \ \ test Enforcing = \"$(getenforce)\"\n\
c1a9fa
+                        then\n\
c1a9fa
+                        \ \ touch %s\n\
c1a9fa
+                        \ \ setenforce 0\n\
c1a9fa
+                        fi\n" selinux_enforcing selinux_enforcing);
c1a9fa
+            fbs "install qga" inst_cmd;
c1a9fa
+            fbs "setenforce restore"
c1a9fa
+              (sprintf "#!/bin/sh\n\
c1a9fa
+                        if test -f %s; then\n\
c1a9fa
+                        \ \ setenforce 1\n\
c1a9fa
+                        \ \ rm -f %s\n\
c1a9fa
+                        fi\n" selinux_enforcing selinux_enforcing);
c1a9fa
+
c1a9fa
+            (* Start the agent now and at subsequent boots. The following
c1a9fa
+             * commands should work on both sysvinit distros / distro versions
c1a9fa
+             * (regardless of "/etc/rc.d/" vs. "/etc/init.d/" being the scheme
c1a9fa
+             * in use) and systemd distros (via redirection to systemctl).
c1a9fa
+             *
c1a9fa
+             * On distros where the chkconfig command is redirected to
c1a9fa
+             * systemctl, the chkconfig command is likely superfluous. That's
c1a9fa
+             * because on systemd distros, the QGA package comes with such
c1a9fa
+             * runtime dependencies / triggers that the presence of the
c1a9fa
+             * virtio-serial port named "org.qemu.guest_agent.0" automatically
c1a9fa
+             * starts the agent during (second and later) boots. However, even
c1a9fa
+             * on such distros, the chkconfig command should do no harm.
c1a9fa
+             *)
c1a9fa
+            fbs "start qga"
c1a9fa
+              (sprintf "#!/bin/sh\n\
c1a9fa
+                        service %s start\n\
c1a9fa
+                        chkconfig %s on\n" qga_pkg qga_pkg)
c1a9fa
+          with
c1a9fa
+          | Guest_packages.Unknown_package_manager msg
c1a9fa
+          | Guest_packages.Unimplemented_package_manager msg ->
c1a9fa
+            warning (f_"The QEMU Guest Agent will not be installed.  The \
c1a9fa
+                        install command for package ā€˜%sā€™ could not be created: \
c1a9fa
+                        %s.") qga_pkg msg
c1a9fa
 
c1a9fa
   and configure_kernel () =
c1a9fa
     (* Previously this function would try to install kernels, but we