On 06/13/22 19:33, Richard W.M. Jones wrote:
> 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 <[email protected]>
>> ---
>>
>> 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?

Nope :)

The first (original) problem is that I very much dislike when we put
scripts and other verbatim texts (multiline strings) to the very left in
the OCaml source; it breaks up the otherwise great indentation of the
OCaml code. Therefore I finish the lines in the string with \ --
subsequently, OCaml throws away (from the string) the newline character,
plus *all* leading whitespace on the next line.

"All whitespace" is the second problem then; I want the compiler to
throw away those space chars that are meant for the OCaml identation,
but not those that indent the embedded shell script! Therefore, I need
to escape at least the very first space character of the shell script's
indentation.

In theory, the further escapes would not be necessary; so for example
rather than

                        \ \ while\n\

I should be able to write

                        \  while\n\

But I kind of disliked this discrepancy. It seemed more consistent to
say: "OCaml indentation (to be stripped): no escapes; shell script
indentation (not to be stripped): escaped".


> 
>> +                        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 <[email protected]>

Thanks!
Laszlo

> 
> Rich.
> 

_______________________________________________
Libguestfs mailing list
[email protected]
https://listman.redhat.com/mailman/listinfo/libguestfs

Reply via email to