123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013 |
- ;;; GNU Guix --- Functional package management for GNU
- ;;; Copyright © 2016-2023 Ludovic Courtès <ludo@gnu.org>
- ;;; Copyright © 2017, 2019, 2021 Tobias Geerinckx-Rice <me@tobias.gr>
- ;;; Copyright © 2020 Mathieu Othacehe <m.othacehe@gmail.com>
- ;;; Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org>
- ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
- ;;; Copyright © 2020, 2021, 2022 Maxim Cournoyer <maxim.cournoyer@gmail.com>
- ;;;
- ;;; This file is part of GNU Guix.
- ;;;
- ;;; GNU Guix 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.
- ;;;
- ;;; GNU Guix 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 GNU Guix. If not, see <http://www.gnu.org/licenses/>.
- (define-module (gnu tests install)
- #:use-module (gnu)
- #:use-module (gnu bootloader extlinux)
- #:use-module (gnu image)
- #:use-module (gnu tests)
- #:use-module (gnu tests base)
- #:use-module (gnu system)
- #:use-module (gnu system image)
- #:use-module (gnu system install)
- #:use-module (gnu system vm)
- #:use-module ((gnu build marionette) #:select (qemu-command))
- #:use-module (gnu packages admin)
- #:use-module (gnu packages bootloaders)
- #:use-module (gnu packages commencement) ;for 'guile-final'
- #:use-module (gnu packages cryptsetup)
- #:use-module (gnu packages disk)
- #:use-module (gnu packages emacs)
- #:use-module (gnu packages emacs-xyz)
- #:use-module (gnu packages firmware)
- #:use-module (gnu packages linux)
- #:use-module (gnu packages ocr)
- #:use-module (gnu packages openbox)
- #:use-module (gnu packages package-management)
- #:use-module (gnu packages ratpoison)
- #:use-module (gnu packages suckless)
- #:use-module (gnu packages virtualization)
- #:use-module (gnu packages wm)
- #:use-module (gnu packages xorg)
- #:use-module (gnu services desktop)
- #:use-module (gnu services networking)
- #:use-module (gnu services xorg)
- #:use-module (guix store)
- #:use-module (guix monads)
- #:use-module (guix packages)
- #:use-module (guix grafts)
- #:use-module (guix gexp)
- #:use-module (guix utils)
- #:use-module (srfi srfi-1)
- #:export (%test-installed-os
- %test-installed-extlinux-os
- %test-iso-image-installer
- %test-separate-store-os
- %test-separate-home-os
- %test-raid-root-os
- %test-encrypted-root-os
- %test-encrypted-home-os
- %test-encrypted-root-not-boot-os
- %test-btrfs-root-os
- %test-btrfs-root-on-subvolume-os
- %test-btrfs-raid-root-os
- %test-btrfs-raid10-root-os
- %test-btrfs-raid10-root-os-degraded
- %test-jfs-root-os
- %test-f2fs-root-os
- %test-xfs-root-os
- %test-lvm-separate-home-os
- %test-gui-installed-os
- %test-gui-uefi-installed-os
- %test-gui-installed-os-encrypted
- %test-gui-installed-desktop-os-encrypted))
- ;;; Commentary:
- ;;;
- ;;; Test the installation of Guix using the documented approach at the
- ;;; command line.
- ;;;
- ;;; Code:
- (define-os-with-source (%minimal-os %minimal-os-source)
- ;; The OS we want to install.
- (use-modules (gnu) (gnu tests) (srfi srfi-1))
- (operating-system
- (host-name "liberigilo")
- (timezone "Europe/Paris")
- (locale "en_US.UTF-8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vdb"))))
- (kernel-arguments '("console=ttyS0"))
- (file-systems (cons (file-system
- (device (file-system-label "my-root"))
- (mount-point "/")
- (type "ext4"))
- %base-file-systems))
- (users (cons (user-account
- (name "alice")
- (comment "Bob's sister")
- (group "users")
- (supplementary-groups '("wheel" "audio" "video")))
- %base-user-accounts))
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix build utils)
- (guix combinators)))))
- %base-services))))
- (define (operating-system-add-packages os packages)
- "Append PACKAGES to OS packages list."
- (operating-system
- (inherit os)
- (packages (append packages (operating-system-packages os)))))
- (define-os-with-source (%minimal-extlinux-os
- %minimal-extlinux-os-source)
- (use-modules (gnu) (gnu tests) (gnu bootloader extlinux)
- (srfi srfi-1))
- (operating-system
- (host-name "liberigilo")
- (timezone "Europe/Paris")
- (locale "en_US.UTF-8")
- (bootloader (bootloader-configuration
- (bootloader extlinux-bootloader-gpt)
- (targets (list "/dev/vdb"))))
- (kernel-arguments '("console=ttyS0"))
- (file-systems (cons (file-system
- (device (file-system-label "my-root"))
- (mount-point "/")
- (type "ext4"))
- %base-file-systems))
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define MiB (expt 2 20))
- (define %simple-installation-script
- ;; Shell script of a simple installation.
- "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- guix build isc-dhcp
- parted --script /dev/vdb mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 1.6G \\
- set 1 boot on \\
- set 1 bios_grub on
- mkfs.ext4 -L my-root /dev/vdb2
- mount /dev/vdb2 /mnt
- df -h /mnt
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n")
- (define %extlinux-gpt-installation-script
- ;; Shell script of a simple installation.
- ;; As syslinux 6.0.3 does not handle 64bits ext4 partitions,
- ;; we make sure to pass -O '^64bit' to mkfs.
- "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- guix build isc-dhcp
- parted --script /dev/vdb mklabel gpt \\
- mkpart ext2 1M 1.6G \\
- set 1 legacy_boot on
- mkfs.ext4 -L my-root -O '^64bit' /dev/vdb1
- mount /dev/vdb1 /mnt
- df -h /mnt
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n")
- (define (uefi-firmware system)
- "Return the appropriate QEMU OVMF UEFI firmware for the given SYSTEM."
- (cond
- ((string-prefix? "x86_64" system)
- (file-append ovmf "/share/firmware/ovmf_x64.bin"))
- ((string-prefix? "i686" system)
- (file-append ovmf "/share/firmware/ovmf_ia32.bin"))
- (else #f)))
- (define* (run-install target-os target-os-source
- #:key
- (script %simple-installation-script)
- (gui-test #f)
- (packages '())
- (os (marionette-operating-system
- (operating-system
- ;; Since the image has no network access, use the
- ;; current Guix so the store items we need are in
- ;; the image and add packages provided.
- (inherit installation-os)
- (kernel-arguments '("console=ttyS0")))
- #:imported-modules '((gnu services herd)
- (gnu installer tests)
- (guix combinators))))
- (uefi-support? #f)
- (installation-image-type 'efi-raw)
- (install-size 'guess)
- (target-size (* 2200 MiB))
- (number-of-disks 1))
- "Run SCRIPT (a shell script following the system installation procedure) in
- OS to install TARGET-OS. Return the VM disk images of TARGET-SIZE bytes
- containing the installed system. PACKAGES is a list of packages added to OS.
- NUMBER-OF-DISKS can be used to specify a number of disks different than one,
- such as for RAID systems."
- (mlet* %store-monad ((_ (set-grafting #f))
- (system (current-system))
- (uefi-firmware -> (and uefi-support?
- (uefi-firmware system)))
- ;; Since the installation system has no network access,
- ;; we cheat a little bit by adding TARGET to its GC
- ;; roots. This way, we know 'guix system init' will
- ;; succeed. Also add guile-final, which is pulled in
- ;; through provenance.drv and may not always be present.
- (target (operating-system-derivation target-os))
- (base-image -> (os->image
- (operating-system-with-gc-roots
- (operating-system-add-packages
- os packages)
- (list target guile-final))
- #:type (lookup-image-type-by-name
- installation-image-type)))
- (image ->
- (system-image
- (image
- (inherit base-image)
- (size install-size)
- ;; Don't provide substitutes; too big.
- (substitutable? #f)))))
- (define install
- (with-imported-modules '((guix build utils)
- (gnu build marionette))
- #~(begin
- (use-modules (guix build utils)
- (gnu build marionette)
- (srfi srfi-1))
- (set-path-environment-variable "PATH" '("bin")
- (list #$qemu-minimal))
- (mkdir-p #$output)
- (for-each (lambda (n)
- (system* "qemu-img" "create" "-f" "qcow2"
- (format #f "~a/disk~a.qcow2" #$output n)
- #$(number->string target-size)))
- (iota #$number-of-disks))
- (define marionette
- (make-marionette
- `(,(which #$(qemu-command system))
- "-no-reboot"
- "-m" "1200"
- ,@(if #$uefi-firmware
- '("-bios" #$uefi-firmware)
- '())
- #$@(cond
- ((eq? 'efi-raw installation-image-type)
- #~("-drive"
- ,(string-append "file=" #$image
- ",if=virtio,readonly")))
- ((eq? 'uncompressed-iso9660 installation-image-type)
- #~("-cdrom" #$image))
- (else
- (error
- "unsupported installation-image-type:"
- installation-image-type)))
- ,@(append-map
- (lambda (n)
- (list "-drive"
- (format #f "file=~a/disk~a.qcow2,if=virtio"
- #$output n)))
- (iota #$number-of-disks))
- ,@(if (file-exists? "/dev/kvm")
- '("-enable-kvm")
- '()))))
- (pk 'uname (marionette-eval '(uname) marionette))
- ;; Wait for tty1.
- (marionette-eval '(begin
- (use-modules (gnu services herd))
- (start-service 'term-tty1))
- marionette)
- (when #$(->bool script)
- (marionette-eval '(call-with-output-file "/etc/target-config.scm"
- (lambda (port)
- (write '#$target-os-source port)))
- marionette)
- ;; Run SCRIPT. It typically invokes 'reboot' as a last step and
- ;; thus normally gets killed with SIGTERM by PID 1.
- (let ((status (marionette-eval '(system #$script) marionette)))
- (exit (or (eof-object? status)
- (equal? (status:term-sig status) SIGTERM)
- (equal? (status:exit-val status) 0)))))
- (when #$(->bool gui-test)
- (wait-for-unix-socket "/var/guix/installer-socket"
- marionette)
- (format #t "installer socket ready~%")
- (force-output)
- (exit #$(and gui-test
- (gui-test #~marionette)))))))
- (mlet %store-monad ((images-dir (gexp->derivation "installation"
- install
- #:substitutable? #f))) ;too big
- (return (with-imported-modules '((guix build utils))
- #~(begin
- (use-modules (guix build utils))
- (find-files #$images-dir)))))))
- (define* (qemu-command* images #:key (uefi-support? #f) (memory-size 256))
- "Return as a monadic value the command to run QEMU with a writable overlay
- on top of IMAGES, a list of disk images. The QEMU VM has access to MEMORY-SIZE
- MiB of RAM."
- (mlet* %store-monad ((system (current-system))
- (uefi-firmware -> (and uefi-support?
- (uefi-firmware system))))
- (return #~(begin
- (use-modules (srfi srfi-1))
- `(,(string-append #$qemu-minimal "/bin/"
- #$(qemu-command system))
- "-snapshot" ;for the volatile, writable overlay
- ,@(if (file-exists? "/dev/kvm")
- '("-enable-kvm")
- '())
- ,@(if #$uefi-firmware
- '("-bios" #$uefi-firmware)
- '())
- "-no-reboot" "-m" #$(number->string memory-size)
- ,@(append-map (lambda (image)
- (list "-drive" (format #f "file=~a,if=virtio"
- image)))
- #$images))))))
- (define %test-installed-os
- (system-test
- (name "installed-os")
- (description
- "Test basic functionality of an OS installed like one would do by hand.
- This test is expensive in terms of CPU and storage usage since we need to
- build (current-guix) and then store a couple of full system images.")
- (value
- (mlet* %store-monad ((images (run-install %minimal-os %minimal-os-source))
- (command (qemu-command* images)))
- (run-basic-test %minimal-os command
- "installed-os")))))
- (define %test-installed-extlinux-os
- (system-test
- (name "installed-extlinux-os")
- (description
- "Test basic functionality of an OS booted with an extlinux bootloader. As
- per %test-installed-os, this test is expensive in terms of CPU and storage.")
- (value
- (mlet* %store-monad ((images (run-install %minimal-extlinux-os
- %minimal-extlinux-os-source
- #:packages
- (list syslinux)
- #:script
- %extlinux-gpt-installation-script))
- (command (qemu-command* images)))
- (run-basic-test %minimal-extlinux-os command
- "installed-extlinux-os")))))
- ;;;
- ;;; Installation through an ISO image.
- ;;;
- (define-os-with-source (%minimal-os-on-vda %minimal-os-on-vda-source)
- ;; The OS we want to install.
- (use-modules (gnu) (gnu tests) (srfi srfi-1))
- (operating-system
- (host-name "liberigilo")
- (timezone "Europe/Paris")
- (locale "en_US.UTF-8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vda"))))
- (kernel-arguments '("console=ttyS0"))
- (file-systems (cons (file-system
- (device (file-system-label "my-root"))
- (mount-point "/")
- (type "ext4"))
- %base-file-systems))
- (users (cons (user-account
- (name "alice")
- (comment "Bob's sister")
- (group "users")
- (supplementary-groups '("wheel" "audio" "video")))
- %base-user-accounts))
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix build utils)
- (guix combinators)))))
- %base-services))))
- (define %simple-installation-script-for-/dev/vda
- ;; Shell script of a simple installation.
- "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- guix build isc-dhcp
- parted --script /dev/vda mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 1.6G \\
- set 1 boot on \\
- set 1 bios_grub on
- mkfs.ext4 -L my-root /dev/vda2
- mount /dev/vda2 /mnt
- df -h /mnt
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n")
- (define %test-iso-image-installer
- (system-test
- (name "iso-image-installer")
- (description
- "")
- (value
- (mlet* %store-monad ((images (run-install
- %minimal-os-on-vda
- %minimal-os-on-vda-source
- #:script
- %simple-installation-script-for-/dev/vda
- #:installation-image-type
- 'uncompressed-iso9660))
- (command (qemu-command* images)))
- (run-basic-test %minimal-os-on-vda command name)))))
- ;;;
- ;;; Separate /home.
- ;;;
- (define-os-with-source (%separate-home-os %separate-home-os-source)
- ;; The OS we want to install.
- (use-modules (gnu) (gnu tests) (srfi srfi-1))
- (operating-system
- (host-name "liberigilo")
- (timezone "Europe/Paris")
- (locale "en_US.utf8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets '("/dev/vdb"))))
- (kernel-arguments '("console=ttyS0"))
- (file-systems (cons* (file-system
- (device (file-system-label "my-root"))
- (mount-point "/")
- (type "ext4"))
- (file-system
- (device "none")
- (mount-point "/home")
- (type "tmpfs"))
- %base-file-systems))
- (users (cons* (user-account
- (name "alice")
- (group "users"))
- (user-account
- (name "charlie")
- (group "users"))
- %base-user-accounts))
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %test-separate-home-os
- (system-test
- (name "separate-home-os")
- (description
- "Test basic functionality of an installed OS with a separate /home
- partition. In particular, home directories must be correctly created (see
- <https://bugs.gnu.org/21108>).")
- (value
- (mlet* %store-monad ((images (run-install %separate-home-os
- %separate-home-os-source
- #:script
- %simple-installation-script))
- (command (qemu-command* images)))
- (run-basic-test %separate-home-os command "separate-home-os")))))
- ;;;
- ;;; Separate /gnu/store partition.
- ;;;
- (define-os-with-source (%separate-store-os %separate-store-os-source)
- ;; The OS we want to install.
- (use-modules (gnu) (gnu tests) (srfi srfi-1))
- (operating-system
- (host-name "liberigilo")
- (timezone "Europe/Paris")
- (locale "en_US.UTF-8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vdb"))))
- (kernel-arguments '("console=ttyS0"))
- (file-systems (cons* (file-system
- (device (file-system-label "root-fs"))
- (mount-point "/")
- (type "ext4"))
- (file-system
- (device (file-system-label "store-fs"))
- (mount-point "/gnu")
- (type "ext4"))
- %base-file-systems))
- (users %base-user-accounts)
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %separate-store-installation-script
- ;; Installation with a separate /gnu partition.
- "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- guix build isc-dhcp
- parted --script /dev/vdb mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 400M \\
- mkpart primary ext2 400M 2.1G \\
- set 1 boot on \\
- set 1 bios_grub on
- mkfs.ext4 -L root-fs /dev/vdb2
- mkfs.ext4 -L store-fs /dev/vdb3
- mount /dev/vdb2 /mnt
- mkdir /mnt/gnu
- mount /dev/vdb3 /mnt/gnu
- df -h /mnt
- df -h /mnt/gnu
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n")
- (define %test-separate-store-os
- (system-test
- (name "separate-store-os")
- (description
- "Test basic functionality of an OS installed like one would do by hand,
- where /gnu lives on a separate partition.")
- (value
- (mlet* %store-monad ((images (run-install %separate-store-os
- %separate-store-os-source
- #:script
- %separate-store-installation-script))
- (command (qemu-command* images)))
- (run-basic-test %separate-store-os command "separate-store-os")))))
- ;;;
- ;;; RAID root device.
- ;;;
- (define-os-with-source (%raid-root-os %raid-root-os-source)
- ;; An OS whose root partition is a RAID partition.
- (use-modules (gnu) (gnu tests))
- (operating-system
- (host-name "raidified")
- (timezone "Europe/Paris")
- (locale "en_US.utf8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vdb"))))
- (kernel-arguments '("console=ttyS0"))
- ;; Add a kernel module for RAID-1 (aka. "mirror").
- (initrd-modules (cons "raid1" %base-initrd-modules))
- (mapped-devices (list (mapped-device
- (source (list "/dev/vda2" "/dev/vda3"))
- (target "/dev/md0")
- (type raid-device-mapping))))
- (file-systems (cons (file-system
- (device (file-system-label "root-fs"))
- (mount-point "/")
- (type "ext4")
- (dependencies mapped-devices))
- %base-file-systems))
- (users %base-user-accounts)
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %raid-root-installation-script
- ;; Installation with a separate /gnu partition. See
- ;; <https://raid.wiki.kernel.org/index.php/RAID_setup> for more on RAID and
- ;; mdadm.
- "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- parted --script /dev/vdb mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 1.6G \\
- mkpart primary ext2 1.6G 3.2G \\
- set 1 boot on \\
- set 1 bios_grub on
- yes | mdadm --create /dev/md0 --verbose --level=mirror --raid-devices=2 \\
- /dev/vdb2 /dev/vdb3
- mkfs.ext4 -L root-fs /dev/md0
- mount /dev/md0 /mnt
- df -h /mnt
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n")
- (define %test-raid-root-os
- (system-test
- (name "raid-root-os")
- (description
- "Test functionality of an OS installed with a RAID root partition managed
- by 'mdadm'.")
- (value
- (mlet* %store-monad ((images (run-install %raid-root-os
- %raid-root-os-source
- #:script
- %raid-root-installation-script
- #:target-size (* 3200 MiB)))
- (command (qemu-command* images)))
- (run-basic-test %raid-root-os
- `(,@command) "raid-root-os")))))
- ;;;
- ;;; LUKS-encrypted root file system.
- ;;;
- (define-os-with-source (%encrypted-root-os %encrypted-root-os-source)
- ;; The OS we want to install.
- (use-modules (gnu) (gnu tests) (srfi srfi-1))
- (operating-system
- (host-name "liberigilo")
- (timezone "Europe/Paris")
- (locale "en_US.UTF-8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets '("/dev/vdb"))))
- ;; Note: Do not pass "console=ttyS0" so we can use our passphrase prompt
- ;; detection logic in 'enter-luks-passphrase'.
- (mapped-devices (list (mapped-device
- (source (uuid "12345678-1234-1234-1234-123456789abc"))
- (target "the-root-device")
- (type luks-device-mapping))))
- (file-systems (cons (file-system
- (device "/dev/mapper/the-root-device")
- (mount-point "/")
- (type "ext4"))
- %base-file-systems))
- (users (cons (user-account
- (name "charlie")
- (group "users")
- (supplementary-groups '("wheel" "audio" "video")))
- %base-user-accounts))
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %luks-passphrase
- ;; LUKS encryption passphrase used in tests.
- "thepassphrase")
- (define %encrypted-root-installation-script
- ;; Shell script of a simple installation.
- (string-append "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- ls -l /run/current-system/gc-roots
- parted --script /dev/vdb mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 1.6G \\
- set 1 boot on \\
- set 1 bios_grub on
- echo -n " %luks-passphrase " | \\
- cryptsetup luksFormat --uuid=12345678-1234-1234-1234-123456789abc -q /dev/vdb2 -
- echo -n " %luks-passphrase " | \\
- cryptsetup open --type luks --key-file - /dev/vdb2 the-root-device
- mkfs.ext4 -L my-root /dev/mapper/the-root-device
- mount LABEL=my-root /mnt
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system build /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n"))
- (define (enter-luks-passphrase marionette)
- "Return a gexp to be inserted in the basic system test running on MARIONETTE
- to enter the LUKS passphrase."
- (let ((ocrad (file-append ocrad "/bin/ocrad")))
- #~(begin
- (define (passphrase-prompt? text)
- (string-contains (pk 'screen-text text) "Enter pass"))
- (define (bios-boot-screen? text)
- ;; Return true if TEXT corresponds to the boot screen, before GRUB's
- ;; menu.
- (string-prefix? "SeaBIOS" text))
- (test-assert "enter LUKS passphrase for GRUB"
- (begin
- ;; At this point we have no choice but to use OCR to determine
- ;; when the passphrase should be entered.
- (wait-for-screen-text #$marionette passphrase-prompt?
- #:ocr #$ocrad)
- (marionette-type #$(string-append %luks-passphrase "\n")
- #$marionette)
- ;; Now wait until we leave the boot screen. This is necessary so
- ;; we can then be sure we match the "Enter passphrase" prompt from
- ;; 'cryptsetup', in the initrd.
- (wait-for-screen-text #$marionette (negate bios-boot-screen?)
- #:ocr #$ocrad
- #:timeout 20)))
- (test-assert "enter LUKS passphrase for the initrd"
- (begin
- ;; XXX: Here we use OCR as well but we could instead use QEMU
- ;; '-serial stdio' and run it in an input pipe,
- (wait-for-screen-text #$marionette passphrase-prompt?
- #:ocr #$ocrad
- #:timeout 60)
- (marionette-type #$(string-append %luks-passphrase "\n")
- #$marionette)
- ;; Take a screenshot for debugging purposes.
- (marionette-control (string-append "screendump " #$output
- "/post-initrd-passphrase.ppm")
- #$marionette))))))
- (define %test-encrypted-root-os
- (system-test
- (name "encrypted-root-os")
- (description
- "Test basic functionality of an OS installed like one would do by hand.
- This test is expensive in terms of CPU and storage usage since we need to
- build (current-guix) and then store a couple of full system images.")
- (value
- (mlet* %store-monad ((images (run-install %encrypted-root-os
- %encrypted-root-os-source
- #:script
- %encrypted-root-installation-script))
- (command (qemu-command* images)))
- (run-basic-test %encrypted-root-os command "encrypted-root-os"
- #:initialization enter-luks-passphrase)))))
- ;;;
- ;;; Separate /home on LVM
- ;;;
- ;; Since LVM support in guix currently doesn't allow root-on-LVM we use /home on LVM
- (define-os-with-source (%lvm-separate-home-os %lvm-separate-home-os-source)
- (use-modules (gnu) (gnu tests))
- (operating-system
- (host-name "separate-home-on-lvm")
- (timezone "Europe/Paris")
- (locale "en_US.utf8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vdb"))))
- (kernel-arguments '("console=ttyS0"))
- (mapped-devices (list (mapped-device
- (source "vg0")
- (target "vg0-home")
- (type lvm-device-mapping))))
- (file-systems (cons* (file-system
- (device (file-system-label "root-fs"))
- (mount-point "/")
- (type "ext4"))
- (file-system
- (device "/dev/mapper/vg0-home")
- (mount-point "/home")
- (type "ext4")
- (dependencies mapped-devices))
- %base-file-systems))
- (users %base-user-accounts)
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %lvm-separate-home-installation-script
- "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- parted --script /dev/vdb mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 1.6G \\
- mkpart primary 1.6G 3.2G \\
- set 1 boot on \\
- set 1 bios_grub on
- pvcreate /dev/vdb3
- vgcreate vg0 /dev/vdb3
- lvcreate -L 1.6G -n home vg0
- vgchange -ay
- mkfs.ext4 -L root-fs /dev/vdb2
- mkfs.ext4 /dev/mapper/vg0-home
- mount /dev/vdb2 /mnt
- mkdir /mnt/home
- mount /dev/mapper/vg0-home /mnt/home
- df -h /mnt /mnt/home
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n")
- (define %test-lvm-separate-home-os
- (system-test
- (name "lvm-separate-home-os")
- (description
- "Test functionality of an OS installed with a LVM /home partition")
- (value
- (mlet* %store-monad ((images (run-install %lvm-separate-home-os
- %lvm-separate-home-os-source
- #:script
- %lvm-separate-home-installation-script
- #:packages (list lvm2-static)
- #:target-size (* 3200 MiB)))
- (command (qemu-command* images)))
- (run-basic-test %lvm-separate-home-os
- `(,@command) "lvm-separate-home-os")))))
- ;;;
- ;;; LUKS-encrypted /home, unencrypted root.
- ;;;
- (define-os-with-source (%encrypted-home-os %encrypted-home-os-source)
- (use-modules (gnu) (gnu tests))
- (operating-system
- (host-name "cipherhome")
- (timezone "Europe/Paris")
- (locale "en_US.utf8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vdb"))))
- ;; Note: Do not pass "console=ttyS0" so we can use our passphrase prompt
- ;; detection logic in 'enter-luks-passphrase'.
- (mapped-devices (list (mapped-device
- (source (uuid "12345678-1234-1234-1234-123456789abc"))
- (target "the-home-device")
- (type luks-device-mapping))))
- (file-systems (cons* (file-system
- (device (file-system-label "root-fs"))
- (mount-point "/")
- (type "ext4"))
- (file-system
- (device (file-system-label "home-fs"))
- (mount-point "/home")
- (type "ext4")
- (dependencies mapped-devices))
- %base-file-systems))
- (users %base-user-accounts)
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %encrypted-home-installation-script
- (string-append "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- parted --script /dev/vdb mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 1.6G \\
- mkpart primary 1.6G 2.0G \\
- set 1 boot on \\
- set 1 bios_grub on
- echo -n " %luks-passphrase " | \\
- cryptsetup luksFormat --uuid=12345678-1234-1234-1234-123456789abc -q /dev/vdb3 -
- echo -n " %luks-passphrase " | \\
- cryptsetup open --type luks --key-file - /dev/vdb3 the-home-device
- mkfs.ext4 -L root-fs /dev/vdb2
- mkfs.ext4 -L home-fs /dev/mapper/the-home-device
- mount /dev/vdb2 /mnt
- mkdir /mnt/home
- mount /dev/mapper/the-home-device /mnt/home
- df -h /mnt /mnt/home
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n"))
- (define (enter-luks-passphrase-for-home marionette)
- "Return a gexp to be inserted in the basic system test running on MARIONETTE
- to enter the LUKS passphrase. Note that 'cryptsetup open' in this case is
- launched as a shepherd service."
- (let ((ocrad (file-append ocrad "/bin/ocrad")))
- #~(begin
- (define (passphrase-prompt? text)
- (string-contains (pk 'screen-text text) "Enter pass"))
- (test-assert "enter LUKS passphrase for the shepherd service"
- (begin
- ;; XXX: Here we use OCR as well but we could instead use QEMU
- ;; '-serial stdio' and run it in an input pipe,
- (wait-for-screen-text #$marionette passphrase-prompt?
- #:ocr #$ocrad
- #:timeout 120)
- (marionette-type #$(string-append %luks-passphrase "\n")
- #$marionette)
- ;; Take a screenshot for debugging purposes.
- (marionette-control (string-append "screendump " #$output
- "/shepherd-passphrase.ppm")
- #$marionette))))))
- (define %test-encrypted-home-os
- (system-test
- (name "encrypted-home-os")
- (description
- "Test functionality of an OS installed with a LUKS /home partition")
- (value
- (mlet* %store-monad ((images (run-install %encrypted-home-os
- %encrypted-home-os-source
- #:script
- %encrypted-home-installation-script))
- (command (qemu-command* images)))
- (run-basic-test %encrypted-home-os command "encrypted-home-os"
- #:initialization enter-luks-passphrase-for-home)))))
- ;;;
- ;;; LUKS-encrypted root file system and /boot in a non-encrypted partition.
- ;;;
- (define-os-with-source (%encrypted-root-not-boot-os
- %encrypted-root-not-boot-os-source)
- ;; The OS we want to install.
- (use-modules (gnu) (gnu tests) (srfi srfi-1))
- (operating-system
- (host-name "bootroot")
- (timezone "Europe/Paris")
- (locale "en_US.UTF-8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vdb"))))
- (mapped-devices (list (mapped-device
- (source
- (uuid "12345678-1234-1234-1234-123456789abc"))
- (target "root")
- (type luks-device-mapping))))
- (file-systems (cons* (file-system
- (device (file-system-label "my-boot"))
- (mount-point "/boot")
- (type "ext4"))
- (file-system
- (device "/dev/mapper/root")
- (mount-point "/")
- (type "ext4"))
- %base-file-systems))
- (users (cons (user-account
- (name "alice")
- (group "users")
- (supplementary-groups '("wheel" "audio" "video")))
- %base-user-accounts))
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %encrypted-root-not-boot-installation-script
- ;; Shell script for an installation with boot not encrypted but root
- ;; encrypted.
- (format #f "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- ls -l /run/current-system/gc-roots
- parted --script /dev/vdb mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 50M \\
- mkpart primary ext2 50M 1.6G \\
- set 1 boot on \\
- set 1 bios_grub on
- echo -n \"~a\" | cryptsetup luksFormat --uuid=\"~a\" -q /dev/vdb3 -
- echo -n \"~a\" | cryptsetup open --type luks --key-file - /dev/vdb3 root
- mkfs.ext4 -L my-root /dev/mapper/root
- mkfs.ext4 -L my-boot /dev/vdb2
- mount LABEL=my-root /mnt
- mkdir /mnt/boot
- mount LABEL=my-boot /mnt/boot
- echo \"Checking mounts\"
- mount
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system build /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- echo \"Debugging info\"
- blkid
- cat /mnt/boot/grub/grub.cfg
- reboot\n"
- %luks-passphrase "12345678-1234-1234-1234-123456789abc"
- %luks-passphrase))
- (define %test-encrypted-root-not-boot-os
- (system-test
- (name "encrypted-root-not-boot-os")
- (description
- "Test the manual installation on an OS with / in an encrypted partition
- but /boot on a different, non-encrypted partition. This test is expensive in
- terms of CPU and storage usage since we need to build (current-guix) and then
- store a couple of full system images.")
- (value
- (mlet* %store-monad
- ((images (run-install %encrypted-root-not-boot-os
- %encrypted-root-not-boot-os-source
- #:script
- %encrypted-root-not-boot-installation-script))
- (command (qemu-command* images)))
- (run-basic-test %encrypted-root-not-boot-os command
- "encrypted-root-not-boot-os"
- #:initialization enter-luks-passphrase)))))
- ;;;
- ;;; Btrfs root file system.
- ;;;
- (define-os-with-source (%btrfs-root-os %btrfs-root-os-source)
- ;; The OS we want to install.
- (use-modules (gnu) (gnu tests) (srfi srfi-1))
- (operating-system
- (host-name "liberigilo")
- (timezone "Europe/Paris")
- (locale "en_US.UTF-8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vdb"))))
- (kernel-arguments '("console=ttyS0"))
- (file-systems (cons (file-system
- (device (file-system-label "my-root"))
- (mount-point "/")
- (type "btrfs"))
- %base-file-systems))
- (users (cons (user-account
- (name "charlie")
- (group "users")
- (supplementary-groups '("wheel" "audio" "video")))
- %base-user-accounts))
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %btrfs-root-installation-script
- ;; Shell script of a simple installation.
- "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- ls -l /run/current-system/gc-roots
- parted --script /dev/vdb mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 2G \\
- set 1 boot on \\
- set 1 bios_grub on
- mkfs.btrfs -L my-root /dev/vdb2
- mount /dev/vdb2 /mnt
- btrfs subvolume create /mnt/home
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system build /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n")
- (define %test-btrfs-root-os
- (system-test
- (name "btrfs-root-os")
- (description
- "Test basic functionality of an OS installed like one would do by hand.
- This test is expensive in terms of CPU and storage usage since we need to
- build (current-guix) and then store a couple of full system images.")
- (value
- (mlet* %store-monad ((images (run-install %btrfs-root-os
- %btrfs-root-os-source
- #:script
- %btrfs-root-installation-script))
- (command (qemu-command* images)))
- (run-basic-test %btrfs-root-os command "btrfs-root-os")))))
- ;;;
- ;;; Btrfs RAID-0 root file system.
- ;;;
- (define-os-with-source (%btrfs-raid-root-os %btrfs-raid-root-os-source)
- ;; An OS whose root partition is a RAID partition.
- (use-modules (gnu) (gnu tests))
- (operating-system
- (host-name "liberigilo")
- (timezone "Europe/Paris")
- (locale "en_US.utf8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vdb"))))
- (kernel-arguments '("console=ttyS0"))
- (file-systems (cons (file-system
- (device (file-system-label "root-fs"))
- (mount-point "/")
- (type "btrfs"))
- %base-file-systems))
- (users %base-user-accounts)
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %btrfs-raid-root-installation-script
- "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- parted --script /dev/vdb mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 1.4G \\
- mkpart primary ext2 1.4G 2.8G \\
- set 1 boot on \\
- set 1 bios_grub on
- mkfs.btrfs -L root-fs -d raid0 -m raid0 /dev/vdb2 /dev/vdb3
- mount /dev/vdb2 /mnt
- df -h /mnt
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n")
- (define %test-btrfs-raid-root-os
- (system-test
- (name "btrfs-raid-root-os")
- (description "Test functionality of an OS installed with a Btrfs
- RAID-0 (stripe) root partition.")
- (value
- (mlet* %store-monad
- ((images (run-install %btrfs-raid-root-os
- %btrfs-raid-root-os-source
- #:script %btrfs-raid-root-installation-script
- #:target-size (* 2800 MiB)))
- (command (qemu-command* images)))
- (run-basic-test %btrfs-raid-root-os `(,@command) "btrfs-raid-root-os")))))
- ;;;
- ;;; Btrfs root file system on a subvolume.
- ;;;
- (define-os-with-source (%btrfs-root-on-subvolume-os
- %btrfs-root-on-subvolume-os-source)
- ;; The OS we want to install.
- (use-modules (gnu) (gnu tests) (srfi srfi-1))
- (operating-system
- (host-name "hurd")
- (timezone "Europe/Paris")
- (locale "en_US.UTF-8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vdb"))))
- (kernel-arguments '("console=ttyS0"))
- (file-systems (cons* (file-system
- (device (file-system-label "btrfs-pool"))
- (mount-point "/")
- (options "subvol=rootfs,compress=zstd")
- (type "btrfs"))
- (file-system
- (device (file-system-label "btrfs-pool"))
- (mount-point "/home")
- (options "subvol=homefs,compress=lzo")
- (type "btrfs"))
- %base-file-systems))
- (users (cons (user-account
- (name "charlie")
- (group "users")
- (supplementary-groups '("wheel" "audio" "video")))
- %base-user-accounts))
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %btrfs-root-on-subvolume-installation-script
- ;; Shell script of a simple installation.
- "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- ls -l /run/current-system/gc-roots
- parted --script /dev/vdb mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 2G \\
- set 1 boot on \\
- set 1 bios_grub on
- # Setup the top level Btrfs file system with its subvolume.
- mkfs.btrfs -L btrfs-pool /dev/vdb2
- mount /dev/vdb2 /mnt
- btrfs subvolume create /mnt/rootfs
- btrfs subvolume create /mnt/homefs
- umount /dev/vdb2
- # Mount the subvolumes, ready for installation.
- mount LABEL=btrfs-pool -o 'subvol=rootfs,compress=zstd' /mnt
- mkdir /mnt/home
- mount LABEL=btrfs-pool -o 'subvol=homefs,compress=zstd' /mnt/home
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system build /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n")
- (define %test-btrfs-root-on-subvolume-os
- (system-test
- (name "btrfs-root-on-subvolume-os")
- (description
- "Test basic functionality of an OS installed like one would do by hand.
- This test is expensive in terms of CPU and storage usage since we need to
- build (current-guix) and then store a couple of full system images.")
- (value
- (mlet* %store-monad
- ((images (run-install %btrfs-root-on-subvolume-os
- %btrfs-root-on-subvolume-os-source
- #:script
- %btrfs-root-on-subvolume-installation-script))
- (command (qemu-command* images)))
- (run-basic-test %btrfs-root-on-subvolume-os command
- "btrfs-root-on-subvolume-os")))))
- ;;;
- ;;; Btrfs RAID10 root file system.
- ;;;
- (define-os-with-source (%btrfs-raid10-root-os
- %btrfs-raid10-root-os-source)
- ;; The OS we want to install.
- (use-modules (gnu) (gnu tests) (srfi srfi-1))
- (operating-system
- (host-name "hurd")
- (timezone "Europe/Paris")
- (locale "en_US.UTF-8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vdb" "/dev/vdc" "/dev/vdd" "/dev/vde"))))
- (kernel-arguments '("console=ttyS0"))
- (file-systems (cons* (file-system
- (device (uuid "16ff18e2-eb41-4324-8df5-80d3b53c411b"))
- (mount-point "/")
- (options "compress-force=zstd,degraded")
- (type "btrfs"))
- %base-file-systems))
- (users (cons (user-account
- (name "charlie")
- (group "users")
- (supplementary-groups '("wheel" "audio" "video")))
- %base-user-accounts))
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %btrfs-raid10-root-installation-script
- ;; Shell script of a simple installation.
- "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- ls -l /run/current-system/gc-roots
- for d in vdb vdc vdd vde; do
- parted --script /dev/$d mklabel gpt \\
- mkpart primary ext2 1M 2M \\
- mkpart primary ext2 2M 100% \\
- set 1 boot on \\
- set 1 bios_grub on
- done
- # Create the RAID10 Btrfs array.
- mkfs.btrfs -d raid10 -m raid1c4 /dev/{vdb2,vdc2,vdd2,vde2} \\
- --uuid 16ff18e2-eb41-4324-8df5-80d3b53c411b
- # Mount it, ready for installation.
- mount UUID=16ff18e2-eb41-4324-8df5-80d3b53c411b -o compress-force=zstd /mnt
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system build /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n")
- (define %test-btrfs-raid10-root-images
- (mlet %store-monad
- ((images (run-install %btrfs-raid10-root-os
- %btrfs-raid10-root-os-source
- #:script
- %btrfs-raid10-root-installation-script
- #:number-of-disks 4
- #:target-size (* 1100 MiB))))
- (return images)))
- (define %test-btrfs-raid10-root-os
- (system-test
- (name "btrfs-raid10-root-os")
- (description
- "Test basic functionality of an OS installed on top of a Btrfs RAID10 file
- system spanning 4 disks. This test is expensive in terms of CPU and storage
- usage since we need to build (current-guix) and then store a couple of full
- system images.")
- (value
- (mlet* %store-monad
- ((images %test-btrfs-raid10-root-images)
- (command (qemu-command* images)))
- (run-basic-test %btrfs-raid10-root-os command
- "btrfs-raid10-root-os")))))
- (define %test-btrfs-raid10-root-os-degraded
- (system-test
- (name "btrfs-raid10-root-os-degraded")
- (description
- "Test basic functionality of an OS installed on top of a Btrfs RAID10 file
- system spanning 6 disks, degraded to 5 disks. This test is expensive in terms
- of CPU and storage usage since we need to build (current-guix) and then store
- a couple of full system images.")
- (value
- (mlet* %store-monad
- ;; Drop the first image; this boots because the root file system uses
- ;; the Btrfs "degraded" mount option.
- ((images %test-btrfs-raid10-root-images)
- (command (qemu-command* #~(cdr #$images))))
- (run-basic-test %btrfs-raid10-root-os command
- "btrfs-raid10-root-os")))))
- ;;;
- ;;; JFS root file system.
- ;;;
- (define-os-with-source (%jfs-root-os %jfs-root-os-source)
- ;; The OS we want to install.
- (use-modules (gnu) (gnu tests) (srfi srfi-1))
- (operating-system
- (host-name "liberigilo")
- (timezone "Europe/Paris")
- (locale "en_US.UTF-8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vdb"))))
- (kernel-arguments '("console=ttyS0"))
- (file-systems (cons (file-system
- (device (file-system-label "my-root"))
- (mount-point "/")
- (type "jfs"))
- %base-file-systems))
- (users (cons (user-account
- (name "charlie")
- (group "users")
- (supplementary-groups '("wheel" "audio" "video")))
- %base-user-accounts))
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %jfs-root-installation-script
- ;; Shell script of a simple installation.
- "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- ls -l /run/current-system/gc-roots
- parted --script /dev/vdb mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 2G \\
- set 1 boot on \\
- set 1 bios_grub on
- jfs_mkfs -L my-root -q /dev/vdb2
- mount /dev/vdb2 /mnt
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system build /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n")
- (define %test-jfs-root-os
- (system-test
- (name "jfs-root-os")
- (description
- "Test basic functionality of an OS installed like one would do by hand.
- This test is expensive in terms of CPU and storage usage since we need to
- build (current-guix) and then store a couple of full system images.")
- (value
- (mlet* %store-monad ((images (run-install %jfs-root-os
- %jfs-root-os-source
- #:script
- %jfs-root-installation-script))
- (command (qemu-command* images)))
- (run-basic-test %jfs-root-os command "jfs-root-os")))))
- ;;;
- ;;; F2FS root file system.
- ;;;
- (define-os-with-source (%f2fs-root-os %f2fs-root-os-source)
- ;; The OS we want to install.
- (use-modules (gnu) (gnu tests) (srfi srfi-1))
- (operating-system
- (host-name "liberigilo")
- (timezone "Europe/Paris")
- (locale "en_US.UTF-8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vdb"))))
- (kernel-arguments '("console=ttyS0"))
- (file-systems (cons (file-system
- (device (file-system-label "my-root"))
- (mount-point "/")
- (type "f2fs"))
- %base-file-systems))
- (users (cons (user-account
- (name "charlie")
- (group "users")
- (supplementary-groups '("wheel" "audio" "video")))
- %base-user-accounts))
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %f2fs-root-installation-script
- ;; Shell script of a simple installation.
- "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- ls -l /run/current-system/gc-roots
- parted --script /dev/vdb mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 2G \\
- set 1 boot on \\
- set 1 bios_grub on
- mkfs.f2fs -l my-root -q /dev/vdb2
- mount /dev/vdb2 /mnt
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system build /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n")
- (define %test-f2fs-root-os
- (system-test
- (name "f2fs-root-os")
- (description
- "Test basic functionality of an OS installed like one would do by hand.
- This test is expensive in terms of CPU and storage usage since we need to
- build (current-guix) and then store a couple of full system images.")
- (value
- (mlet* %store-monad ((images (run-install %f2fs-root-os
- %f2fs-root-os-source
- #:script
- %f2fs-root-installation-script))
- (command (qemu-command* images)))
- (run-basic-test %f2fs-root-os command "f2fs-root-os")))))
- ;;;
- ;;; XFS root file system.
- ;;;
- (define-os-with-source (%xfs-root-os %xfs-root-os-source)
- ;; The OS we want to install.
- (use-modules (gnu) (gnu tests) (srfi srfi-1))
- (operating-system
- (host-name "liberigilo")
- (timezone "Europe/Paris")
- (locale "en_US.UTF-8")
- (bootloader (bootloader-configuration
- (bootloader grub-bootloader)
- (targets (list "/dev/vdb"))))
- (kernel-arguments '("console=ttyS0"))
- (file-systems (cons (file-system
- (device (file-system-label "my-root"))
- (mount-point "/")
- (type "xfs"))
- %base-file-systems))
- (users (cons (user-account
- (name "charlie")
- (group "users")
- (supplementary-groups '("wheel" "audio" "video")))
- %base-user-accounts))
- (services (cons (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix combinators)))))
- %base-services))))
- (define %xfs-root-installation-script
- ;; Shell script of a simple installation.
- "\
- . /etc/profile
- set -e -x
- guix --version
- export GUIX_BUILD_OPTIONS=--no-grafts
- ls -l /run/current-system/gc-roots
- parted --script /dev/vdb mklabel gpt \\
- mkpart primary ext2 1M 3M \\
- mkpart primary ext2 3M 2G \\
- set 1 boot on \\
- set 1 bios_grub on
- mkfs.xfs -L my-root -q /dev/vdb2
- mount /dev/vdb2 /mnt
- herd start cow-store /mnt
- mkdir /mnt/etc
- cp /etc/target-config.scm /mnt/etc/config.scm
- guix system build /mnt/etc/config.scm
- guix system init /mnt/etc/config.scm /mnt --no-substitutes
- sync
- reboot\n")
- (define %test-xfs-root-os
- (system-test
- (name "xfs-root-os")
- (description
- "Test basic functionality of an OS installed like one would do by hand.
- This test is expensive in terms of CPU and storage usage since we need to
- build (current-guix) and then store a couple of full system images.")
- (value
- (mlet* %store-monad ((images (run-install %xfs-root-os
- %xfs-root-os-source
- #:script
- %xfs-root-installation-script))
- (command (qemu-command* images)))
- (run-basic-test %xfs-root-os command "xfs-root-os")))))
- ;;;
- ;;; Installation through the graphical interface.
- ;;;
- (define %syslog-conf
- ;; Syslog configuration that dumps to /dev/console, so we can see the
- ;; installer's messages during the test.
- (computed-file "syslog.conf"
- #~(begin
- (copy-file #$%default-syslog.conf #$output)
- (chmod #$output #o644)
- (let ((port (open-file #$output "a")))
- (display "\n*.info /dev/console\n" port)
- #t))))
- (define (operating-system-with-console-syslog os)
- "Return OS with a syslog service that writes to /dev/console."
- (operating-system
- (inherit os)
- (services (modify-services (operating-system-user-services os)
- (syslog-service-type config
- =>
- (syslog-configuration
- (inherit config)
- (config-file %syslog-conf)))))))
- (define %root-password "foo")
- (define* (gui-test-program marionette
- #:key
- (desktop? #f)
- (encrypted? #f)
- (uefi-support? #f)
- (system (%current-system)))
- #~(let ()
- (define (screenshot file)
- (marionette-control (string-append "screendump " file)
- #$marionette))
- (define-syntax-rule (marionette-eval* exp marionette)
- (or (marionette-eval exp marionette)
- (throw 'marionette-eval-failure 'exp)))
- (setvbuf (current-output-port) 'none)
- (setvbuf (current-error-port) 'none)
- (marionette-eval* '(use-modules (gnu installer tests)
- (guix build utils))
- #$marionette)
- ;; Arrange so that 'converse' prints debugging output to the console.
- (marionette-eval* '(let ((console (open-output-file "/dev/console")))
- (setvbuf console 'none)
- (conversation-log-port console))
- #$marionette)
- ;; Tell the installer to not wait for the Connman "online" status.
- (marionette-eval* '(call-with-output-file "/tmp/installer-assume-online"
- (const #t))
- #$marionette)
- ;; Run 'guix system init' with '--no-grafts', to cope with the lack of
- ;; network access.
- (marionette-eval* '(call-with-output-file
- "/tmp/installer-system-init-options"
- (lambda (port)
- (write '("--no-grafts" "--no-substitutes")
- port)))
- #$marionette)
- (marionette-eval* '(define installer-socket
- (open-installer-socket))
- #$marionette)
- (screenshot "installer-start.ppm")
- (marionette-eval* '(choose-locale+keyboard installer-socket)
- #$marionette)
- (screenshot "installer-locale.ppm")
- ;; Choose the host name that the "basic" test expects.
- (marionette-eval* '(enter-host-name+passwords installer-socket
- #:host-name "liberigilo"
- #:root-password
- #$%root-password
- #:users
- '(("alice" "pass1")
- ("bob" "pass2")))
- #$marionette)
- (screenshot "installer-services.ppm")
- (marionette-eval* '(choose-services installer-socket
- #:choose-desktop-environment?
- (const #$desktop?)
- #:choose-network-service?
- (const #f))
- #$marionette)
- (screenshot "installer-partitioning.ppm")
- (marionette-eval* '(choose-partitioning installer-socket
- #:encrypted? #$encrypted?
- #:passphrase #$%luks-passphrase
- #:uefi-support? #$uefi-support?)
- #$marionette)
- (screenshot "installer-run.ppm")
- (unless #$encrypted?
- ;; At this point, user partitions are formatted and the installer is
- ;; waiting for us to start the final step: generating the
- ;; configuration file, etc. Set a fixed UUID on the swap partition
- ;; that matches what 'installation-target-os-for-gui-tests' expects.
- (marionette-eval* '(invoke #$(file-append util-linux "/sbin/swaplabel")
- "-U" "11111111-2222-3333-4444-123456789abc"
- "/dev/vda2")
- #$marionette))
- (marionette-eval* '(start-installation installer-socket)
- #$marionette)
- ;; XXX: The grub-install process uses efibootmgr to add an UEFI Guix
- ;; boot entry. The corresponding UEFI variable is stored in RAM, and
- ;; possibly saved persistently on QEMU reboot in a NvVars file, see:
- ;; https://lists.gnu.org/archive/html/qemu-discuss/2018-04/msg00045.html.
- ;;
- ;; As we are running QEMU with the no-reboot flag, this variable is
- ;; never saved persistently, QEMU fails to boot the installed system and
- ;; an UEFI shell is displayed instead.
- ;;
- ;; To make the installed UEFI system bootable, register Grub as the
- ;; default UEFI boot entry, in the same way as if grub-install was
- ;; invoked with the --removable option.
- (when #$uefi-support?
- (marionette-eval*
- '(begin
- (use-modules (ice-9 match))
- (let ((targets (cond
- ((string-prefix? "x86_64" #$system)
- '("grubx64.efi" "BOOTX64.EFI"))
- ((string-prefix? "i686" #$system)
- '("grubia32.efi" "BOOTIA32.EFI"))
- (else #f))))
- (match targets
- ((src dest)
- (rename-file "/mnt/boot/efi/EFI/Guix"
- "/mnt/boot/efi/EFI/BOOT")
- (rename-file
- (string-append "/mnt/boot/efi/EFI/BOOT/" src)
- (string-append "/mnt/boot/efi/EFI/BOOT/" dest)))
- (_ #f))))
- #$marionette))
- (marionette-eval* '(complete-installation installer-socket)
- #$marionette)
- (sync)
- #t))
- (define %extra-packages
- ;; Packages needed when installing with an encrypted root.
- (list isc-dhcp
- lvm2-static cryptsetup-static e2fsck/static
- loadkeys-static grub-efi fatfsck/static dosfstools))
- (define installation-os-for-gui-tests
- ;; Operating system that contains all of %EXTRA-PACKAGES, needed for the
- ;; target OS, as well as syslog output redirected to the console so we can
- ;; see what the installer is up to.
- (marionette-operating-system
- (operating-system
- (inherit (operating-system-with-console-syslog
- (operating-system-add-packages
- installation-os
- %extra-packages)))
- (kernel-arguments '("console=ttyS0")))
- #:imported-modules '((gnu services herd)
- (gnu installer tests)
- (guix combinators))))
- (define* (installation-target-os-for-gui-tests
- #:key
- (encrypted? #f)
- (uefi-support? #f))
- (operating-system
- (inherit %minimal-os-on-vda)
- (file-systems `(,(file-system
- (device (file-system-label "my-root"))
- (mount-point "/")
- (type "ext4"))
- ,@(if uefi-support?
- (list (file-system
- (device (uuid "1234-ABCD" 'fat))
- (mount-point "/boot/efi")
- (type "vfat")))
- '())
- ,@%base-file-systems))
- (users (append (list (user-account
- (name "alice")
- (comment "Bob's sister")
- (group "users")
- (supplementary-groups
- '("wheel" "audio" "video")))
- (user-account
- (name "bob")
- (comment "Alice's brother")
- (group "users")
- (supplementary-groups
- '("wheel" "audio" "video"))))
- %base-user-accounts))
- ;; The installer does not create a swap device in guided mode with
- ;; encryption support. The installer produces a UUID for the partition;
- ;; this "UUID" is explicitly set in 'gui-test-program' to the value shown
- ;; below.
- (swap-devices
- (if encrypted?
- '()
- (list
- (swap-space
- (target (uuid "11111111-2222-3333-4444-123456789abc"))))))
- (services (cons* (service dhcp-client-service-type)
- (service ntp-service-type)
- (operating-system-user-services %minimal-os-on-vda)))))
- (define* (installation-target-desktop-os-for-gui-tests
- #:key (encrypted? #f))
- (operating-system
- (inherit (installation-target-os-for-gui-tests
- #:encrypted? encrypted?))
- (keyboard-layout (keyboard-layout "us" "altgr-intl"))
- ;; Make sure that all the packages and services that may be used by the
- ;; graphical installer are available.
- (packages (append
- (list openbox awesome i3-wm i3status
- dmenu st ratpoison xterm
- emacs emacs-exwm emacs-desktop-environment)
- %base-packages))
- (services
- (append
- (list (service gnome-desktop-service-type)
- (service xfce-desktop-service-type)
- (service mate-desktop-service-type)
- (service enlightenment-desktop-service-type)
- (set-xorg-configuration
- (xorg-configuration
- (keyboard-layout keyboard-layout)))
- (service marionette-service-type
- (marionette-configuration
- (imported-modules '((gnu services herd)
- (guix build utils)
- (guix combinators))))))
- %desktop-services))))
- (define* (guided-installation-test name
- #:key
- (desktop? #f)
- (encrypted? #f)
- (uefi-support? #f)
- target-os
- (install-size 'guess)
- (target-size (* 2200 MiB)))
- (system-test
- (name name)
- (description
- "Install an OS using the graphical installer and test it.")
- (value
- (mlet* %store-monad
- ((images (run-install target-os '(this is unused)
- #:script #f
- #:os installation-os-for-gui-tests
- #:uefi-support? uefi-support?
- #:install-size install-size
- #:target-size target-size
- #:installation-image-type
- 'uncompressed-iso9660
- #:gui-test
- (lambda (marionette)
- (gui-test-program
- marionette
- #:desktop? desktop?
- #:encrypted? encrypted?
- #:uefi-support? uefi-support?))))
- (command (qemu-command* images
- #:uefi-support? uefi-support?
- #:memory-size 512)))
- (run-basic-test target-os command name
- #:initialization (and encrypted? enter-luks-passphrase)
- #:root-password %root-password
- #:desktop? desktop?)))))
- (define %test-gui-installed-os
- (guided-installation-test
- "gui-installed-os"
- #:target-os (installation-target-os-for-gui-tests)))
- ;; Test the UEFI installation of Guix System using the graphical installer.
- (define %test-gui-uefi-installed-os
- (guided-installation-test
- "gui-uefi-installed-os"
- #:uefi-support? #t
- #:target-os (installation-target-os-for-gui-tests
- #:uefi-support? #t)
- #:target-size (* 3200 MiB)))
- (define %test-gui-installed-os-encrypted
- (guided-installation-test
- "gui-installed-os-encrypted"
- #:encrypted? #t
- #:target-os (installation-target-os-for-gui-tests
- #:encrypted? #t)))
- ;; Building a desktop image is very time and space consuming. Install all
- ;; desktop environments in a single test to reduce the overhead.
- (define %test-gui-installed-desktop-os-encrypted
- (guided-installation-test "gui-installed-desktop-os-encrypted"
- #:desktop? #t
- #:encrypted? #t
- #:target-os
- (installation-target-desktop-os-for-gui-tests
- #:encrypted? #t)
- ;; XXX: The disk-image size guess is too low. Use
- ;; a constant value until this is fixed.
- #:install-size (* 8000 MiB)
- #:target-size (* 9000 MiB)))
- ;;; install.scm ends here
|