From 9cc02ddde1e164fabfbddc8bbd3832ef9468d92d Mon Sep 17 00:00:00 2001 From: Denis 'GNUtoo' Carikli Date: Thu, 4 Jul 2024 15:26:30 +0200 Subject: [PATCH] packages: roms: Start adding automatic tests. In GNU Boot, at the time of writing, we want to advise users to use the GRUB images as they don't require users to modify their distribtions. However before the commit aec2e2f2bcf7693a05e416f9722e15b9d1854516 ("Fix bug #65663 (No support for LVM2)."), most computers using LVM2 would not boot with these images. The bug is now fixed by this commit, however since we ship a custom grub.cfg and that it is very important to get it right, it's a good idea to have some sort of automated testing for it. It uses Trisquel (instead of other FSF certified distributions) for several reasons: - Trisquel can be used by less technical users, and so it's important to make sure it works as less technical users tend to have harder times finding workaround when things break. - It's probably the GNU/Linux distribution that most current and potential GNU Boot users use. - It is also maintained by a community that welcome contributions, so if we hit some issues, we can also contribute to get it fixed (we also verified that multiple times by contributing to it). Note that we also welcome tests that reuse other distributions as well. Signed-off-by: Denis 'GNUtoo' Carikli neox: fixed typos in the commit message and fixed copyright notice Acked-by: Adrien Bourmault --- .gitignore | 6 + Makefile.am | 1 + configure.ac | 39 ++ .../gnuboot/packages/trisquel-netinst.scm | 372 ++++++++++++++++++ resources/packages/roms/boot | 1 - resources/packages/roms/download | 246 ++++++++++++ resources/packages/roms/test | 105 +++++ resources/trisquel/grub.cfg | 18 + resources/trisquel/preseed.cfg | 87 ++++ resources/trisquel/preseed.img.sha512 | 1 + .../trisquel/shutdown-after-boot.service | 22 ++ tests/lint | 2 + 12 files changed, 899 insertions(+), 1 deletion(-) create mode 100644 resources/guix/gnuboot/packages/trisquel-netinst.scm create mode 100755 resources/packages/roms/download create mode 100755 resources/packages/roms/test create mode 100644 resources/trisquel/grub.cfg create mode 100644 resources/trisquel/preseed.cfg create mode 100644 resources/trisquel/preseed.img.sha512 create mode 100644 resources/trisquel/shutdown-after-boot.service diff --git a/.gitignore b/.gitignore index 679c7c7..1006978 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,10 @@ /bin/ /bucts/ /build_error +/compile +/config.guess +/config.sh +/config.sub /coreboot/ /crossgcc/ /depthcharge/ @@ -20,6 +24,8 @@ /docs/version /grub/ /ich9utils/ +/libtool +/ltmain.sh /me_cleaner/ /memtest86plus/ /payload/ diff --git a/Makefile.am b/Makefile.am index 96d8950..dacddd3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -62,6 +62,7 @@ release: set -o pipefail ; ./build release roms | tee -a $(LOG) set -o pipefail ; ./build release website | tee -a $(LOG) set -o pipefail ; ./build release gnuboot-source | tee -a $(LOG) + set -o pipefail ; ./build test roms | tee -a $(LOG) set -o pipefail ; ./build test release | tee -a $(LOG) @echo "[ OK ] Makefile: $@ target. See $(LOG) for the log." diff --git a/configure.ac b/configure.ac index 57c9a5d..5f29cf9 100644 --- a/configure.ac +++ b/configure.ac @@ -20,6 +20,7 @@ AC_CONFIG_FILES([ resources/packages/i945-thinkpads-install-utilities/Makefile ]) +AC_SUBST([ENABLE_KVM], []) AC_SUBST([GUIX_BUILD_MAX_CORES], []) # When the Guix revision changes, the output changes, so we need to @@ -42,6 +43,16 @@ AC_SUBST([GUIX_BUILD_MAX_CORES], []) AC_SUBST([GUIX_REVISION], [v1.4.0]) +# --enable-kvm +AC_ARG_ENABLE(kvm, + [AS_HELP_STRING([--disable-kvm], + [Disable KVM virtualization when building VMs. + (default=enabled)])], + [kvm="$enableval"], + [kvm="yes"]) + +AM_CONDITIONAL( [WANT_KVM], [test x"$kvm" = x"yes"]) + # --with-guix-build-max-cores AC_ARG_WITH([guix-build-max-cores], [AS_HELP_STRING([--with-guix-build-max-cores=N], @@ -56,12 +67,36 @@ AS_IF([test x"$FOUND_GUIX" = x""], [AC_MSG_ERROR( [guix was not found in PATH ($PATH)])]) +dnl In theory we could test KVM with the 'echo quit | +dnl qemu-system-x86_64 -display none -vga none -enable-kvm -monitor +dnl stdio' command, but then we would need to require users to install +dnl qemu just for this test, because in the rest of GNU Boot we use +dnl Guix's qemu instead. The solution here could then be to use Guix +dnl here as well to do a real test, but this would require more work +dnl to make sure guix always works out of the box here too, and so +dnl help is welcome for doing that. +AS_IF([test x"$kvm" = x"yes"], + [AS_IF([test -c /dev/kvm], [], AC_MSG_ERROR([/dev/kvm not found.])) + AS_IF([test -r /dev/kvm], + [], + AC_MSG_ERROR([/dev/kvm: missing read permissions.])) + AS_IF([test -w /dev/kvm], + [], + AC_MSG_ERROR([/dev/kvm: missing write permissions.])) +]) + +dnl We want to be able to access variables like host_cpu, so we +dnl (ab)use AC_PROG_LIBTOOL to get that. +AC_PROG_LIBTOOL + # Generate a config.sh file to enable script shell to retrieve some # settings by sourcing it. printf '#!/usr/bin/env bash\n' > config.sh printf '# This file is generated by configure.ac\n' >> config.sh printf 'GUIX_BUILD_MAX_CORES=%s\n' "$GUIX_BUILD_MAX_CORES" >> config.sh printf 'GUIX_REVISION=%s\n' "$GUIX_REVISION" >> config.sh +printf 'build_cpu=%s\n' "$build_cpu" >> config.sh +printf 'kvm=%s # kvm possible values: yes, no\n' "$kvm" >> config.sh chmod +x config.sh AC_OUTPUT @@ -71,3 +106,7 @@ AS_ECHO(["Configuration options:"]) AS_IF([test x"$GUIX_BUILD_MAX_CORES" = x"0"], AS_ECHO([" GUIX_BUILD_MAX_CORES: not limited."]), AS_ECHO([" GUIX_BUILD_MAX_CORES: $GUIX_BUILD_MAX_CORES"])) +AS_IF([test x"$kvm" = x"yes"], + [AS_ECHO([" KVM: enabled"])], + [AS_ECHO([" KVM: disabled"])]) +AS_ECHO([" build_cpu: $build_cpu"]) diff --git a/resources/guix/gnuboot/packages/trisquel-netinst.scm b/resources/guix/gnuboot/packages/trisquel-netinst.scm new file mode 100644 index 0000000..ecb30d4 --- /dev/null +++ b/resources/guix/gnuboot/packages/trisquel-netinst.scm @@ -0,0 +1,372 @@ +;;; Copyright © 2024 Denis Carikli +;;; +;;; This file 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 3 of the License, or (at +;;; your option) any later version. +;;; +;;; This file 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. + +(define-module (gnuboot packages trisquel-netinst) + #:use-module (gnu packages) + #:use-module (gnu packages adns) + #:use-module (gnu packages base) + #:use-module (gnu packages bootloaders) + #:use-module (gnu packages cdrom) + #:use-module (gnu packages compression) + #:use-module (gnu packages debian) + #:use-module (gnu packages disk) + #:use-module (gnu packages gnupg) + #:use-module (gnu packages libevent) + #:use-module (gnu packages mtools) + #:use-module (gnu packages pkg-config) + #:use-module (gnu packages tls) + #:use-module (gnu packages virtualization) + #:use-module (guix build-system cmake) + #:use-module (guix build-system copy) + #:use-module (guix build-system gnu) + #:use-module (guix build-system trivial) + #:use-module (guix download) + #:use-module (guix gexp) + #:use-module (guix git-download) + #:use-module ((guix licenses) #:prefix license:) + #:use-module (guix packages) + #:use-module (guix utils) + #:use-module (rnrs base) + #:use-module (ice-9 safe-r5rs) + #:use-module (srfi srfi-19) + #:use-module (srfi srfi-26)) + +;; When running Guix through the resources/packages/ scripts, +;; '(current-filename)' returns the current filename, but in some +;; other situations it returns #f, so it's better to test for it +;; rather than fail with some cryptic message. +(assert (current-filename)) + +(define topdir + (dirname (dirname (dirname (dirname (dirname (current-filename))))))) + +(define (search-trisquel-resources-file file-name) + "Search FILE-NAME in resources. Return #f if not found." + (string-append (string-append topdir "/resources/trisquel/") file-name)) + +(define-public 0xD24DDAC9226D5BA5E9F3BED3F5DAAAF74AD4C938 + "-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBGNQMswBEACpaLnL36fWyve4zXHKrN7AjXl+g5cafQyei4j1saTLfQatdJed +ubvcscZ3yERB+R0+8xuH2UqvR0E57ohZZaTiwcUWJ3VemxCZhwKy+Xvt1ZUNxBrh +2qAJBcP0+UCskSfWb+QQ1twNIeQ8Raj+kRPGphlNmjYxF2CFOsw9c56Lz+jNyty9 +RC3Bg4l+Kcdhw23w5XBUXpHOyL6lsG317PWgEHUIQzNhXZfHL9GzwtTVQV8tVPyu +MOQIa7KDFXUEEnRN31mVLzfNHqKtTgFfP2LnSiD3LsBYsqJUtAnFGyORHgKhddRg +AKLrn1h0dEzkN+XsMaAWPrJg87ks7qXhhNz3SEI+t7dL4ozfUryRY9/8t/rXuQK+ +ffRO/63i8SaHdu1Sl8MgHsNZRFOlbYGPw73TpdJ3JvfmfPNrRcTzsU1arMML8GWs +q6/QYDTWVYBYXy0kEqJQmeb3yJRvnIdVfiAdu9fyDPY8FCTUTcsxKe88u2bgrIaY +pNdoNFXojIC9JvMUM5QakMeog+ocTrZFOyhRMKfq5KEV/IDvsx6BfQzpjvK27LgX +LcdlP9HUVb9ZkKUgMGV1trqSA7kKrkDtfw+BInReTeSEnr4jsAwwiG62kDmmA4mo +dFq1MsWTAJTvpeeK+86gYliZukt6076zPrszmDJIyJWwHCLFn1jVkn1tlQARAQAB +tFpUcmlzcXVlbCBHTlUvTGludXggQXJjaGl2ZSBBdXRvbWF0aWMgU2lnbmluZyBL +ZXkgKDExL2FyYW1vKSA8dHJpc3F1ZWwtZGV2ZWxAdHJpc3F1ZWwuaW5mbz6JAk4E +EwEKADgCGwMFCwkIBwMFFQoJCAsFFgMCAQACHgECF4AWIQTSTdrJIm1bpenzvtP1 +2qr3StTJOAUCY1AzAgAKCRD12qr3StTJOIxbD/44B7Kv+26TBW6BIiUlp1iDsvoX +yHk9yau41g6HjJR53KrFID4uszN9B+Cl+R0PjywfgC9OSSTKOjJq4/yQE00JpuF+ +HtWieshZJs8QFKLD+mZQfRVCQweqj9HZS8AFH02LYkdsXiv4LZLaNljcHEPC3Y34 +61xcg3viATgHL1ZJIPGT/vk425jQkEv9wjCjIvKsMhoE9EcqDBft9jKBC6H8LQwZ +iIYYNf28WRIW/EbutPe+0B3YOuw3PT/o/x40ySLWIJARODxBCqJ0wEC4PI7lUiLg +DGV0cUUykZz7BXKaIZIj+3wViR5zDGqIWx5TwdW2MJpDi9ove8N/3HaAc6BwQQXH +acZohOBqf/BjTKXQufVzx1sMBxB+a5zp284uICX54y/mm9tPHWcOOtl+NYj5qk4A +qn+vh433kNW622qJ8tt72kbcfaRekBnCj/A10U46TyWgZgMc7XxCc5r8slJWlhYZ +bRgbWWvkyH1s0mzbkAyNwrNa0vafcxOxO9psc7LG4mLPBqLoKKPmYY5Vgu8fdlbb +OLLFVvNhuTSX2ugkPfAp/XeWucQPJv3een1C1AWNcufhKYm1DZkYTGBeT8cbsw3T +0JnpRad+Sm2VhLcQ8PHKHUUeklVqUMjyCHo32sydo+I1MjC3QWycolljno2un9HU +TNAXG/1k2DzsqFPFjw== +=LJyh +-----END PGP PUBLIC KEY BLOCK-----") + +(define trisquel-installer-public-key + (package + (name "trisquel-installer-public-key") + (version "07-2024") + (source #f) + (build-system trivial-build-system) + (home-page "https://trisquel.info") + (arguments + (list + #:builder + #~(begin + (mkdir #$output) + (mkdir (string-append #$output "/share/")) + (mkdir (string-append #$output "/share/trisquel-installer/")) + (call-with-output-file + (string-append + #$output + "/share/trisquel-installer/" + "0xD24DDAC9226D5BA5E9F3BED3F5DAAAF74AD4C938.asc") + (lambda (port) + (format + port + #$0xD24DDAC9226D5BA5E9F3BED3F5DAAAF74AD4C938)))))) + (synopsis "Trisquel installer signing key") + (description #f) + (license #f))) ;; Public keys are not copyrightable. + +(define trisquel-netinst_11.0_amd64.iso.asc + (package + (name "trisquel-netinst-amd64-signature") + (version "11.0") + (source + (origin + (method url-fetch) + (uri + (string-append + "https://cdimage.trisquel.info/trisquel-images/" + "trisquel-netinst_11.0_amd64.iso.asc")) + (sha256 (base32 "1b46w7wnd81yw71f18ia5wfsg1ybxbn132b8psh42p4xw2g40f4q")))) + (build-system gnu-build-system) + (home-page "https://trisquel.info") + (arguments + (list + #:tests? #f ;no tests + #:phases + #~(modify-phases %standard-phases + (delete 'bootstrap) + (delete 'build) + (delete 'configure) + (delete 'patch-shebangs) + (delete 'patch-usr-bin-file) + (delete 'unpack) + (replace 'install + (lambda _ + (mkdir-p (string-append #$output "/share/trisquel-installer/")) + (copy-file + #$source + (string-append + #$output + "/share/trisquel-installer/" + "trisquel-netinst_11.0_amd64.iso.asc"))))))) + (synopsis "Trisquel installer signing key") + (description #f) + (license #f))) ;; Signatures are not copyrightable. + +;; TODO: move gpg in check +(define-public trisquel-netinst_11.0_amd64.iso + (package + (name "trisquel-netinst-amd64") + (version "11.0") + (source + (origin + (method url-fetch) + (uri + (string-append + "https://cdimage.trisquel.info/trisquel-images/" + "trisquel-netinst_11.0_amd64.iso")) + (sha256 (base32 "0rn2fk91lhmgfcl267l7f6iqqky2qd8aiwkqpflmvi9dqlgf6g70")))) + (build-system gnu-build-system) + (native-inputs (list + gnupg + trisquel-netinst_11.0_amd64.iso.asc + trisquel-installer-public-key)) + (arguments + (list + #:tests? #f ;no tests + #:phases + #~(modify-phases %standard-phases + (delete 'bootstrap) + (delete 'build) + (delete 'configure) + (delete 'patch-shebangs) + (delete 'patch-usr-bin-file) + (delete 'unpack) + (replace 'install + (lambda _ + (mkdir ".gnupg") + (invoke + "gpg" + "--homedir" ".gnupg" + "--import" (string-append + #$trisquel-installer-public-key + "/share/trisquel-installer/" + "0xD24DDAC9226D5BA5E9F3BED3F5DAAAF74AD4C938.asc")) + (invoke + "gpg" + "--homedir" ".gnupg" + "--verify" + (string-append + #$trisquel-netinst_11.0_amd64.iso.asc + "/share/trisquel-installer/" + "trisquel-netinst_11.0_amd64.iso.asc") + #$source) + (mkdir-p (string-append #$output "/share/trisquel-installer/")) + (copy-file + #$source + (string-append + #$output + "/share/trisquel-installer/" + "trisquel-netinst_11.0_amd64.iso"))))))) + (synopsis + "Trisquel netinstall image") + (description + "Trisquel netinstall image. It supports (mostly) automatic installation +through preseeding, though the user is expected to manually select the +right boot menu entry and to enter the URI to the preseed file +manually.") + (home-page "https://trisquel.info") + (license (license:fsdg-compatible + "https://www.gnu.org/distros/free-distros.html")))) + +(define-public gnuboot-trisquel-preseed.img + (package + (name "gnuboot-trisquel-preseed.img") + (version "07-2024") + (source #f) + (home-page "https://gnu.org/software/gnuboot") + (build-system gnu-build-system) + (native-inputs (list + coreutils + dosfstools + mtools)) + (arguments + (list + #:phases + #~(modify-phases %standard-phases + (delete 'bootstrap) + (delete 'configure) + (delete 'patch-shebangs) + (delete 'patch-usr-bin-file) + (replace + 'unpack + (lambda _ + (setenv "TZ" "UTC0") + (copy-file + #$(local-file (search-trisquel-resources-file "preseed.cfg")) + "preseed.cfg") + (invoke "touch" "-d" "@0" "preseed.cfg") + (copy-file + #$(local-file + (search-trisquel-resources-file "shutdown-after-boot.service")) + "shutdown-after-boot.service") + (invoke "touch" "-d" "@0" "shutdown-after-boot.service") + (copy-file + #$(local-file + (search-trisquel-resources-file "preseed.img.sha512")) + "preseed.img.sha512"))) + (replace + 'build + (lambda _ + (invoke "dd" "if=/dev/zero" "of=preseed.img" "count=2048") + (invoke "mkfs.vfat" + "-a" + "--mbr=y" + "-n" "MEDIA" + "--invariant" + "preseed.img") + (invoke "mcopy" + "-i" "preseed.img" + "-m" + "preseed.cfg" + "::/preseed.cfg") + (invoke "mcopy" + "-i" "preseed.img" + "-m" + "shutdown-after-boot.service" + "::/shutdown-after-boot.service"))) + (replace + 'install + (lambda _ + (mkdir-p (string-append #$output "/share/trisquel-installer/")) + (install-file "preseed.img" (string-append #$output "/share/trisquel-installer/")))) + (replace + 'check + (lambda _ + (invoke "sha512sum" "-c" "preseed.img.sha512")))))) + (synopsis "Preseed configuration as a FAT12 filesystem.") + (description "FAT12 filesystem with inside a preseed.cfg file for automatic install, +as well as dependencies for the preseed.cfg, such as the files +preseed.cfg includes in the target rootfs.") + (license license:gpl3+))) ;; License of GNU Boot. + +;; TODO: make it reproducible +(define-public gnuboot-trisquel-grub.img + (package + (name "gnuboot-trisquel-grub.img") + (version "07-2024") + (source #f) + (home-page "https://gnu.org/software/gnuboot") + (build-system gnu-build-system) + (native-inputs (list + grub + trisquel-netinst_11.0_amd64.iso + xorriso)) + (arguments + (list + #:tests? #f ;no tests + #:phases + #~(modify-phases %standard-phases + (delete 'bootstrap) + (delete 'configure) + (delete 'patch-shebangs) + (delete 'patch-usr-bin-file) + (replace + 'unpack + (lambda _ + (setenv "TZ" "UTC0") + (mkdir-p "grub/boot/grub/") + (invoke + "xorriso" + "-osirrox" "on" + "-indev" (string-append + #$trisquel-netinst_11.0_amd64.iso + "/share/trisquel-installer/" + "trisquel-netinst_11.0_amd64.iso") + "-extract" "/linux" "grub/boot/linux") + (invoke "chmod" "770" "grub/boot/linux") + (invoke "touch" "-d" "@0" "grub/boot/linux") + (invoke + "xorriso" + "-osirrox" "on" + "-indev" (string-append + #$trisquel-netinst_11.0_amd64.iso + "/share/trisquel-installer/" + "trisquel-netinst_11.0_amd64.iso") + "-extract" "/initrd.gz" "grub/boot/initrd.gz") + (invoke "chmod" "770" "grub/boot/initrd.gz") + (invoke "touch" "-d" "@0" "grub/boot/initrd.gz") + (copy-file + #$(local-file (search-trisquel-resources-file "grub.cfg")) + "grub/boot/grub/grub.cfg") + (invoke "touch" "-d" "@0" "grub/boot/grub/grub.cfg"))) + (replace + 'build + (lambda _ + ;; From Guix 1.4.0 in gnu/build/image.scm: + ;; 'grub-mkrescue' calls out to mtools programs to create + ;; 'efi.img', a FAT file system image, and mtools honors + ;; SOURCE_DATE_EPOCH for the mtime of those files. The + ;; epoch for FAT is Jan. 1st 1980, not 1970, so choose + ;; that. + (setenv "SOURCE_DATE_EPOCH" "315532800") + ;; TODO, replace "315532800" by the function below + ;; (number->string + ;; (time-second + ;; (date->time-utc (make-date 0 0 0 0 1 1 1980 0)))) + (setenv "GRUB_FAT_SERIAL_NUMBER" "2e24ec82") + (invoke "grub-mkrescue" "-o" "grub.img" "grub"))) + (replace + 'install + (lambda _ + (mkdir-p (string-append #$output "/share/trisquel-installer/")) + (install-file + "grub.img" + (string-append #$output "/share/trisquel-installer/"))))))) + (synopsis "Bootable netinstall that is meant to be used with a preseed image.") + (description "To produce a netinstall image that works with preseed, we use +grub, a custom grub.cfg and the kernel and initramfs extracted from the trisquel +official netinstall. This enables us to more easily understand how it works +and modify it than if we had to modify or rebuild an existing netinstall +image.") + (license license:gpl3+))) ;; License of GRUB and GNU Boot. + +(list gnuboot-trisquel-grub.img + gnuboot-trisquel-preseed.img) diff --git a/resources/packages/roms/boot b/resources/packages/roms/boot index e79a667..35f003a 100755 --- a/resources/packages/roms/boot +++ b/resources/packages/roms/boot @@ -107,4 +107,3 @@ fi printf "\n\nDone! Your ROMs are in bin/\n\n" - diff --git a/resources/packages/roms/download b/resources/packages/roms/download new file mode 100755 index 0000000..cea77df --- /dev/null +++ b/resources/packages/roms/download @@ -0,0 +1,246 @@ +#!/usr/bin/env bash +# Copyright (C) 2023-2024 Denis 'GNUtoo' Carikli +# +# 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 3 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, see . +set -e + +topdir="$(dirname "$(dirname "$(dirname "$(dirname "$0")")")")" + +. "${topdir}"/resources/scripts/misc/sysexits.sh + +usage() +{ + progname="$1" + + printf "Usage:\n" + printf "\t%s # %s.\n" \ + "${progname}" \ + "Download all the files required for offline tests" + printf "\t%s %s # %s.\n" \ + "${progname}" \ + "trisquel-netinst_11.0_amd64.iso" \ + "Get the path of trisquel-netinst_11.0_amd64.iso" + printf "\t%s %s # %s.\n" \ + "${progname}" \ + "preseed.img" \ + "Get the path of the pressed.img image" + printf "\t%s %s # %s.\n" \ + "${progname}" \ + "grub.img" \ + "Get the path of the grub.img image" + printf "\t%s <-h|--help> # %s.\n" \ + "${progname}" \ + "Display this help and exit" + printf "\n" +} + +build_trisquel_netinst_x86_64() +{ + source "${topdir}"/config.sh + source "${topdir}"/resources/scripts/misc/guix.sh + source_guix_profile + + # The trisquel-netinst_11.0_amd64.iso package is architecture + # independent. + guix time-machine \ + --commit=${GUIX_REVISION} -- \ + build \ + -L "${topdir}"/resources/guix/ \ + -L "${topdir}"/resources/guix/gnuboot/patches/ \ + --system=i686-linux \ + trisquel-netinst-amd64 +} + +return_trisquel_netinst_x86_64_iso() +{ + iso_install_path="share/trisquel-installer/trisquel-netinst_11.0_amd64.iso" + iso_path="$(build_trisquel_netinst_x86_64)${iso_install_path}" + echo "${iso_path}" +} + +build_guix_qemu_x86_64() +{ + source "${topdir}"/config.sh + source "${topdir}"/resources/scripts/misc/guix.sh + source_guix_profile + + # There are two qemu packages: qemu and qemu-minimal. For now qemu + # was used as (1) it enabled easier testing as with some extra we + # can run the distributions in a graphical environment and (2) it + # also had extra architectures like ARM. However if qemu-minimal + # also works for all the architectures currently supported by GNU + # Boot (at the time of writing this is i686 and x86_64), it might + # be better to use it as it has way less dependencies (and so this + # reduces the download time a lot). + guix time-machine \ + --commit=${GUIX_REVISION} -- \ + build \ + -L "${topdir}"/resources/guix/ \ + -L "${topdir}"/resources/guix/gnuboot/patches/ \ + --system=x86_64-linux \ + qemu +} + +build_trisquel_preseed_x86_64_img() +{ + source "${topdir}"/config.sh + source "${topdir}"/resources/scripts/misc/guix.sh + source_guix_profile + + guix time-machine \ + --commit=${GUIX_REVISION} -- \ + build \ + -L "${topdir}"/resources/guix/ \ + -L "${topdir}"/resources/guix/gnuboot/patches/ \ + --system=i686-linux \ + gnuboot-trisquel-preseed.img +} + +build_trisquel_grub_img() +{ + source "${topdir}"/config.sh + source "${topdir}"/resources/scripts/misc/guix.sh + source_guix_profile + + guix time-machine \ + --commit=${GUIX_REVISION} -- \ + build \ + -L "${topdir}"/resources/guix/ \ + -L "${topdir}"/resources/guix/gnuboot/patches/ \ + --system=i686-linux \ + gnuboot-trisquel-grub.img +} + +build_trisquel_rootfs_img() +{ + source "${topdir}"/config.sh + source "${topdir}"/resources/scripts/misc/guix.sh + source_guix_profile + + guix time-machine \ + --commit=${GUIX_REVISION} -- \ + build \ + -L "${topdir}"/resources/guix/ \ + -L "${topdir}"/resources/guix/gnuboot/patches/ \ + --system=i686-linux \ + rootfs.img +} + +return_guix_qemu_x86_64() +{ + img_install_path="bin/qemu-system-x86_64" + # Guix produces 3 qemu outputs: one for the docs, one for the + # static version, and one for all the rest. + pkg_path="$(build_guix_qemu_x86_64 | \ + grep -v '\-doc$' | grep -v '\-static$')" + qemu_path="${pkg_path}/${img_install_path}" + echo "${qemu_path}" +} + +return_trisquel_preseed_x86_64_img() +{ + img_install_path="share/trisquel-installer/preseed.img" + img_path="$(build_trisquel_preseed_x86_64_img)/${img_install_path}" + echo "${img_path}" +} + +return_trisquel_grub_img() +{ + img_install_path="share/trisquel-installer/grub.img" + img_path="$(build_trisquel_grub_img)/${img_install_path}" + echo "${img_path}" +} + +return_trisquel_rootfs_img() +{ + grub_img="$(return_trisquel_grub_img)" + cp "${grub_img}" grub.img + chmod 770 grub.img + + preseed_x86_64_img="$(return_trisquel_preseed_x86_64_img)" + cp "${preseed_x86_64_img}" preseed.img + chmod 770 preseed.img + + qemu-img "create" "-f" "raw" "rootfs.img" "4.1G" + + extra_qemu_args="" + if [ "${kvm}" = "yes" ] ; then + extra_qemu_args="-enable-kvm" + fi + + # Here we don't run that yet inside a Guix package since for now + # running the preseed netinstall requires networking. It is + # possible to capture the packets used during the installation + # with apt-cacher-ng by running apt-cacher-ng on localhost and + # setting mirror/http/proxy to http://10.0.2.2:3142 in presed.cfg + # like that: 'd-i mirror/http/proxy string + # http://10.0.2.2:3142'. It is also relatively easy to package + # apt-cacher-ng for Guix so we could even run it inside a package. + # However once all the packages have been captured, for some + # reasons I didn't manage to make apt-cacher-ng became a partial + # mirror and run fully offline. If someone knows how to do that it + # would be relatively easy to move this command inside Guix + # package(s). As for the enable-kvm parameter, it might be + # possible to generate one package with it and one without it, and + # select the right package depending on if the user used + # --disable-kvm. + "$(return_guix_qemu_x86_64)" \ + "-M" "pc" \ + "-m" "790M" \ + "-nographic" \ + "-drive" "file=grub.img,index=2,media=cdrom,if=ide" \ + "-drive" "file=rootfs.img,index=1,media=disk,if=virtio,driver=raw" \ + "-drive" "file=preseed.img,index=0,media=disk,if=none,format=raw,id=usb" \ + "-usb" "-device" "usb-ehci,id=ehci" "-device" "usb-storage,bus=ehci.0,drive=usb" \ + ${extra_qemu_args} +} + +download_roms() +{ + source "${topdir}"/config.sh + + # We use a Trisquel rootfs for automatic testing. Trisquel 10.0 + # LTS (nabia) still supports i686 and it is supported until April + # 2025. The next Trisquel version doesn't support i686, so in the + # long run users that still have i686-only computers will probably + # use something else than Trisquel nabia by 2025. + # + # Given the above we only added support for testing with Trisquel + # on x86_64, but contributions are welcome to add more + # distributions that work on i686 (like Guix or older Trisquel + # versions for instance). + if [ "${build_cpu}" = "x86_64" ] ; then + return_trisquel_rootfs_img + fi +} + +progname="download" + +if [ $# -eq 1 ] && { [ "$1" = "-h" ] || [ "$1" == "--help" ] ;} ; then + usage "${progname}" + exit 0 +elif [ $# -eq 0 ] ; then + download_roms +elif [ $# -eq 1 ] && [ "$1" = "trisquel-netinst_11.0_amd64.iso" ] ; then + return_trisquel_netinst_x86_64_iso +elif [ $# -eq 1 ] && [ "$1" = "preseed.img" ] ; then + return_trisquel_preseed_img +elif [ $# -eq 1 ] && [ "$1" = "grub.img" ] ; then + return_trisquel_grub_img +elif [ $# -eq 1 ] && [ "$1" = "rootfs.img" ] ; then + return_trisquel_rootfs_img +else + usage "${progname}" + exit ${EX_USAGE} +fi diff --git a/resources/packages/roms/test b/resources/packages/roms/test new file mode 100755 index 0000000..4701780 --- /dev/null +++ b/resources/packages/roms/test @@ -0,0 +1,105 @@ +#!/usr/bin/env bash +# Copyright (C) 2023-2024 Denis 'GNUtoo' Carikli +# +# 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 3 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, see . +set -e + +. resources/scripts/misc/sysexits.sh + +usage() +{ + progname="$1" + + printf "Usage: %s [options]\n\n" "${progname}" + printf "Available options:\n" + printf "\t-h, --help\n" + printf "\t\tDisplay this help and exit.\n" +} + +run_qemu_x86_64() +{ + source config.sh + + gnuboot_img_path="$1" + rootfs_path="$2" + guix_system="$3" + + qemu_pkg="$(guix time-machine \ + --commit="${GUIX_REVISION}" \ + -- \ + build \ + --system="${guix_system}" \ + qemu | grep -v '\-doc$' | grep -v '\-static$')" + + if [ "${kvm}" = "yes" ] ; then + extra_qemu_args="-enable-kvm" + fi + + qemu_system_x86_64="${qemu_pkg}/bin/qemu-system-x86_64" + # shellcheck disable=SC2086 + "${qemu_system_x86_64}" \ + -bios "${gnuboot_img_path}" \ + -M pc \ + -m 790M \ + -nographic \ + -blockdev '{"driver":"file","filename":"'"${rootfs_path}"'","node-name":"libvirt-1-storage"}' \ + -blockdev '{"node-name":"libvirt-1-format","driver":"raw","file":"libvirt-1-storage"}' \ + -device '{"driver":"virtio-scsi-pci","id":"scsi0","bus":"pci.0","addr":"0x4"}' \ + -device '{"driver":"ahci","id":"sata0","bus":"pci.0","addr":"0x5"}' \ + -device '{"driver":"ide-hd","bus":"sata0.0","drive":"libvirt-1-format","id":"sata0-0-0"}' \ + ${extra_qemu_args} +} + +test_grub_cfg_with_lvm() +{ + source config.sh + + test_name="Test grub.cfg with Trisquel LVM install" + + # TODO: Make the test also work with i686. + if [ "${build_cpu}" != "x86_64" ] ; then + printf '[ SKIP ] %s: %s\n' \ + "${test_name}" \ + "test doesn't work (yet) on ${build_cpu} CPUs." + return 0 + fi + + rootfs_path="rootfs.img" + + if [ ! -f ${rootfs_path} ] ; then + resources/packages/roms/download + fi + + run_qemu_x86_64 \ + bin/qemu-pc_2mb/grub_qemu-pc_2mb_libgfxinit_corebootfb_usqwerty.rom \ + "${rootfs_path}" \ + "x86_64-linux" ; ret=$? + + if [ ${ret} -eq 0 ] ; then + printf '[ PASS ] %s.\n' "${test_name}" + else + printf '[ FAIL ] %s.\n' "${test_name}" + exit "${ret}" + fi +} + +if [ $# -eq 1 ] && { [ "$1" = "-h" ] || [ "$1" == "--help" ] ;} ; then + usage "${progname}" + exit 0 +elif [ $# -eq 0 ] ; then + test_grub_cfg_with_lvm +else + usage "${progname}" + exit ${EX_USAGE} +fi diff --git a/resources/trisquel/grub.cfg b/resources/trisquel/grub.cfg new file mode 100644 index 0000000..6df9e37 --- /dev/null +++ b/resources/trisquel/grub.cfg @@ -0,0 +1,18 @@ +# Copyright (C) 2024 Denis 'GNUtoo' Carikli +# +# This file 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 3 of the License, or (at +# your option) any later version. +# +# This file 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. + +set timeout=1 + +menuentry "Trisquel 11 netinstall with custom preseed" { + linux /boot/linux auto=true priority=critical preseed/file=/media/preseed.cfg --- console=ttyS0,115200 quiet + initrd /boot/initrd.gz +} diff --git a/resources/trisquel/preseed.cfg b/resources/trisquel/preseed.cfg new file mode 100644 index 0000000..e7c3682 --- /dev/null +++ b/resources/trisquel/preseed.cfg @@ -0,0 +1,87 @@ +#_preseed_V1 + +# Copyright (C) 2024 Denis 'GNUtoo' Carikli +# +# This file 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 3 of the License, or (at +# your option) any later version. +# +# This file 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. + +############ +# Accounts # +############ +d-i passwd/root-login boolean false +d-i passwd/username string gnuboot +d-i passwd/user-fullname string gnuboot +d-i passwd/user-password password password +d-i passwd/user-password-again password password + +################### +# Keyboard layout # +################### +d-i keyboard-configuration/xkb-keymap select us + +########### +# Locales # +########### +d-i debian-installer/locale string en_US + +########### +# Network # +########### +d-i netcfg/choose_interface select auto +d-i netcfg/get_domain string test +d-i netcfg/get_hostname string test + +###################### +# Package management # +###################### +d-i mirror/country string manual +d-i mirror/http/directory string /trisquel +d-i mirror/http/hostname string mirror.fsf.org +d-i mirror/http/proxy string +popularity-contest popularity-contest/participate boolean false + +################ +# Partitioning # +################ +d-i grub-installer/bootdev string /dev/vda +d-i partman-auto-lvm/guided_size string max +d-i partman-auto/choose_recipe select atomic +d-i partman-auto/disk string /dev/vda +d-i partman-auto/method string lvm +d-i partman-lvm/confirm boolean true +d-i partman-lvm/confirm_nooverwrite boolean true +d-i partman-md/confirm boolean true +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true +d-i partman/confirm_nooverwrite boolean true + +################################# +# Automatically shutdown the VM # +################################# +d-i preseed/late_command string cp /media/shutdown-after-boot.service /target/etc/systemd/system; \ +in-target systemctl enable shutdown-after-boot.service + +############ +# Timezone # +############ +d-i clock-setup/ntp boolean true +d-i clock-setup/utc boolean true +d-i time/zone string UTC + +####################### +# Shutdown at the end # +####################### +d-i finish-install/reboot_in_progress note +d-i debian-installer/exit/poweroff boolean true diff --git a/resources/trisquel/preseed.img.sha512 b/resources/trisquel/preseed.img.sha512 new file mode 100644 index 0000000..cae4dce --- /dev/null +++ b/resources/trisquel/preseed.img.sha512 @@ -0,0 +1 @@ +f12a4a941afc9e24288481ed1b44fbfedf52d706e9e8aa01cfb26bf5ccd54ca52afe9ef5497faf2966ba730c1200d8b8691ebb87e6a75cd8966e0edd49bcb3c0 preseed.img diff --git a/resources/trisquel/shutdown-after-boot.service b/resources/trisquel/shutdown-after-boot.service new file mode 100644 index 0000000..a4de3a8 --- /dev/null +++ b/resources/trisquel/shutdown-after-boot.service @@ -0,0 +1,22 @@ +# This file is part of GNU Boot. +# +# Copyright (C) 2024 Denis 'GNUtoo' Carikli +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Shut down the VM to make the boot test conclude. +DefaultDependencies=no +Wants=display-manager.service +After=display-manager.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/poweroff + +[Install] +WantedBy=multi-user.target diff --git a/tests/lint b/tests/lint index f8e8fe2..7574267 100755 --- a/tests/lint +++ b/tests/lint @@ -58,6 +58,8 @@ run_shellcheck \ resources/packages/payloads/distclean \ resources/packages/rom_images/distclean \ resources/packages/roms/distclean \ + resources/packages/roms/download \ + resources/packages/roms/test \ resources/packages/seabios/distclean \ resources/packages/src/distclean \ resources/packages/u-boot-libre/distclean \