1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2017, 2019 Tobias Geerinckx-Rice <me@tobias.gr>
4 ;;; Copyright © 2020 Mathieu Othacehe <m.othacehe@gmail.com>
5 ;;; Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org>
7 ;;; This file is part of GNU Guix.
9 ;;; GNU Guix is free software; you can redistribute it and/or modify it
10 ;;; under the terms of the GNU General Public License as published by
11 ;;; the Free Software Foundation; either version 3 of the License, or (at
12 ;;; your option) any later version.
14 ;;; GNU Guix is distributed in the hope that it will be useful, but
15 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;;; GNU General Public License for more details.
19 ;;; You should have received a copy of the GNU General Public License
20 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
22 (define-module (gnu tests install)
24 #:use-module (gnu bootloader extlinux)
25 #:use-module (gnu image)
26 #:use-module (gnu tests)
27 #:use-module (gnu tests base)
28 #:use-module (gnu system)
29 #:use-module (gnu system image)
30 #:use-module (gnu system install)
31 #:use-module (gnu system vm)
32 #:use-module ((gnu build vm) #:select (qemu-command))
33 #:use-module (gnu packages admin)
34 #:use-module (gnu packages bootloaders)
35 #:use-module (gnu packages commencement) ;for 'guile-final'
36 #:use-module (gnu packages cryptsetup)
37 #:use-module (gnu packages linux)
38 #:use-module (gnu packages ocr)
39 #:use-module (gnu packages openbox)
40 #:use-module (gnu packages package-management)
41 #:use-module (gnu packages ratpoison)
42 #:use-module (gnu packages suckless)
43 #:use-module (gnu packages virtualization)
44 #:use-module (gnu packages wm)
45 #:use-module (gnu packages xorg)
46 #:use-module (gnu services desktop)
47 #:use-module (gnu services networking)
48 #:use-module (gnu services xorg)
49 #:use-module (guix store)
50 #:use-module (guix monads)
51 #:use-module (guix packages)
52 #:use-module (guix grafts)
53 #:use-module (guix gexp)
54 #:use-module (guix utils)
55 #:use-module (srfi srfi-1)
56 #:export (%test-installed-os
57 %test-installed-extlinux-os
58 %test-iso-image-installer
59 %test-separate-store-os
60 %test-separate-home-os
62 %test-encrypted-root-os
67 %test-gui-installed-os
68 %test-gui-installed-os-encrypted
69 %test-gui-installed-desktop-os-encrypted))
73 ;;; Test the installation of Guix using the documented approach at the
78 (define-os-with-source (%minimal-os %minimal-os-source)
79 ;; The OS we want to install.
80 (use-modules (gnu) (gnu tests) (srfi srfi-1))
83 (host-name "liberigilo")
84 (timezone "Europe/Paris")
85 (locale "en_US.UTF-8")
87 (bootloader (bootloader-configuration
88 (bootloader grub-bootloader)
90 (kernel-arguments '("console=ttyS0"))
91 (file-systems (cons (file-system
92 (device (file-system-label "my-root"))
96 (users (cons (user-account
98 (comment "Bob's sister")
100 (supplementary-groups '("wheel" "audio" "video")))
101 %base-user-accounts))
102 (services (cons (service marionette-service-type
103 (marionette-configuration
104 (imported-modules '((gnu services herd)
106 (guix combinators)))))
109 (define (operating-system-add-packages os packages)
110 "Append PACKAGES to OS packages list."
113 (packages (append packages (operating-system-packages os)))))
115 (define-os-with-source (%minimal-extlinux-os
116 %minimal-extlinux-os-source)
117 (use-modules (gnu) (gnu tests) (gnu bootloader extlinux)
121 (host-name "liberigilo")
122 (timezone "Europe/Paris")
123 (locale "en_US.UTF-8")
125 (bootloader (bootloader-configuration
126 (bootloader extlinux-bootloader-gpt)
127 (target "/dev/vdb")))
128 (kernel-arguments '("console=ttyS0"))
129 (file-systems (cons (file-system
130 (device (file-system-label "my-root"))
134 (services (cons (service marionette-service-type
135 (marionette-configuration
136 (imported-modules '((gnu services herd)
137 (guix combinators)))))
140 (define (operating-system-with-current-guix os)
141 "Return a variant of OS that uses the current Guix."
144 (services (modify-services (operating-system-user-services os)
145 (guix-service-type config =>
148 (guix (current-guix))))))))
151 (define MiB (expt 2 20))
153 (define %simple-installation-script
154 ;; Shell script of a simple installation.
160 export GUIX_BUILD_OPTIONS=--no-grafts
162 parted --script /dev/vdb mklabel gpt \\
163 mkpart primary ext2 1M 3M \\
164 mkpart primary ext2 3M 1.4G \\
167 mkfs.ext4 -L my-root /dev/vdb2
170 herd start cow-store /mnt
172 cp /etc/target-config.scm /mnt/etc/config.scm
173 guix system init /mnt/etc/config.scm /mnt --no-substitutes
177 (define %extlinux-gpt-installation-script
178 ;; Shell script of a simple installation.
179 ;; As syslinux 6.0.3 does not handle 64bits ext4 partitions,
180 ;; we make sure to pass -O '^64bit' to mkfs.
186 export GUIX_BUILD_OPTIONS=--no-grafts
188 parted --script /dev/vdb mklabel gpt \\
189 mkpart ext2 1M 1.4G \\
191 mkfs.ext4 -L my-root -O '^64bit' /dev/vdb1
194 herd start cow-store /mnt
196 cp /etc/target-config.scm /mnt/etc/config.scm
197 guix system init /mnt/etc/config.scm /mnt --no-substitutes
201 (define* (run-install target-os target-os-source
203 (script %simple-installation-script)
206 (os (marionette-operating-system
208 ;; Since the image has no network access, use the
209 ;; current Guix so the store items we need are in
210 ;; the image and add packages provided.
211 (inherit (operating-system-add-packages
212 (operating-system-with-current-guix
215 (kernel-arguments '("console=ttyS0")))
216 #:imported-modules '((gnu services herd)
217 (gnu installer tests)
218 (guix combinators))))
219 (installation-disk-image-file-system-type "ext4")
220 (install-size 'guess)
221 (target-size (* 2200 MiB)))
222 "Run SCRIPT (a shell script following the system installation procedure) in
223 OS to install TARGET-OS. Return a VM image of TARGET-SIZE bytes containing
224 the installed system. The packages specified in PACKAGES will be appended to
225 packages defined in installation-os."
227 (mlet* %store-monad ((_ (set-grafting #f))
228 (system (current-system))
229 (target (operating-system-derivation target-os))
231 ;; Since the installation system has no network access,
232 ;; we cheat a little bit by adding TARGET to its GC
233 ;; roots. This way, we know 'guix system init' will
234 ;; succeed. Also add guile-final, which is pulled in
235 ;; through provenance.drv and may not always be present.
241 installation-disk-image-file-system-type))
244 (operating-system-with-gc-roots
245 os (list target guile-final)))
246 ;; Don't provide substitutes; too big.
247 (substitutable? #f)))))
249 (with-imported-modules '((guix build utils)
250 (gnu build marionette))
252 (use-modules (guix build utils)
253 (gnu build marionette))
255 (set-path-environment-variable "PATH" '("bin")
256 (list #$qemu-minimal))
258 (system* "qemu-img" "create" "-f" "qcow2"
259 #$output #$(number->string target-size))
263 `(,(which #$(qemu-command system))
267 ((string=? "ext4" installation-disk-image-file-system-type)
269 ,(string-append "file=" #$image
270 ",if=virtio,readonly")))
271 ((string=? "iso9660" installation-disk-image-file-system-type)
272 #~("-cdrom" #$image))
275 "unsupported installation-disk-image-file-system-type:"
276 installation-disk-image-file-system-type)))
278 ,(string-append "file=" #$output ",if=virtio")
279 ,@(if (file-exists? "/dev/kvm")
283 (pk 'uname (marionette-eval '(uname) marionette))
286 (marionette-eval '(begin
287 (use-modules (gnu services herd))
291 (when #$(->bool script)
292 (marionette-eval '(call-with-output-file "/etc/target-config.scm"
294 (write '#$target-os-source port)))
297 ;; Run SCRIPT. It typically invokes 'reboot' as a last step and
298 ;; thus normally gets killed with SIGTERM by PID 1.
299 (let ((status (marionette-eval '(system #$script) marionette)))
300 (exit (or (equal? (status:term-sig status) SIGTERM)
301 (equal? (status:exit-val status) 0)))))
303 (when #$(->bool gui-test)
304 (wait-for-unix-socket "/var/guix/installer-socket"
306 (format #t "installer socket ready~%")
308 (exit #$(and gui-test
309 (gui-test #~marionette)))))))
311 (gexp->derivation "installation" install
312 #:substitutable? #f))) ;too big
314 (define* (qemu-command/writable-image image #:key (memory-size 256))
315 "Return as a monadic value the command to run QEMU on a writable copy of
316 IMAGE, a disk image. The QEMU VM has access to MEMORY-SIZE MiB of RAM."
317 (mlet %store-monad ((system (current-system)))
318 (return #~(let ((image #$image))
319 ;; First we need a writable copy of the image.
320 (format #t "creating writable image from '~a'...~%" image)
321 (unless (zero? (system* #+(file-append qemu-minimal
323 "create" "-f" "qcow2"
325 (string-append "backing_file=" image)
327 (error "failed to create writable QEMU image" image))
329 (chmod "disk.img" #o644)
330 `(,(string-append #$qemu-minimal "/bin/"
331 #$(qemu-command system))
332 ,@(if (file-exists? "/dev/kvm")
335 "-no-reboot" "-m" #$(number->string memory-size)
336 "-drive" "file=disk.img,if=virtio")))))
338 (define %test-installed-os
340 (name "installed-os")
342 "Test basic functionality of an OS installed like one would do by hand.
343 This test is expensive in terms of CPU and storage usage since we need to
344 build (current-guix) and then store a couple of full system images.")
346 (mlet* %store-monad ((image (run-install %minimal-os %minimal-os-source))
347 (command (qemu-command/writable-image image)))
348 (run-basic-test %minimal-os command
351 (define %test-installed-extlinux-os
353 (name "installed-extlinux-os")
355 "Test basic functionality of an OS booted with an extlinux bootloader. As
356 per %test-installed-os, this test is expensive in terms of CPU and storage.")
358 (mlet* %store-monad ((image (run-install %minimal-extlinux-os
359 %minimal-extlinux-os-source
363 %extlinux-gpt-installation-script))
364 (command (qemu-command/writable-image image)))
365 (run-basic-test %minimal-extlinux-os command
366 "installed-extlinux-os")))))
370 ;;; Installation through an ISO image.
373 (define-os-with-source (%minimal-os-on-vda %minimal-os-on-vda-source)
374 ;; The OS we want to install.
375 (use-modules (gnu) (gnu tests) (srfi srfi-1))
378 (host-name "liberigilo")
379 (timezone "Europe/Paris")
380 (locale "en_US.UTF-8")
382 (bootloader (bootloader-configuration
383 (bootloader grub-bootloader)
384 (target "/dev/vda")))
385 (kernel-arguments '("console=ttyS0"))
386 (file-systems (cons (file-system
387 (device (file-system-label "my-root"))
391 (users (cons (user-account
393 (comment "Bob's sister")
395 (supplementary-groups '("wheel" "audio" "video")))
396 %base-user-accounts))
397 (services (cons (service marionette-service-type
398 (marionette-configuration
399 (imported-modules '((gnu services herd)
401 (guix combinators)))))
404 (define %simple-installation-script-for-/dev/vda
405 ;; Shell script of a simple installation.
411 export GUIX_BUILD_OPTIONS=--no-grafts
413 parted --script /dev/vda mklabel gpt \\
414 mkpart primary ext2 1M 3M \\
415 mkpart primary ext2 3M 1.4G \\
418 mkfs.ext4 -L my-root /dev/vda2
421 herd start cow-store /mnt
423 cp /etc/target-config.scm /mnt/etc/config.scm
424 guix system init /mnt/etc/config.scm /mnt --no-substitutes
428 (define %test-iso-image-installer
430 (name "iso-image-installer")
434 (mlet* %store-monad ((image (run-install
436 %minimal-os-on-vda-source
438 %simple-installation-script-for-/dev/vda
439 #:installation-disk-image-file-system-type
441 (command (qemu-command/writable-image image)))
442 (run-basic-test %minimal-os-on-vda command name)))))
449 (define-os-with-source (%separate-home-os %separate-home-os-source)
450 ;; The OS we want to install.
451 (use-modules (gnu) (gnu tests) (srfi srfi-1))
454 (host-name "liberigilo")
455 (timezone "Europe/Paris")
456 (locale "en_US.utf8")
458 (bootloader (bootloader-configuration
459 (bootloader grub-bootloader)
460 (target "/dev/vdb")))
461 (kernel-arguments '("console=ttyS0"))
462 (file-systems (cons* (file-system
463 (device (file-system-label "my-root"))
468 (mount-point "/home")
471 (users (cons* (user-account
477 %base-user-accounts))
478 (services (cons (service marionette-service-type
479 (marionette-configuration
480 (imported-modules '((gnu services herd)
481 (guix combinators)))))
484 (define %test-separate-home-os
486 (name "separate-home-os")
488 "Test basic functionality of an installed OS with a separate /home
489 partition. In particular, home directories must be correctly created (see
490 <https://bugs.gnu.org/21108>).")
492 (mlet* %store-monad ((image (run-install %separate-home-os
493 %separate-home-os-source
495 %simple-installation-script))
496 (command (qemu-command/writable-image image)))
497 (run-basic-test %separate-home-os command "separate-home-os")))))
501 ;;; Separate /gnu/store partition.
504 (define-os-with-source (%separate-store-os %separate-store-os-source)
505 ;; The OS we want to install.
506 (use-modules (gnu) (gnu tests) (srfi srfi-1))
509 (host-name "liberigilo")
510 (timezone "Europe/Paris")
511 (locale "en_US.UTF-8")
513 (bootloader (bootloader-configuration
514 (bootloader grub-bootloader)
515 (target "/dev/vdb")))
516 (kernel-arguments '("console=ttyS0"))
517 (file-systems (cons* (file-system
518 (device (file-system-label "root-fs"))
522 (device (file-system-label "store-fs"))
526 (users %base-user-accounts)
527 (services (cons (service marionette-service-type
528 (marionette-configuration
529 (imported-modules '((gnu services herd)
530 (guix combinators)))))
533 (define %separate-store-installation-script
534 ;; Installation with a separate /gnu partition.
540 export GUIX_BUILD_OPTIONS=--no-grafts
542 parted --script /dev/vdb mklabel gpt \\
543 mkpart primary ext2 1M 3M \\
544 mkpart primary ext2 3M 400M \\
545 mkpart primary ext2 400M 2.1G \\
548 mkfs.ext4 -L root-fs /dev/vdb2
549 mkfs.ext4 -L store-fs /dev/vdb3
552 mount /dev/vdb3 /mnt/gnu
555 herd start cow-store /mnt
557 cp /etc/target-config.scm /mnt/etc/config.scm
558 guix system init /mnt/etc/config.scm /mnt --no-substitutes
562 (define %test-separate-store-os
564 (name "separate-store-os")
566 "Test basic functionality of an OS installed like one would do by hand,
567 where /gnu lives on a separate partition.")
569 (mlet* %store-monad ((image (run-install %separate-store-os
570 %separate-store-os-source
572 %separate-store-installation-script))
573 (command (qemu-command/writable-image image)))
574 (run-basic-test %separate-store-os command "separate-store-os")))))
578 ;;; RAID root device.
581 (define-os-with-source (%raid-root-os %raid-root-os-source)
582 ;; An OS whose root partition is a RAID partition.
583 (use-modules (gnu) (gnu tests))
586 (host-name "raidified")
587 (timezone "Europe/Paris")
588 (locale "en_US.utf8")
590 (bootloader (bootloader-configuration
591 (bootloader grub-bootloader)
592 (target "/dev/vdb")))
593 (kernel-arguments '("console=ttyS0"))
595 ;; Add a kernel module for RAID-1 (aka. "mirror").
596 (initrd-modules (cons "raid1" %base-initrd-modules))
598 (mapped-devices (list (mapped-device
599 (source (list "/dev/vda2" "/dev/vda3"))
601 (type raid-device-mapping))))
602 (file-systems (cons (file-system
603 (device (file-system-label "root-fs"))
606 (dependencies mapped-devices))
608 (users %base-user-accounts)
609 (services (cons (service marionette-service-type
610 (marionette-configuration
611 (imported-modules '((gnu services herd)
612 (guix combinators)))))
615 (define %raid-root-installation-script
616 ;; Installation with a separate /gnu partition. See
617 ;; <https://raid.wiki.kernel.org/index.php/RAID_setup> for more on RAID and
624 export GUIX_BUILD_OPTIONS=--no-grafts
625 parted --script /dev/vdb mklabel gpt \\
626 mkpart primary ext2 1M 3M \\
627 mkpart primary ext2 3M 1.4G \\
628 mkpart primary ext2 1.4G 2.8G \\
631 yes | mdadm --create /dev/md0 --verbose --level=mirror --raid-devices=2 \\
633 mkfs.ext4 -L root-fs /dev/md0
636 herd start cow-store /mnt
638 cp /etc/target-config.scm /mnt/etc/config.scm
639 guix system init /mnt/etc/config.scm /mnt --no-substitutes
643 (define %test-raid-root-os
645 (name "raid-root-os")
647 "Test functionality of an OS installed with a RAID root partition managed
650 (mlet* %store-monad ((image (run-install %raid-root-os
653 %raid-root-installation-script
654 #:target-size (* 2800 MiB)))
655 (command (qemu-command/writable-image image)))
656 (run-basic-test %raid-root-os
657 `(,@command) "raid-root-os")))))
661 ;;; LUKS-encrypted root file system.
664 (define-os-with-source (%encrypted-root-os %encrypted-root-os-source)
665 ;; The OS we want to install.
666 (use-modules (gnu) (gnu tests) (srfi srfi-1))
669 (host-name "liberigilo")
670 (timezone "Europe/Paris")
671 (locale "en_US.UTF-8")
673 (bootloader (bootloader-configuration
674 (bootloader grub-bootloader)
675 (target "/dev/vdb")))
677 ;; Note: Do not pass "console=ttyS0" so we can use our passphrase prompt
678 ;; detection logic in 'enter-luks-passphrase'.
680 (mapped-devices (list (mapped-device
681 (source (uuid "12345678-1234-1234-1234-123456789abc"))
682 (target "the-root-device")
683 (type luks-device-mapping))))
684 (file-systems (cons (file-system
685 (device "/dev/mapper/the-root-device")
689 (users (cons (user-account
692 (supplementary-groups '("wheel" "audio" "video")))
693 %base-user-accounts))
694 (services (cons (service marionette-service-type
695 (marionette-configuration
696 (imported-modules '((gnu services herd)
697 (guix combinators)))))
700 (define %luks-passphrase
701 ;; LUKS encryption passphrase used in tests.
704 (define %encrypted-root-installation-script
705 ;; Shell script of a simple installation.
711 export GUIX_BUILD_OPTIONS=--no-grafts
712 ls -l /run/current-system/gc-roots
713 parted --script /dev/vdb mklabel gpt \\
714 mkpart primary ext2 1M 3M \\
715 mkpart primary ext2 3M 1.4G \\
718 echo -n " %luks-passphrase " | \\
719 cryptsetup luksFormat --uuid=12345678-1234-1234-1234-123456789abc -q /dev/vdb2 -
720 echo -n " %luks-passphrase " | \\
721 cryptsetup open --type luks --key-file - /dev/vdb2 the-root-device
722 mkfs.ext4 -L my-root /dev/mapper/the-root-device
723 mount LABEL=my-root /mnt
724 herd start cow-store /mnt
726 cp /etc/target-config.scm /mnt/etc/config.scm
727 guix system build /mnt/etc/config.scm
728 guix system init /mnt/etc/config.scm /mnt --no-substitutes
732 (define (enter-luks-passphrase marionette)
733 "Return a gexp to be inserted in the basic system test running on MARIONETTE
734 to enter the LUKS passphrase."
735 (let ((ocrad (file-append ocrad "/bin/ocrad")))
737 (define (passphrase-prompt? text)
738 (string-contains (pk 'screen-text text) "Enter pass"))
740 (define (bios-boot-screen? text)
741 ;; Return true if TEXT corresponds to the boot screen, before GRUB's
743 (string-prefix? "SeaBIOS" text))
745 (test-assert "enter LUKS passphrase for GRUB"
747 ;; At this point we have no choice but to use OCR to determine
748 ;; when the passphrase should be entered.
749 (wait-for-screen-text #$marionette passphrase-prompt?
751 (marionette-type #$(string-append %luks-passphrase "\n")
754 ;; Now wait until we leave the boot screen. This is necessary so
755 ;; we can then be sure we match the "Enter passphrase" prompt from
756 ;; 'cryptsetup', in the initrd.
757 (wait-for-screen-text #$marionette (negate bios-boot-screen?)
761 (test-assert "enter LUKS passphrase for the initrd"
763 ;; XXX: Here we use OCR as well but we could instead use QEMU
764 ;; '-serial stdio' and run it in an input pipe,
765 (wait-for-screen-text #$marionette passphrase-prompt?
768 (marionette-type #$(string-append %luks-passphrase "\n")
771 ;; Take a screenshot for debugging purposes.
772 (marionette-control (string-append "screendump " #$output
773 "/post-initrd-passphrase.ppm")
776 (define %test-encrypted-root-os
778 (name "encrypted-root-os")
780 "Test basic functionality of an OS installed like one would do by hand.
781 This test is expensive in terms of CPU and storage usage since we need to
782 build (current-guix) and then store a couple of full system images.")
784 (mlet* %store-monad ((image (run-install %encrypted-root-os
785 %encrypted-root-os-source
787 %encrypted-root-installation-script))
788 (command (qemu-command/writable-image image)))
789 (run-basic-test %encrypted-root-os command "encrypted-root-os"
790 #:initialization enter-luks-passphrase)))))
794 ;;; Btrfs root file system.
797 (define-os-with-source (%btrfs-root-os %btrfs-root-os-source)
798 ;; The OS we want to install.
799 (use-modules (gnu) (gnu tests) (srfi srfi-1))
802 (host-name "liberigilo")
803 (timezone "Europe/Paris")
804 (locale "en_US.UTF-8")
806 (bootloader (bootloader-configuration
807 (bootloader grub-bootloader)
808 (target "/dev/vdb")))
809 (kernel-arguments '("console=ttyS0"))
810 (file-systems (cons (file-system
811 (device (file-system-label "my-root"))
815 (users (cons (user-account
818 (supplementary-groups '("wheel" "audio" "video")))
819 %base-user-accounts))
820 (services (cons (service marionette-service-type
821 (marionette-configuration
822 (imported-modules '((gnu services herd)
823 (guix combinators)))))
826 (define %btrfs-root-installation-script
827 ;; Shell script of a simple installation.
833 export GUIX_BUILD_OPTIONS=--no-grafts
834 ls -l /run/current-system/gc-roots
835 parted --script /dev/vdb mklabel gpt \\
836 mkpart primary ext2 1M 3M \\
837 mkpart primary ext2 3M 2G \\
840 mkfs.btrfs -L my-root /dev/vdb2
842 btrfs subvolume create /mnt/home
843 herd start cow-store /mnt
845 cp /etc/target-config.scm /mnt/etc/config.scm
846 guix system build /mnt/etc/config.scm
847 guix system init /mnt/etc/config.scm /mnt --no-substitutes
851 (define %test-btrfs-root-os
853 (name "btrfs-root-os")
855 "Test basic functionality of an OS installed like one would do by hand.
856 This test is expensive in terms of CPU and storage usage since we need to
857 build (current-guix) and then store a couple of full system images.")
859 (mlet* %store-monad ((image (run-install %btrfs-root-os
860 %btrfs-root-os-source
862 %btrfs-root-installation-script))
863 (command (qemu-command/writable-image image)))
864 (run-basic-test %btrfs-root-os command "btrfs-root-os")))))
868 ;;; JFS root file system.
871 (define-os-with-source (%jfs-root-os %jfs-root-os-source)
872 ;; The OS we want to install.
873 (use-modules (gnu) (gnu tests) (srfi srfi-1))
876 (host-name "liberigilo")
877 (timezone "Europe/Paris")
878 (locale "en_US.UTF-8")
880 (bootloader (bootloader-configuration
881 (bootloader grub-bootloader)
882 (target "/dev/vdb")))
883 (kernel-arguments '("console=ttyS0"))
884 (file-systems (cons (file-system
885 (device (file-system-label "my-root"))
889 (users (cons (user-account
892 (supplementary-groups '("wheel" "audio" "video")))
893 %base-user-accounts))
894 (services (cons (service marionette-service-type
895 (marionette-configuration
896 (imported-modules '((gnu services herd)
897 (guix combinators)))))
900 (define %jfs-root-installation-script
901 ;; Shell script of a simple installation.
907 export GUIX_BUILD_OPTIONS=--no-grafts
908 ls -l /run/current-system/gc-roots
909 parted --script /dev/vdb mklabel gpt \\
910 mkpart primary ext2 1M 3M \\
911 mkpart primary ext2 3M 2G \\
914 jfs_mkfs -L my-root -q /dev/vdb2
916 herd start cow-store /mnt
918 cp /etc/target-config.scm /mnt/etc/config.scm
919 guix system build /mnt/etc/config.scm
920 guix system init /mnt/etc/config.scm /mnt --no-substitutes
924 (define %test-jfs-root-os
928 "Test basic functionality of an OS installed like one would do by hand.
929 This test is expensive in terms of CPU and storage usage since we need to
930 build (current-guix) and then store a couple of full system images.")
932 (mlet* %store-monad ((image (run-install %jfs-root-os
935 %jfs-root-installation-script))
936 (command (qemu-command/writable-image image)))
937 (run-basic-test %jfs-root-os command "jfs-root-os")))))
941 ;;; F2FS root file system.
944 (define-os-with-source (%f2fs-root-os %f2fs-root-os-source)
945 ;; The OS we want to install.
946 (use-modules (gnu) (gnu tests) (srfi srfi-1))
949 (host-name "liberigilo")
950 (timezone "Europe/Paris")
951 (locale "en_US.UTF-8")
953 (bootloader (bootloader-configuration
954 (bootloader grub-bootloader)
955 (target "/dev/vdb")))
956 (kernel-arguments '("console=ttyS0"))
957 (file-systems (cons (file-system
958 (device (file-system-label "my-root"))
962 (users (cons (user-account
965 (supplementary-groups '("wheel" "audio" "video")))
966 %base-user-accounts))
967 (services (cons (service marionette-service-type
968 (marionette-configuration
969 (imported-modules '((gnu services herd)
970 (guix combinators)))))
973 (define %f2fs-root-installation-script
974 ;; Shell script of a simple installation.
980 export GUIX_BUILD_OPTIONS=--no-grafts
981 ls -l /run/current-system/gc-roots
982 parted --script /dev/vdb mklabel gpt \\
983 mkpart primary ext2 1M 3M \\
984 mkpart primary ext2 3M 2G \\
987 mkfs.f2fs -l my-root -q /dev/vdb2
989 herd start cow-store /mnt
991 cp /etc/target-config.scm /mnt/etc/config.scm
992 guix system build /mnt/etc/config.scm
993 guix system init /mnt/etc/config.scm /mnt --no-substitutes
997 (define %test-f2fs-root-os
999 (name "f2fs-root-os")
1001 "Test basic functionality of an OS installed like one would do by hand.
1002 This test is expensive in terms of CPU and storage usage since we need to
1003 build (current-guix) and then store a couple of full system images.")
1005 (mlet* %store-monad ((image (run-install %f2fs-root-os
1006 %f2fs-root-os-source
1008 %f2fs-root-installation-script))
1009 (command (qemu-command/writable-image image)))
1010 (run-basic-test %f2fs-root-os command "f2fs-root-os")))))
1014 ;;; Installation through the graphical interface.
1017 (define %syslog-conf
1018 ;; Syslog configuration that dumps to /dev/console, so we can see the
1019 ;; installer's messages during the test.
1020 (computed-file "syslog.conf"
1022 (copy-file #$%default-syslog.conf #$output)
1023 (chmod #$output #o644)
1024 (let ((port (open-file #$output "a")))
1025 (display "\n*.info /dev/console\n" port)
1028 (define (operating-system-with-console-syslog os)
1029 "Return OS with a syslog service that writes to /dev/console."
1032 (services (modify-services (operating-system-user-services os)
1033 (syslog-service-type config
1035 (syslog-configuration
1037 (config-file %syslog-conf)))))))
1039 (define %root-password "foo")
1041 (define* (gui-test-program marionette
1046 (define (screenshot file)
1047 (marionette-control (string-append "screendump " file)
1050 (define-syntax-rule (marionette-eval* exp marionette)
1051 (or (marionette-eval exp marionette)
1052 (throw 'marionette-eval-failure 'exp)))
1054 (setvbuf (current-output-port) 'none)
1055 (setvbuf (current-error-port) 'none)
1057 (marionette-eval* '(use-modules (gnu installer tests))
1060 ;; Arrange so that 'converse' prints debugging output to the console.
1061 (marionette-eval* '(let ((console (open-output-file "/dev/console")))
1062 (setvbuf console 'none)
1063 (conversation-log-port console))
1066 ;; Tell the installer to not wait for the Connman "online" status.
1067 (marionette-eval* '(call-with-output-file "/tmp/installer-assume-online"
1071 ;; Run 'guix system init' with '--no-grafts', to cope with the lack of
1073 (marionette-eval* '(call-with-output-file
1074 "/tmp/installer-system-init-options"
1076 (write '("--no-grafts" "--no-substitutes")
1080 (marionette-eval* '(define installer-socket
1081 (open-installer-socket))
1083 (screenshot "installer-start.ppm")
1085 (marionette-eval* '(choose-locale+keyboard installer-socket)
1087 (screenshot "installer-locale.ppm")
1089 ;; Choose the host name that the "basic" test expects.
1090 (marionette-eval* '(enter-host-name+passwords installer-socket
1091 #:host-name "liberigilo"
1098 (screenshot "installer-services.ppm")
1100 (marionette-eval* '(choose-services installer-socket
1101 #:choose-desktop-environment?
1103 #:choose-network-service?
1106 (screenshot "installer-partitioning.ppm")
1108 (marionette-eval* '(choose-partitioning installer-socket
1109 #:encrypted? #$encrypted?
1110 #:passphrase #$%luks-passphrase)
1112 (screenshot "installer-run.ppm")
1114 (marionette-eval* '(conclude-installation installer-socket)
1120 (define %extra-packages
1121 ;; Packages needed when installing with an encrypted root.
1123 lvm2-static cryptsetup-static e2fsck/static
1126 (define installation-os-for-gui-tests
1127 ;; Operating system that contains all of %EXTRA-PACKAGES, needed for the
1128 ;; target OS, as well as syslog output redirected to the console so we can
1129 ;; see what the installer is up to.
1130 (marionette-operating-system
1132 (inherit (operating-system-with-console-syslog
1133 (operating-system-add-packages
1134 (operating-system-with-current-guix
1137 (kernel-arguments '("console=ttyS0")))
1138 #:imported-modules '((gnu services herd)
1139 (gnu installer tests)
1140 (guix combinators))))
1142 (define* (installation-target-os-for-gui-tests
1143 #:key (encrypted? #f))
1145 (inherit %minimal-os-on-vda)
1146 (users (append (list (user-account
1148 (comment "Bob's sister")
1150 (supplementary-groups
1151 '("wheel" "audio" "video")))
1154 (comment "Alice's brother")
1156 (supplementary-groups
1157 '("wheel" "audio" "video"))))
1158 %base-user-accounts))
1159 ;; The installer does not create a swap device in guided mode with
1160 ;; encryption support.
1161 (swap-devices (if encrypted? '() '("/dev/vda2")))
1162 (services (cons (service dhcp-client-service-type)
1163 (operating-system-user-services %minimal-os-on-vda)))))
1165 (define* (installation-target-desktop-os-for-gui-tests
1166 #:key (encrypted? #f))
1168 (inherit (installation-target-os-for-gui-tests
1169 #:encrypted? encrypted?))
1170 (keyboard-layout (keyboard-layout "us" "altgr-intl"))
1172 ;; Make sure that all the packages and services that may be used by the
1173 ;; graphical installer are available.
1175 (list openbox awesome i3-wm i3status
1176 dmenu st ratpoison xterm)
1180 (list (service gnome-desktop-service-type)
1181 (service xfce-desktop-service-type)
1182 (service mate-desktop-service-type)
1183 (service enlightenment-desktop-service-type)
1184 (set-xorg-configuration
1186 (keyboard-layout keyboard-layout)))
1187 (service marionette-service-type
1188 (marionette-configuration
1189 (imported-modules '((gnu services herd)
1191 (guix combinators))))))
1192 %desktop-services))))
1194 (define* (guided-installation-test name
1199 (install-size 'guess)
1200 (target-size (* 2200 MiB)))
1204 "Install an OS using the graphical installer and test it.")
1207 ((image (run-install target-os '(this is unused)
1209 #:os installation-os-for-gui-tests
1210 #:install-size install-size
1211 #:target-size target-size
1212 #:installation-disk-image-file-system-type
1215 (lambda (marionette)
1219 #:encrypted? encrypted?))))
1220 (command (qemu-command/writable-image image)))
1221 (run-basic-test target-os command name
1222 #:initialization (and encrypted? enter-luks-passphrase)
1223 #:root-password %root-password)))))
1225 (define %test-gui-installed-os
1226 (guided-installation-test
1228 #:target-os (installation-target-os-for-gui-tests)))
1230 (define %test-gui-installed-os-encrypted
1231 (guided-installation-test
1232 "gui-installed-os-encrypted"
1234 #:target-os (installation-target-os-for-gui-tests
1237 ;; Building a desktop image is very time and space consuming. Install all
1238 ;; desktop environments in a single test to reduce the overhead.
1239 (define %test-gui-installed-desktop-os-encrypted
1240 (guided-installation-test "gui-installed-desktop-os-encrypted"
1244 (installation-target-desktop-os-for-gui-tests
1246 ;; XXX: The disk-image size guess is too low. Use
1247 ;; a constant value until this is fixed.
1248 #:install-size (* 8000 MiB)
1249 #:target-size (* 9000 MiB)))
1251 ;;; install.scm ends here