Richard W.M. Jones
2016-Aug-26 17:33 UTC
[Libguestfs] [PATCH 1/2] customize: Fix firstboot scripts on Debian 6 & 7 (RHBZ#1019388).
I have only verified the fix on Debian 7. The Debian 6 guest doesn't appear to boot, I'm not sure why. The second patch contains a test suite. Rich.
Richard W.M. Jones
2016-Aug-26 17:33 UTC
[Libguestfs] [PATCH 1/2] customize: Fix firstboot scripts on Debian 6 & 7 (RHBZ#1019388).
--- customize/firstboot.ml | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/customize/firstboot.ml b/customize/firstboot.ml index 706d63c..f7213bc 100644 --- a/customize/firstboot.ml +++ b/customize/firstboot.ml @@ -97,7 +97,7 @@ StandardError=inherit WantedBy=default.target " firstboot_dir - let rec install_service (g : Guestfs.guestfs) distro + let rec install_service (g : Guestfs.guestfs) root distro major g#mkdir_p firstboot_dir; g#mkdir_p (sprintf "%s/scripts" firstboot_dir); g#write (sprintf "%s/firstboot.sh" firstboot_dir) firstboot_sh; @@ -113,7 +113,7 @@ WantedBy=default.target if g#is_dir "/etc/systemd/system" then install_systemd_service g; if g#is_dir "/etc/rc.d" || g#is_dir "/etc/init.d" then - install_sysvinit_service g distro + install_sysvinit_service g root distro major (* Install the systemd firstboot service, if not installed already. *) and install_systemd_service g @@ -144,12 +144,16 @@ WantedBy=default.target oldunitfile csum ) - and install_sysvinit_service g = function + and install_sysvinit_service g root distro major + match distro with | "fedora"|"rhel"|"centos"|"scientificlinux"|"redhat-based" -> install_sysvinit_redhat g | "opensuse"|"sles"|"suse-based" -> install_sysvinit_suse g - | "debian"|"ubuntu" -> + | "debian" -> + install_sysvinit_debian g; + if major <= 7 then try_update_rc_d g root + | "ubuntu" -> install_sysvinit_debian g | distro -> error (f_"guest type %s is not supported") distro @@ -209,6 +213,23 @@ WantedBy=default.target g#rm_f "/etc/rc2.d/S99virt-sysprep-firstboot"; g#rm_f "/etc/rc3.d/S99virt-sysprep-firstboot"; g#rm_f "/etc/rc5.d/S99virt-sysprep-firstboot" + + (* On Debian 6 & 7 you have to run: update-rc.d guestfs-firstboot defaults + * RHBZ#1019388. + *) + and try_update_rc_d g root + let guest_arch = g#inspect_get_arch root in + let guest_arch_compatible = guest_arch_compatible guest_arch in + let cmd = "update-rc.d guestfs-firstboot defaults" in + if guest_arch_compatible then + try ignore (g#sh cmd) + with Guestfs.Error msg -> + warning (f_"could not finish firstboot installation by running '%s' because the command failed: %s") + cmd msg + else ( + warning (f_"cannot finish firstboot installation by running '%s' because host cpu (%s) and guest arch (%s) are not compatible. The firstboot service may not run at boot.") + cmd Guestfs_config.host_cpu guest_arch + ) end module Windows = struct @@ -340,11 +361,12 @@ let script_count = ref 0 let add_firstboot_script (g : Guestfs.guestfs) root name content let typ = g#inspect_get_type root in let distro = g#inspect_get_distro root in + let major = g#inspect_get_major_version root in incr script_count; let filename = sprintf "%04d-%s" !script_count (sanitize_name name) in match typ, distro with | "linux", _ -> - Linux.install_service g distro; + Linux.install_service g root distro major; let filename = Linux.firstboot_dir // "scripts" // filename in g#write filename content; g#chmod 0o755 filename -- 2.7.4
Richard W.M. Jones
2016-Aug-26 17:33 UTC
[Libguestfs] [PATCH 2/2] customize: Add a slow test that firstboot works on a variety of real guests.
--- .gitignore | 1 + customize/Makefile.am | 41 ++++++++++++++- customize/test-firstboot.sh | 119 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+), 1 deletion(-) create mode 100755 customize/test-firstboot.sh diff --git a/.gitignore b/.gitignore index a97fe11..0d98fcd 100644 --- a/.gitignore +++ b/.gitignore @@ -128,6 +128,7 @@ Makefile.in /customize/customize-options.pod /customize/customize-synopsis.pod /customize/stamp-virt-customize.pod +/customize/test-firstboot-*.sh /customize/virt-customize /customize/virt-customize.1 /daemon/actions.h diff --git a/customize/Makefile.am b/customize/Makefile.am index a76b6c5..3a3e229 100644 --- a/customize/Makefile.am +++ b/customize/Makefile.am @@ -21,6 +21,7 @@ EXTRA_DIST = \ $(generator_built) \ $(SOURCES_MLI) $(SOURCES_ML) $(SOURCES_C) \ customize_main.ml \ + test-firstboot.sh \ test-virt-customize.sh \ test-virt-customize-docs.sh \ virt-customize.pod @@ -192,12 +193,50 @@ TESTS = \ if ENABLE_APPLIANCE TESTS += \ - test-virt-customize.sh + test-virt-customize.sh \ + $(SLOW_TESTS) endif check-valgrind: $(MAKE) VG="$(top_builddir)/run @VG@" check +# Slow tests of firstboot functionality in real guests. + +SLOW_TESTS = \ + $(firstboot_test_scripts) + +check-slow: + $(MAKE) check TESTS="$(SLOW_TESTS)" SLOW=1 + +firstboot_test_scripts := \ + test-firstboot-rhel-4.9.sh \ + test-firstboot-rhel-5.11.sh \ + test-firstboot-rhel-6.8.sh \ + test-firstboot-rhel-7.2.sh \ + test-firstboot-debian-7.sh \ + test-firstboot-debian-8.sh \ + test-firstboot-fedora-24.sh \ + test-firstboot-ubuntu-10.04.sh \ + test-firstboot-ubuntu-12.04.sh \ + test-firstboot-ubuntu-14.04.sh \ + test-firstboot-ubuntu-16.04.sh +# Firstboot is known-broken on RHEL 3: +# test-firstboot-rhel-3.9.sh +# Debian 6 does not work, but should do. The guest doesn't appear to +# boot, so it may be a problem with the test-firstboot.sh test script. +# test-firstboot-debian-6.sh + +test-firstboot-%.sh: + rm -f $@ $@-t + f=`echo "$@" | sed 's/test-firstboot-\(.*\).sh/\1/'`; \ + echo 'exec $$srcdir/test-firstboot.sh' "$$f" > $@-t + chmod 0755 $@-t + mv $@-t $@ + +CLEANFILES += \ + $(firstboot_test_scripts) \ + firstboot-*.img + # Dependencies. depend: .depend diff --git a/customize/test-firstboot.sh b/customize/test-firstboot.sh new file mode 100755 index 0000000..168b4f3 --- /dev/null +++ b/customize/test-firstboot.sh @@ -0,0 +1,119 @@ +#!/bin/bash - +# Test firstboot functionality. +# Copyright (C) 2016 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. + +# This slow test checks that firstboot works. +# +# NB. 'test-firstboot.sh' runs the tests, but the various tests are +# run via the 'test-firstboot-GUESTNAME.sh' wrappers. + +export LANG=C +set -e + +if [ -z "$SLOW" ]; then + echo "$0: use 'make check-slow' to run this test" + exit 77 +fi + +if [ -n "$SKIP_TEST_FIRSTBOOT_SH" ]; then + echo "$0: test skipped because environment variable is set." + exit 77 +fi + +guestname="$1" +if [ -z "$guestname" ]; then + echo "$0: guestname parameter not set, don't run this test directly." + exit 1 +fi + +disk="firstboot-$guestname.img" +rm -f "$disk" + +# If the guest doesn't exist in virt-builder, skip. This is because +# we test some RHEL guests which most users won't have access to. +if ! virt-builder -l "$guestname" >/dev/null 2>&1; then + echo "$0: test skipped because \"$guestname\" not known to virt-builder." + exit 77 +fi + +# We can only run the tests on x86_64. +if [ "$(uname -m)" != "x86_64" ]; then + echo "$0: test skipped because !x86_64." + exit 77 +fi + +# Check qemu is installed. +qemu=qemu-system-x86_64 +if ! $qemu -help >/dev/null 2>&1; then + echo "$0: test skipped because $qemu not found." + exit 77 +fi + +# Some guests need special virt-builder parameters. +# See virt-builder --notes "$guestname" +declare -a extra +case "$guestname" in + debian-6|debian-7) + extra[${#extra[*]}]='--edit' + extra[${#extra[*]}]='/etc/inittab: + s,^#([1-9].*respawn.*/sbin/getty.*),$1,' + ;; + fedora*|rhel*|centos*) + extra[${#extra[*]}]='--selinux-relabel' + ;; + *) + ;; +esac + +# Build a guest (using virt-builder) with some firstboot commands. +# +# The script currently assumes a Linux guest. We should test Windows, +# FreeBSD in future (XXX). +virt-builder "$guestname" \ + --quiet \ + -o "$disk" \ + --firstboot-command "mkdir /fb1; sleep 5" \ + --firstboot-command "touch /fb1/fb2; sleep 5" \ + --firstboot-command "poweroff" \ + "${extra[@]}" + +# Boot the guest in qemu and wait for the firstboot scripts to run. +# +# Use IDE because some ancient guests don't support anything else. +# +# Adding a network device is not strictly necessary, but makes +# the Debian 7 guest happier. +timeout 300s \ +$qemu \ + -nodefconfig \ + -display none \ + -machine accel=kvm:tcg \ + -m 2048 \ + -boot c \ + -drive file="$disk",format=raw,if=ide \ + -netdev user,id=usernet \ + -device rtl8139,netdev=usernet \ + -serial stdio ||: + +# Did the firstboot scripts run? And in the right order? We can tell +# because the directory and file are created and so the 'stat' +# commands should not fail in guestfish. +guestfish --ro -a "$disk" -i \ + statns /fb1 : \ + statns /fb1/fb2 + +rm "$disk" -- 2.7.4
Reasonably Related Threads
- [PATCH] sysprep: handle distro specific sysv scripts
- [PATCH v2 1/2] firstboot: rename systemd and sysvinit
- [PATCH 0/4] firstboot: assorted enhancements
- [PATCH 0/4] Add customization capabilities to virt-sysprep
- [PATCH] customize: Move virt-customize-related code to a separate