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 cryptsetup)
36 #:use-module (gnu packages linux)
37 #:use-module (gnu packages ocr)
38 #:use-module (gnu packages openbox)
39 #:use-module (gnu packages package-management)
40 #:use-module (gnu packages ratpoison)
41 #:use-module (gnu packages suckless)
42 #:use-module (gnu packages virtualization)
43 #:use-module (gnu packages wm)
44 #:use-module (gnu packages xorg)
45 #:use-module (gnu services desktop)
46 #:use-module (gnu services networking)
47 #:use-module (gnu services xorg)
48 #:use-module (guix store)
49 #:use-module (guix monads)
50 #:use-module (guix packages)
51 #:use-module (guix grafts)
52 #:use-module (guix gexp)
53 #:use-module (guix utils)
54 #:use-module (srfi srfi-1)
55 #:export (%test-installed-os
56 %test-installed-extlinux-os
57 %test-iso-image-installer
58 %test-separate-store-os
59 %test-separate-home-os
61 %test-encrypted-root-os
66 %test-gui-installed-os
67 %test-gui-installed-os-encrypted
68 %test-gui-installed-desktop-os-encrypted))
72 ;;; Test the installation of Guix using the documented approach at the
77 (define-os-with-source (%minimal-os %minimal-os-source)
78 ;; The OS we want to install.
79 (use-modules (gnu) (gnu tests) (srfi srfi-1))
82 (host-name "liberigilo")
83 (timezone "Europe/Paris")
84 (locale "en_US.UTF-8")
86 (bootloader (bootloader-configuration
87 (bootloader grub-bootloader)
89 (kernel-arguments '("console=ttyS0"))
90 (file-systems (cons (file-system
91 (device (file-system-label "my-root"))
95 (users (cons (user-account
97 (comment "Bob's sister")
99 (supplementary-groups '("wheel" "audio" "video")))
100 %base-user-accounts))
101 (services (cons (service marionette-service-type
102 (marionette-configuration
103 (imported-modules '((gnu services herd)
105 (guix combinators)))))
108 (define (operating-system-add-packages os packages)
109 "Append PACKAGES to OS packages list."
112 (packages (append packages (operating-system-packages os)))))
114 (define-os-with-source (%minimal-extlinux-os
115 %minimal-extlinux-os-source)
116 (use-modules (gnu) (gnu tests) (gnu bootloader extlinux)
120 (host-name "liberigilo")
121 (timezone "Europe/Paris")
122 (locale "en_US.UTF-8")
124 (bootloader (bootloader-configuration
125 (bootloader extlinux-bootloader-gpt)
126 (target "/dev/vdb")))
127 (kernel-arguments '("console=ttyS0"))
128 (file-systems (cons (file-system
129 (device (file-system-label "my-root"))
133 (services (cons (service marionette-service-type
134 (marionette-configuration
135 (imported-modules '((gnu services herd)
136 (guix combinators)))))
139 (define (operating-system-with-current-guix os)
140 "Return a variant of OS that uses the current Guix."
143 (services (modify-services (operating-system-user-services os)
144 (guix-service-type config =>
147 (guix (current-guix))))))))
150 (define MiB (expt 2 20))
152 (define %simple-installation-script
153 ;; Shell script of a simple installation.
159 export GUIX_BUILD_OPTIONS=--no-grafts
161 parted --script /dev/vdb mklabel gpt \\
162 mkpart primary ext2 1M 3M \\
163 mkpart primary ext2 3M 1.4G \\
166 mkfs.ext4 -L my-root /dev/vdb2
169 herd start cow-store /mnt
171 cp /etc/target-config.scm /mnt/etc/config.scm
172 guix system init /mnt/etc/config.scm /mnt --no-substitutes
176 (define %extlinux-gpt-installation-script
177 ;; Shell script of a simple installation.
178 ;; As syslinux 6.0.3 does not handle 64bits ext4 partitions,
179 ;; we make sure to pass -O '^64bit' to mkfs.
185 export GUIX_BUILD_OPTIONS=--no-grafts
187 parted --script /dev/vdb mklabel gpt \\
188 mkpart ext2 1M 1.4G \\
190 mkfs.ext4 -L my-root -O '^64bit' /dev/vdb1
193 herd start cow-store /mnt
195 cp /etc/target-config.scm /mnt/etc/config.scm
196 guix system init /mnt/etc/config.scm /mnt --no-substitutes
200 (define* (run-install target-os target-os-source
202 (script %simple-installation-script)
205 (os (marionette-operating-system
207 ;; Since the image has no network access, use the
208 ;; current Guix so the store items we need are in
209 ;; the image and add packages provided.
210 (inherit (operating-system-add-packages
211 (operating-system-with-current-guix
214 (kernel-arguments '("console=ttyS0")))
215 #:imported-modules '((gnu services herd)
216 (gnu installer tests)
217 (guix combinators))))
218 (installation-disk-image-file-system-type "ext4")
219 (install-size 'guess)
220 (target-size (* 2200 MiB)))
221 "Run SCRIPT (a shell script following the system installation procedure) in
222 OS to install TARGET-OS. Return a VM image of TARGET-SIZE bytes containing
223 the installed system. The packages specified in PACKAGES will be appended to
224 packages defined in installation-os."
226 (mlet* %store-monad ((_ (set-grafting #f))
227 (system (current-system))
228 (target (operating-system-derivation target-os))
230 ;; Since the installation system has no network access,
231 ;; we cheat a little bit by adding TARGET to its GC
232 ;; roots. This way, we know 'guix system init' will
239 installation-disk-image-file-system-type))
242 (operating-system-with-gc-roots
244 ;; Don't provide substitutes; too big.
245 (substitutable? #f)))))
247 (with-imported-modules '((guix build utils)
248 (gnu build marionette))
250 (use-modules (guix build utils)
251 (gnu build marionette))
253 (set-path-environment-variable "PATH" '("bin")
254 (list #$qemu-minimal))
256 (system* "qemu-img" "create" "-f" "qcow2"
257 #$output #$(number->string target-size))
261 `(,(which #$(qemu-command system))
265 ((string=? "ext4" installation-disk-image-file-system-type)
267 ,(string-append "file=" #$image
268 ",if=virtio,readonly")))
269 ((string=? "iso9660" installation-disk-image-file-system-type)
270 #~("-cdrom" #$image))
273 "unsupported installation-disk-image-file-system-type:"
274 installation-disk-image-file-system-type)))
276 ,(string-append "file=" #$output ",if=virtio")
277 ,@(if (file-exists? "/dev/kvm")
281 (pk 'uname (marionette-eval '(uname) marionette))
284 (marionette-eval '(begin
285 (use-modules (gnu services herd))
289 (when #$(->bool script)
290 (marionette-eval '(call-with-output-file "/etc/target-config.scm"
292 (write '#$target-os-source port)))
295 ;; Run SCRIPT. It typically invokes 'reboot' as a last step and
296 ;; thus normally gets killed with SIGTERM by PID 1.
297 (let ((status (marionette-eval '(system #$script) marionette)))
298 (exit (or (equal? (status:term-sig status) SIGTERM)
299 (equal? (status:exit-val status) 0)))))
301 (when #$(->bool gui-test)
302 (wait-for-unix-socket "/var/guix/installer-socket"
304 (format #t "installer socket ready~%")
306 (exit #$(and gui-test
307 (gui-test #~marionette)))))))
309 (gexp->derivation "installation" install
310 #:substitutable? #f))) ;too big
312 (define* (qemu-command/writable-image image #:key (memory-size 256))
313 "Return as a monadic value the command to run QEMU on a writable copy of
314 IMAGE, a disk image. The QEMU VM has access to MEMORY-SIZE MiB of RAM."
315 (mlet %store-monad ((system (current-system)))
316 (return #~(let ((image #$image))
317 ;; First we need a writable copy of the image.
318 (format #t "creating writable image from '~a'...~%" image)
319 (unless (zero? (system* #+(file-append qemu-minimal
321 "create" "-f" "qcow2"
323 (string-append "backing_file=" image)
325 (error "failed to create writable QEMU image" image))
327 (chmod "disk.img" #o644)
328 `(,(string-append #$qemu-minimal "/bin/"
329 #$(qemu-command system))
330 ,@(if (file-exists? "/dev/kvm")
333 "-no-reboot" "-m" #$(number->string memory-size)
334 "-drive" "file=disk.img,if=virtio")))))
336 (define %test-installed-os
338 (name "installed-os")
340 "Test basic functionality of an OS installed like one would do by hand.
341 This test is expensive in terms of CPU and storage usage since we need to
342 build (current-guix) and then store a couple of full system images.")
344 (mlet* %store-monad ((image (run-install %minimal-os %minimal-os-source))
345 (command (qemu-command/writable-image image)))
346 (run-basic-test %minimal-os command
349 (define %test-installed-extlinux-os
351 (name "installed-extlinux-os")
353 "Test basic functionality of an OS booted with an extlinux bootloader. As
354 per %test-installed-os, this test is expensive in terms of CPU and storage.")
356 (mlet* %store-monad ((image (run-install %minimal-extlinux-os
357 %minimal-extlinux-os-source
361 %extlinux-gpt-installation-script))
362 (command (qemu-command/writable-image image)))
363 (run-basic-test %minimal-extlinux-os command
364 "installed-extlinux-os")))))
368 ;;; Installation through an ISO image.
371 (define-os-with-source (%minimal-os-on-vda %minimal-os-on-vda-source)
372 ;; The OS we want to install.
373 (use-modules (gnu) (gnu tests) (srfi srfi-1))
376 (host-name "liberigilo")
377 (timezone "Europe/Paris")
378 (locale "en_US.UTF-8")
380 (bootloader (bootloader-configuration
381 (bootloader grub-bootloader)
382 (target "/dev/vda")))
383 (kernel-arguments '("console=ttyS0"))
384 (file-systems (cons (file-system
385 (device (file-system-label "my-root"))
389 (users (cons (user-account
391 (comment "Bob's sister")
393 (supplementary-groups '("wheel" "audio" "video")))
394 %base-user-accounts))
395 (services (cons (service marionette-service-type
396 (marionette-configuration
397 (imported-modules '((gnu services herd)
399 (guix combinators)))))
402 (define %simple-installation-script-for-/dev/vda
403 ;; Shell script of a simple installation.
409 export GUIX_BUILD_OPTIONS=--no-grafts
411 parted --script /dev/vda mklabel gpt \\
412 mkpart primary ext2 1M 3M \\
413 mkpart primary ext2 3M 1.4G \\
416 mkfs.ext4 -L my-root /dev/vda2
419 herd start cow-store /mnt
421 cp /etc/target-config.scm /mnt/etc/config.scm
422 guix system init /mnt/etc/config.scm /mnt --no-substitutes
426 (define %test-iso-image-installer
428 (name "iso-image-installer")
432 (mlet* %store-monad ((image (run-install
434 %minimal-os-on-vda-source
436 %simple-installation-script-for-/dev/vda
437 #:installation-disk-image-file-system-type
439 (command (qemu-command/writable-image image)))
440 (run-basic-test %minimal-os-on-vda command name)))))
447 (define-os-with-source (%separate-home-os %separate-home-os-source)
448 ;; The OS we want to install.
449 (use-modules (gnu) (gnu tests) (srfi srfi-1))
452 (host-name "liberigilo")
453 (timezone "Europe/Paris")
454 (locale "en_US.utf8")
456 (bootloader (bootloader-configuration
457 (bootloader grub-bootloader)
458 (target "/dev/vdb")))
459 (kernel-arguments '("console=ttyS0"))
460 (file-systems (cons* (file-system
461 (device (file-system-label "my-root"))
466 (mount-point "/home")
469 (users (cons* (user-account
475 %base-user-accounts))
476 (services (cons (service marionette-service-type
477 (marionette-configuration
478 (imported-modules '((gnu services herd)
479 (guix combinators)))))
482 (define %test-separate-home-os
484 (name "separate-home-os")
486 "Test basic functionality of an installed OS with a separate /home
487 partition. In particular, home directories must be correctly created (see
488 <https://bugs.gnu.org/21108>).")
490 (mlet* %store-monad ((image (run-install %separate-home-os
491 %separate-home-os-source
493 %simple-installation-script))
494 (command (qemu-command/writable-image image)))
495 (run-basic-test %separate-home-os command "separate-home-os")))))
499 ;;; Separate /gnu/store partition.
502 (define-os-with-source (%separate-store-os %separate-store-os-source)
503 ;; The OS we want to install.
504 (use-modules (gnu) (gnu tests) (srfi srfi-1))
507 (host-name "liberigilo")
508 (timezone "Europe/Paris")
509 (locale "en_US.UTF-8")
511 (bootloader (bootloader-configuration
512 (bootloader grub-bootloader)
513 (target "/dev/vdb")))
514 (kernel-arguments '("console=ttyS0"))
515 (file-systems (cons* (file-system
516 (device (file-system-label "root-fs"))
520 (device (file-system-label "store-fs"))
524 (users %base-user-accounts)
525 (services (cons (service marionette-service-type
526 (marionette-configuration
527 (imported-modules '((gnu services herd)
528 (guix combinators)))))
531 (define %separate-store-installation-script
532 ;; Installation with a separate /gnu partition.
538 export GUIX_BUILD_OPTIONS=--no-grafts
540 parted --script /dev/vdb mklabel gpt \\
541 mkpart primary ext2 1M 3M \\
542 mkpart primary ext2 3M 400M \\
543 mkpart primary ext2 400M 2.1G \\
546 mkfs.ext4 -L root-fs /dev/vdb2
547 mkfs.ext4 -L store-fs /dev/vdb3
550 mount /dev/vdb3 /mnt/gnu
553 herd start cow-store /mnt
555 cp /etc/target-config.scm /mnt/etc/config.scm
556 guix system init /mnt/etc/config.scm /mnt --no-substitutes
560 (define %test-separate-store-os
562 (name "separate-store-os")
564 "Test basic functionality of an OS installed like one would do by hand,
565 where /gnu lives on a separate partition.")
567 (mlet* %store-monad ((image (run-install %separate-store-os
568 %separate-store-os-source
570 %separate-store-installation-script))
571 (command (qemu-command/writable-image image)))
572 (run-basic-test %separate-store-os command "separate-store-os")))))
576 ;;; RAID root device.
579 (define-os-with-source (%raid-root-os %raid-root-os-source)
580 ;; An OS whose root partition is a RAID partition.
581 (use-modules (gnu) (gnu tests))
584 (host-name "raidified")
585 (timezone "Europe/Paris")
586 (locale "en_US.utf8")
588 (bootloader (bootloader-configuration
589 (bootloader grub-bootloader)
590 (target "/dev/vdb")))
591 (kernel-arguments '("console=ttyS0"))
593 ;; Add a kernel module for RAID-1 (aka. "mirror").
594 (initrd-modules (cons "raid1" %base-initrd-modules))
596 (mapped-devices (list (mapped-device
597 (source (list "/dev/vda2" "/dev/vda3"))
599 (type raid-device-mapping))))
600 (file-systems (cons (file-system
601 (device (file-system-label "root-fs"))
604 (dependencies mapped-devices))
606 (users %base-user-accounts)
607 (services (cons (service marionette-service-type
608 (marionette-configuration
609 (imported-modules '((gnu services herd)
610 (guix combinators)))))
613 (define %raid-root-installation-script
614 ;; Installation with a separate /gnu partition. See
615 ;; <https://raid.wiki.kernel.org/index.php/RAID_setup> for more on RAID and
622 export GUIX_BUILD_OPTIONS=--no-grafts
623 parted --script /dev/vdb mklabel gpt \\
624 mkpart primary ext2 1M 3M \\
625 mkpart primary ext2 3M 1.4G \\
626 mkpart primary ext2 1.4G 2.8G \\
629 yes | mdadm --create /dev/md0 --verbose --level=mirror --raid-devices=2 \\
631 mkfs.ext4 -L root-fs /dev/md0
634 herd start cow-store /mnt
636 cp /etc/target-config.scm /mnt/etc/config.scm
637 guix system init /mnt/etc/config.scm /mnt --no-substitutes
641 (define %test-raid-root-os
643 (name "raid-root-os")
645 "Test functionality of an OS installed with a RAID root partition managed
648 (mlet* %store-monad ((image (run-install %raid-root-os
651 %raid-root-installation-script
652 #:target-size (* 2800 MiB)))
653 (command (qemu-command/writable-image image)))
654 (run-basic-test %raid-root-os
655 `(,@command) "raid-root-os")))))
659 ;;; LUKS-encrypted root file system.
662 (define-os-with-source (%encrypted-root-os %encrypted-root-os-source)
663 ;; The OS we want to install.
664 (use-modules (gnu) (gnu tests) (srfi srfi-1))
667 (host-name "liberigilo")
668 (timezone "Europe/Paris")
669 (locale "en_US.UTF-8")
671 (bootloader (bootloader-configuration
672 (bootloader grub-bootloader)
673 (target "/dev/vdb")))
675 ;; Note: Do not pass "console=ttyS0" so we can use our passphrase prompt
676 ;; detection logic in 'enter-luks-passphrase'.
678 (mapped-devices (list (mapped-device
679 (source (uuid "12345678-1234-1234-1234-123456789abc"))
680 (target "the-root-device")
681 (type luks-device-mapping))))
682 (file-systems (cons (file-system
683 (device "/dev/mapper/the-root-device")
687 (users (cons (user-account
690 (supplementary-groups '("wheel" "audio" "video")))
691 %base-user-accounts))
692 (services (cons (service marionette-service-type
693 (marionette-configuration
694 (imported-modules '((gnu services herd)
695 (guix combinators)))))
698 (define %luks-passphrase
699 ;; LUKS encryption passphrase used in tests.
702 (define %encrypted-root-installation-script
703 ;; Shell script of a simple installation.
709 export GUIX_BUILD_OPTIONS=--no-grafts
710 ls -l /run/current-system/gc-roots
711 parted --script /dev/vdb mklabel gpt \\
712 mkpart primary ext2 1M 3M \\
713 mkpart primary ext2 3M 1.4G \\
716 echo -n " %luks-passphrase " | \\
717 cryptsetup luksFormat --uuid=12345678-1234-1234-1234-123456789abc -q /dev/vdb2 -
718 echo -n " %luks-passphrase " | \\
719 cryptsetup open --type luks --key-file - /dev/vdb2 the-root-device
720 mkfs.ext4 -L my-root /dev/mapper/the-root-device
721 mount LABEL=my-root /mnt
722 herd start cow-store /mnt
724 cp /etc/target-config.scm /mnt/etc/config.scm
725 guix system build /mnt/etc/config.scm
726 guix system init /mnt/etc/config.scm /mnt --no-substitutes
730 (define (enter-luks-passphrase marionette)
731 "Return a gexp to be inserted in the basic system test running on MARIONETTE
732 to enter the LUKS passphrase."
733 (let ((ocrad (file-append ocrad "/bin/ocrad")))
735 (define (passphrase-prompt? text)
736 (string-contains (pk 'screen-text text) "Enter pass"))
738 (define (bios-boot-screen? text)
739 ;; Return true if TEXT corresponds to the boot screen, before GRUB's
741 (string-prefix? "SeaBIOS" text))
743 (test-assert "enter LUKS passphrase for GRUB"
745 ;; At this point we have no choice but to use OCR to determine
746 ;; when the passphrase should be entered.
747 (wait-for-screen-text #$marionette passphrase-prompt?
749 (marionette-type #$(string-append %luks-passphrase "\n")
752 ;; Now wait until we leave the boot screen. This is necessary so
753 ;; we can then be sure we match the "Enter passphrase" prompt from
754 ;; 'cryptsetup', in the initrd.
755 (wait-for-screen-text #$marionette (negate bios-boot-screen?)
759 (test-assert "enter LUKS passphrase for the initrd"
761 ;; XXX: Here we use OCR as well but we could instead use QEMU
762 ;; '-serial stdio' and run it in an input pipe,
763 (wait-for-screen-text #$marionette passphrase-prompt?
766 (marionette-type #$(string-append %luks-passphrase "\n")
769 ;; Take a screenshot for debugging purposes.
770 (marionette-control (string-append "screendump " #$output
771 "/post-initrd-passphrase.ppm")
774 (define %test-encrypted-root-os
776 (name "encrypted-root-os")
778 "Test basic functionality of an OS installed like one would do by hand.
779 This test is expensive in terms of CPU and storage usage since we need to
780 build (current-guix) and then store a couple of full system images.")
782 (mlet* %store-monad ((image (run-install %encrypted-root-os
783 %encrypted-root-os-source
785 %encrypted-root-installation-script))
786 (command (qemu-command/writable-image image)))
787 (run-basic-test %encrypted-root-os command "encrypted-root-os"
788 #:initialization enter-luks-passphrase)))))
792 ;;; Btrfs root file system.
795 (define-os-with-source (%btrfs-root-os %btrfs-root-os-source)
796 ;; The OS we want to install.
797 (use-modules (gnu) (gnu tests) (srfi srfi-1))
800 (host-name "liberigilo")
801 (timezone "Europe/Paris")
802 (locale "en_US.UTF-8")
804 (bootloader (bootloader-configuration
805 (bootloader grub-bootloader)
806 (target "/dev/vdb")))
807 (kernel-arguments '("console=ttyS0"))
808 (file-systems (cons (file-system
809 (device (file-system-label "my-root"))
813 (users (cons (user-account
816 (supplementary-groups '("wheel" "audio" "video")))
817 %base-user-accounts))
818 (services (cons (service marionette-service-type
819 (marionette-configuration
820 (imported-modules '((gnu services herd)
821 (guix combinators)))))
824 (define %btrfs-root-installation-script
825 ;; Shell script of a simple installation.
831 export GUIX_BUILD_OPTIONS=--no-grafts
832 ls -l /run/current-system/gc-roots
833 parted --script /dev/vdb mklabel gpt \\
834 mkpart primary ext2 1M 3M \\
835 mkpart primary ext2 3M 2G \\
838 mkfs.btrfs -L my-root /dev/vdb2
840 btrfs subvolume create /mnt/home
841 herd start cow-store /mnt
843 cp /etc/target-config.scm /mnt/etc/config.scm
844 guix system build /mnt/etc/config.scm
845 guix system init /mnt/etc/config.scm /mnt --no-substitutes
849 (define %test-btrfs-root-os
851 (name "btrfs-root-os")
853 "Test basic functionality of an OS installed like one would do by hand.
854 This test is expensive in terms of CPU and storage usage since we need to
855 build (current-guix) and then store a couple of full system images.")
857 (mlet* %store-monad ((image (run-install %btrfs-root-os
858 %btrfs-root-os-source
860 %btrfs-root-installation-script))
861 (command (qemu-command/writable-image image)))
862 (run-basic-test %btrfs-root-os command "btrfs-root-os")))))
866 ;;; JFS root file system.
869 (define-os-with-source (%jfs-root-os %jfs-root-os-source)
870 ;; The OS we want to install.
871 (use-modules (gnu) (gnu tests) (srfi srfi-1))
874 (host-name "liberigilo")
875 (timezone "Europe/Paris")
876 (locale "en_US.UTF-8")
878 (bootloader (bootloader-configuration
879 (bootloader grub-bootloader)
880 (target "/dev/vdb")))
881 (kernel-arguments '("console=ttyS0"))
882 (file-systems (cons (file-system
883 (device (file-system-label "my-root"))
887 (users (cons (user-account
890 (supplementary-groups '("wheel" "audio" "video")))
891 %base-user-accounts))
892 (services (cons (service marionette-service-type
893 (marionette-configuration
894 (imported-modules '((gnu services herd)
895 (guix combinators)))))
898 (define %jfs-root-installation-script
899 ;; Shell script of a simple installation.
905 export GUIX_BUILD_OPTIONS=--no-grafts
906 ls -l /run/current-system/gc-roots
907 parted --script /dev/vdb mklabel gpt \\
908 mkpart primary ext2 1M 3M \\
909 mkpart primary ext2 3M 2G \\
912 jfs_mkfs -L my-root -q /dev/vdb2
914 herd start cow-store /mnt
916 cp /etc/target-config.scm /mnt/etc/config.scm
917 guix system build /mnt/etc/config.scm
918 guix system init /mnt/etc/config.scm /mnt --no-substitutes
922 (define %test-jfs-root-os
926 "Test basic functionality of an OS installed like one would do by hand.
927 This test is expensive in terms of CPU and storage usage since we need to
928 build (current-guix) and then store a couple of full system images.")
930 (mlet* %store-monad ((image (run-install %jfs-root-os
933 %jfs-root-installation-script))
934 (command (qemu-command/writable-image image)))
935 (run-basic-test %jfs-root-os command "jfs-root-os")))))
939 ;;; F2FS root file system.
942 (define-os-with-source (%f2fs-root-os %f2fs-root-os-source)
943 ;; The OS we want to install.
944 (use-modules (gnu) (gnu tests) (srfi srfi-1))
947 (host-name "liberigilo")
948 (timezone "Europe/Paris")
949 (locale "en_US.UTF-8")
951 (bootloader (bootloader-configuration
952 (bootloader grub-bootloader)
953 (target "/dev/vdb")))
954 (kernel-arguments '("console=ttyS0"))
955 (file-systems (cons (file-system
956 (device (file-system-label "my-root"))
960 (users (cons (user-account
963 (supplementary-groups '("wheel" "audio" "video")))
964 %base-user-accounts))
965 (services (cons (service marionette-service-type
966 (marionette-configuration
967 (imported-modules '((gnu services herd)
968 (guix combinators)))))
971 (define %f2fs-root-installation-script
972 ;; Shell script of a simple installation.
978 export GUIX_BUILD_OPTIONS=--no-grafts
979 ls -l /run/current-system/gc-roots
980 parted --script /dev/vdb mklabel gpt \\
981 mkpart primary ext2 1M 3M \\
982 mkpart primary ext2 3M 2G \\
985 mkfs.f2fs -l my-root -q /dev/vdb2
987 herd start cow-store /mnt
989 cp /etc/target-config.scm /mnt/etc/config.scm
990 guix system build /mnt/etc/config.scm
991 guix system init /mnt/etc/config.scm /mnt --no-substitutes
995 (define %test-f2fs-root-os
997 (name "f2fs-root-os")
999 "Test basic functionality of an OS installed like one would do by hand.
1000 This test is expensive in terms of CPU and storage usage since we need to
1001 build (current-guix) and then store a couple of full system images.")
1003 (mlet* %store-monad ((image (run-install %f2fs-root-os
1004 %f2fs-root-os-source
1006 %f2fs-root-installation-script))
1007 (command (qemu-command/writable-image image)))
1008 (run-basic-test %f2fs-root-os command "f2fs-root-os")))))
1012 ;;; Installation through the graphical interface.
1015 (define %syslog-conf
1016 ;; Syslog configuration that dumps to /dev/console, so we can see the
1017 ;; installer's messages during the test.
1018 (computed-file "syslog.conf"
1020 (copy-file #$%default-syslog.conf #$output)
1021 (chmod #$output #o644)
1022 (let ((port (open-file #$output "a")))
1023 (display "\n*.info /dev/console\n" port)
1026 (define (operating-system-with-console-syslog os)
1027 "Return OS with a syslog service that writes to /dev/console."
1030 (services (modify-services (operating-system-user-services os)
1031 (syslog-service-type config
1033 (syslog-configuration
1035 (config-file %syslog-conf)))))))
1037 (define %root-password "foo")
1039 (define* (gui-test-program marionette
1044 (define (screenshot file)
1045 (marionette-control (string-append "screendump " file)
1048 (define-syntax-rule (marionette-eval* exp marionette)
1049 (or (marionette-eval exp marionette)
1050 (throw 'marionette-eval-failure 'exp)))
1052 (setvbuf (current-output-port) 'none)
1053 (setvbuf (current-error-port) 'none)
1055 (marionette-eval* '(use-modules (gnu installer tests))
1058 ;; Arrange so that 'converse' prints debugging output to the console.
1059 (marionette-eval* '(let ((console (open-output-file "/dev/console")))
1060 (setvbuf console 'none)
1061 (conversation-log-port console))
1064 ;; Tell the installer to not wait for the Connman "online" status.
1065 (marionette-eval* '(call-with-output-file "/tmp/installer-assume-online"
1069 ;; Run 'guix system init' with '--no-grafts', to cope with the lack of
1071 (marionette-eval* '(call-with-output-file
1072 "/tmp/installer-system-init-options"
1074 (write '("--no-grafts" "--no-substitutes")
1078 (marionette-eval* '(define installer-socket
1079 (open-installer-socket))
1081 (screenshot "installer-start.ppm")
1083 (marionette-eval* '(choose-locale+keyboard installer-socket)
1085 (screenshot "installer-locale.ppm")
1087 ;; Choose the host name that the "basic" test expects.
1088 (marionette-eval* '(enter-host-name+passwords installer-socket
1089 #:host-name "liberigilo"
1096 (screenshot "installer-services.ppm")
1098 (marionette-eval* '(choose-services installer-socket
1099 #:choose-desktop-environment?
1101 #:choose-network-service?
1104 (screenshot "installer-partitioning.ppm")
1106 (marionette-eval* '(choose-partitioning installer-socket
1107 #:encrypted? #$encrypted?
1108 #:passphrase #$%luks-passphrase)
1110 (screenshot "installer-run.ppm")
1112 (marionette-eval* '(conclude-installation installer-socket)
1118 (define %extra-packages
1119 ;; Packages needed when installing with an encrypted root.
1121 lvm2-static cryptsetup-static e2fsck/static
1124 (define installation-os-for-gui-tests
1125 ;; Operating system that contains all of %EXTRA-PACKAGES, needed for the
1126 ;; target OS, as well as syslog output redirected to the console so we can
1127 ;; see what the installer is up to.
1128 (marionette-operating-system
1130 (inherit (operating-system-with-console-syslog
1131 (operating-system-add-packages
1132 (operating-system-with-current-guix
1135 (kernel-arguments '("console=ttyS0")))
1136 #:imported-modules '((gnu services herd)
1137 (gnu installer tests)
1138 (guix combinators))))
1140 (define* (installation-target-os-for-gui-tests
1141 #:key (encrypted? #f))
1143 (inherit %minimal-os-on-vda)
1144 (users (append (list (user-account
1146 (comment "Bob's sister")
1148 (supplementary-groups
1149 '("wheel" "audio" "video")))
1152 (comment "Alice's brother")
1154 (supplementary-groups
1155 '("wheel" "audio" "video"))))
1156 %base-user-accounts))
1157 ;; The installer does not create a swap device in guided mode with
1158 ;; encryption support.
1159 (swap-devices (if encrypted? '() '("/dev/vda2")))
1160 (services (cons (service dhcp-client-service-type)
1161 (operating-system-user-services %minimal-os-on-vda)))))
1163 (define* (installation-target-desktop-os-for-gui-tests
1164 #:key (encrypted? #f))
1166 (inherit (installation-target-os-for-gui-tests
1167 #:encrypted? encrypted?))
1168 (keyboard-layout (keyboard-layout "us" "altgr-intl"))
1170 ;; Make sure that all the packages and services that may be used by the
1171 ;; graphical installer are available.
1173 (list openbox awesome i3-wm i3status
1174 dmenu st ratpoison xterm)
1178 (list (service gnome-desktop-service-type)
1179 (service xfce-desktop-service-type)
1180 (service mate-desktop-service-type)
1181 (service enlightenment-desktop-service-type)
1182 (set-xorg-configuration
1184 (keyboard-layout keyboard-layout)))
1185 (service marionette-service-type
1186 (marionette-configuration
1187 (imported-modules '((gnu services herd)
1189 (guix combinators))))))
1190 %desktop-services))))
1192 (define* (guided-installation-test name
1197 (install-size 'guess)
1198 (target-size (* 2200 MiB)))
1202 "Install an OS using the graphical installer and test it.")
1205 ((image (run-install target-os '(this is unused)
1207 #:os installation-os-for-gui-tests
1208 #:install-size install-size
1209 #:target-size target-size
1210 #:installation-disk-image-file-system-type
1213 (lambda (marionette)
1217 #:encrypted? encrypted?))))
1218 (command (qemu-command/writable-image image)))
1219 (run-basic-test target-os command name
1220 #:initialization (and encrypted? enter-luks-passphrase)
1221 #:root-password %root-password)))))
1223 (define %test-gui-installed-os
1224 (guided-installation-test
1226 #:target-os (installation-target-os-for-gui-tests)))
1228 (define %test-gui-installed-os-encrypted
1229 (guided-installation-test
1230 "gui-installed-os-encrypted"
1232 #:target-os (installation-target-os-for-gui-tests
1235 ;; Building a desktop image is very time and space consuming. Install all
1236 ;; desktop environments in a single test to reduce the overhead.
1237 (define %test-gui-installed-desktop-os-encrypted
1238 (guided-installation-test "gui-installed-desktop-os-encrypted"
1242 (installation-target-desktop-os-for-gui-tests
1244 ;; XXX: The disk-image size guess is too low. Use
1245 ;; a constant value until this is fixed.
1246 #:install-size (* 8000 MiB)
1247 #:target-size (* 9000 MiB)))
1249 ;;; install.scm ends here