[Libguestfs] [v2v PATCH v2 4/4] convert_linux: install the QEMU guest agent with a firstboot script

Richard W.M. Jones rjones at redhat.com
Mon Jun 13 17:33:40 UTC 2022


On Mon, Jun 13, 2022 at 07:01:35PM +0200, Laszlo Ersek wrote:
> Register a firstboot script, for installing the guest agent with the
> guest's own package manager -- that is, "Guest_packages.install_command".
> 
> For installing the package, network connectivity is required. Check it
> first with "nmcli" (also checking whether NetworkManager is running), then
> with "systemd-networkd-wait-online" (dependent on systemd-networkd). Note
> that NetworkManager and systemd-networkd are never supposed to be enabled
> at the same time.
> 
> The source domain's SELinux policy may not allow our firstboot service to
> execute the package's installation scripts (if any). For that reason,
> temporarily disable SELinux around package installation.
> 
> After installation, register another script for launching the agent.
> 
> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2028764
> Signed-off-by: Laszlo Ersek <lersek at redhat.com>
> ---
> 
> Notes:
>     v2:
>     
>     - drop the "pkg_mgmt" helper variable; replace the call to
>       "g#inspect_get_package_management" with the already populated
>       "inspect.i_package_management" [Rich]
>     
>     - replace "sleep 60" with an open-coded "nmcli + sleep" loop, plus
>       systemd-networkd-wait-online [Rich]:
>     
>     > #!/bin/sh
>     > if conn=$(nmcli networking connectivity); then
>     >   tries=0
>     >   while
>     >     test $tries -lt 30 &&
>     >     test full != "$conn"
>     >   do
>     >     sleep 1
>     >     tries=$((tries + 1))
>     >     conn=$(nmcli networking connectivity)
>     >   done
>     > elif systemctl -q is-active systemd-networkd; then
>     >   /usr/lib/systemd/systemd-networkd-wait-online \
>     >     -q --timeout=30
>     > fi
>     
>     - refresh submodule checkout against now-upstream libguestfs-common
>       commit 9e990f3e4530 ("mlcustomize: factor out pkg
>       install/update/uninstall from guestfs-tools", 2022-06-09)
> 
>  convert/convert_linux.ml | 78 +++++++++++++++++++-
>  common                   |  2 +-
>  2 files changed, 77 insertions(+), 3 deletions(-)
> 
> diff --git a/convert/convert_linux.ml b/convert/convert_linux.ml
> index 2ddbc07aa86a..59d143bdda4b 100644
> --- a/convert/convert_linux.ml
> +++ b/convert/convert_linux.ml
> @@ -562,8 +562,82 @@ let convert (g : G.guestfs) source inspect keep_serial_console _ =
>                name = qga_pkg
>            ) inspect.i_apps in
>          if not has_qemu_guest_agent then
> -          (* FIXME -- install qemu-guest-agent here *)
> -          ()
> +          try
> +            let inst_cmd = Guest_packages.install_command [qga_pkg]
> +                             inspect.i_package_management in
> +
> +            (* Use only the portable filename character set in this. *)
> +            let selinux_enforcing = "/root/virt-v2v-fb-selinux-enforcing"
> +            and timeout = 30 in
> +            let fbs =
> +              Firstboot.add_firstboot_script g inspect.i_root
> +            in
> +            info (f_"The QEMU Guest Agent will be installed for this guest at \
> +                     first boot.");
> +
> +            (* Wait for the network to come online in the guest (best effort).
> +             *)
> +            fbs "wait online"
> +              (sprintf "#!/bin/sh\n\
> +                        if conn=$(nmcli networking connectivity); then\n\
> +                        \ \ tries=0\n\
> +                        \ \ while\n\
> +                        \ \ \ \ test $tries -lt %d &&\n\
> +                        \ \ \ \ test full != \"$conn\"\n\
> +                        \ \ do\n\
> +                        \ \ \ \ sleep 1\n\
> +                        \ \ \ \ tries=$((tries + 1))\n\
> +                        \ \ \ \ conn=$(nmcli networking connectivity)\n\
> +                        \ \ done\n\
> +                        elif systemctl -q is-active systemd-networkd; then\n\
> +                        \ \ /usr/lib/systemd/systemd-networkd-wait-online \\\n\
> +                        \ \ \ \ -q --timeout=%d\n\

I was trying to work out what the \-spaces do here.  Tabs?

> +                        fi\n" timeout timeout);
> +
> +            (* Disable SELinux temporarily around package installation. Refer to
> +             * <https://bugzilla.redhat.com/show_bug.cgi?id=2028764#c7> and
> +             * <https://bugzilla.redhat.com/show_bug.cgi?id=2028764#c8>.
> +             *)
> +            fbs "setenforce 0"
> +              (sprintf "#!/bin/sh\n\
> +                        rm -f %s\n\
> +                        if command -v getenforce >/dev/null &&\n\
> +                        \ \ test Enforcing = \"$(getenforce)\"\n\
> +                        then\n\
> +                        \ \ touch %s\n\
> +                        \ \ setenforce 0\n\
> +                        fi\n" selinux_enforcing selinux_enforcing);
> +            fbs "install qga" inst_cmd;
> +            fbs "setenforce restore"
> +              (sprintf "#!/bin/sh\n\
> +                        if test -f %s; then\n\
> +                        \ \ setenforce 1\n\
> +                        \ \ rm -f %s\n\
> +                        fi\n" selinux_enforcing selinux_enforcing);
> +
> +            (* Start the agent now and at subsequent boots. The following
> +             * commands should work on both sysvinit distros / distro versions
> +             * (regardless of "/etc/rc.d/" vs. "/etc/init.d/" being the scheme
> +             * in use) and systemd distros (via redirection to systemctl).
> +             *
> +             * On distros where the chkconfig command is redirected to
> +             * systemctl, the chkconfig command is likely superfluous. That's
> +             * because on systemd distros, the QGA package comes with such
> +             * runtime dependencies / triggers that the presence of the
> +             * virtio-serial port named "org.qemu.guest_agent.0" automatically
> +             * starts the agent during (second and later) boots. However, even
> +             * on such distros, the chkconfig command should do no harm.
> +             *)
> +            fbs "start qga"
> +              (sprintf "#!/bin/sh\n\
> +                        service %s start\n\
> +                        chkconfig %s on\n" qga_pkg qga_pkg)
> +          with
> +          | Guest_packages.Unknown_package_manager msg
> +          | Guest_packages.Unimplemented_package_manager msg ->
> +            warning (f_"The QEMU Guest Agent will not be installed.  The \
> +                        install command for package ‘%s’ could not be created: \
> +                        %s.") qga_pkg msg
>  
>    and configure_kernel () =
>      (* Previously this function would try to install kernels, but we
> diff --git a/common b/common
> index 48527b8768d7..9e990f3e4530 160000
> --- a/common
> +++ b/common
> @@ -1 +1 @@
> -Subproject commit 48527b8768d7e010552beb62500a46ad940bca9a
> +Subproject commit 9e990f3e4530df3708d176bc50e0bc68cf07d3ff
> -- 
> 2.19.1.3.g30247aa5d201

Reviewed-by: Richard W.M. Jones <rjones at redhat.com>

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
libguestfs lets you edit virtual machines.  Supports shell scripting,
bindings from many languages.  http://libguestfs.org


More information about the Libguestfs mailing list