Laszlo Ersek
2022-Jun-13 17:01 UTC
[Libguestfs] [v2v PATCH v2 4/4] convert_linux: install the QEMU guest agent with a firstboot script
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\ + 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
Richard W.M. Jones
2022-Jun-13 17:33 UTC
[Libguestfs] [v2v PATCH v2 4/4] convert_linux: install the QEMU guest agent with a firstboot script
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.g30247aa5d201Reviewed-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