lint: Check for trailing whitespace in synopsis.
[jackhill/guix/guix.git] / gnu / tests / install.scm
... / ...
CommitLineData
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>
6;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
7;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
8;;;
9;;; This file is part of GNU Guix.
10;;;
11;;; GNU Guix is free software; you can redistribute it and/or modify it
12;;; under the terms of the GNU General Public License as published by
13;;; the Free Software Foundation; either version 3 of the License, or (at
14;;; your option) any later version.
15;;;
16;;; GNU Guix is distributed in the hope that it will be useful, but
17;;; WITHOUT ANY WARRANTY; without even the implied warranty of
18;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;;; GNU General Public License for more details.
20;;;
21;;; You should have received a copy of the GNU General Public License
22;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
23
24(define-module (gnu tests install)
25 #:use-module (gnu)
26 #:use-module (gnu bootloader extlinux)
27 #:use-module (gnu image)
28 #:use-module (gnu tests)
29 #:use-module (gnu tests base)
30 #:use-module (gnu system)
31 #:use-module (gnu system image)
32 #:use-module (gnu system install)
33 #:use-module (gnu system vm)
34 #:use-module ((gnu build vm) #:select (qemu-command))
35 #:use-module (gnu packages admin)
36 #:use-module (gnu packages bootloaders)
37 #:use-module (gnu packages commencement) ;for 'guile-final'
38 #:use-module (gnu packages cryptsetup)
39 #:use-module (gnu packages disk)
40 #:use-module (gnu packages emacs)
41 #:use-module (gnu packages emacs-xyz)
42 #:use-module (gnu packages firmware)
43 #:use-module (gnu packages linux)
44 #:use-module (gnu packages ocr)
45 #:use-module (gnu packages openbox)
46 #:use-module (gnu packages package-management)
47 #:use-module (gnu packages ratpoison)
48 #:use-module (gnu packages suckless)
49 #:use-module (gnu packages virtualization)
50 #:use-module (gnu packages wm)
51 #:use-module (gnu packages xorg)
52 #:use-module (gnu services desktop)
53 #:use-module (gnu services networking)
54 #:use-module (gnu services xorg)
55 #:use-module (guix store)
56 #:use-module (guix monads)
57 #:use-module (guix packages)
58 #:use-module (guix grafts)
59 #:use-module (guix gexp)
60 #:use-module (guix utils)
61 #:use-module (srfi srfi-1)
62 #:export (%test-installed-os
63 %test-installed-extlinux-os
64 %test-iso-image-installer
65 %test-separate-store-os
66 %test-separate-home-os
67 %test-raid-root-os
68 %test-encrypted-root-os
69 %test-encrypted-root-not-boot-os
70 %test-btrfs-root-os
71 %test-btrfs-root-on-subvolume-os
72 %test-btrfs-raid-root-os
73 %test-jfs-root-os
74 %test-f2fs-root-os
75 %test-lvm-separate-home-os
76
77 %test-gui-installed-os
78 %test-gui-uefi-installed-os
79 %test-gui-installed-os-encrypted
80 %test-gui-installed-desktop-os-encrypted))
81
82;;; Commentary:
83;;;
84;;; Test the installation of Guix using the documented approach at the
85;;; command line.
86;;;
87;;; Code:
88
89(define-os-with-source (%minimal-os %minimal-os-source)
90 ;; The OS we want to install.
91 (use-modules (gnu) (gnu tests) (srfi srfi-1))
92
93 (operating-system
94 (host-name "liberigilo")
95 (timezone "Europe/Paris")
96 (locale "en_US.UTF-8")
97
98 (bootloader (bootloader-configuration
99 (bootloader grub-bootloader)
100 (target "/dev/vdb")))
101 (kernel-arguments '("console=ttyS0"))
102 (file-systems (cons (file-system
103 (device (file-system-label "my-root"))
104 (mount-point "/")
105 (type "ext4"))
106 %base-file-systems))
107 (users (cons (user-account
108 (name "alice")
109 (comment "Bob's sister")
110 (group "users")
111 (supplementary-groups '("wheel" "audio" "video")))
112 %base-user-accounts))
113 (services (cons (service marionette-service-type
114 (marionette-configuration
115 (imported-modules '((gnu services herd)
116 (guix build utils)
117 (guix combinators)))))
118 %base-services))))
119
120(define (operating-system-add-packages os packages)
121 "Append PACKAGES to OS packages list."
122 (operating-system
123 (inherit os)
124 (packages (append packages (operating-system-packages os)))))
125
126(define-os-with-source (%minimal-extlinux-os
127 %minimal-extlinux-os-source)
128 (use-modules (gnu) (gnu tests) (gnu bootloader extlinux)
129 (srfi srfi-1))
130
131 (operating-system
132 (host-name "liberigilo")
133 (timezone "Europe/Paris")
134 (locale "en_US.UTF-8")
135
136 (bootloader (bootloader-configuration
137 (bootloader extlinux-bootloader-gpt)
138 (target "/dev/vdb")))
139 (kernel-arguments '("console=ttyS0"))
140 (file-systems (cons (file-system
141 (device (file-system-label "my-root"))
142 (mount-point "/")
143 (type "ext4"))
144 %base-file-systems))
145 (services (cons (service marionette-service-type
146 (marionette-configuration
147 (imported-modules '((gnu services herd)
148 (guix combinators)))))
149 %base-services))))
150
151(define (operating-system-with-current-guix os)
152 "Return a variant of OS that uses the current Guix."
153 (operating-system
154 (inherit os)
155 (services (modify-services (operating-system-user-services os)
156 (guix-service-type config =>
157 (guix-configuration
158 (inherit config)
159 (guix (current-guix))))))))
160
161\f
162(define MiB (expt 2 20))
163
164(define %simple-installation-script
165 ;; Shell script of a simple installation.
166 "\
167. /etc/profile
168set -e -x
169guix --version
170
171export GUIX_BUILD_OPTIONS=--no-grafts
172guix build isc-dhcp
173parted --script /dev/vdb mklabel gpt \\
174 mkpart primary ext2 1M 3M \\
175 mkpart primary ext2 3M 1.6G \\
176 set 1 boot on \\
177 set 1 bios_grub on
178mkfs.ext4 -L my-root /dev/vdb2
179mount /dev/vdb2 /mnt
180df -h /mnt
181herd start cow-store /mnt
182mkdir /mnt/etc
183cp /etc/target-config.scm /mnt/etc/config.scm
184guix system init /mnt/etc/config.scm /mnt --no-substitutes
185sync
186reboot\n")
187
188(define %extlinux-gpt-installation-script
189 ;; Shell script of a simple installation.
190 ;; As syslinux 6.0.3 does not handle 64bits ext4 partitions,
191 ;; we make sure to pass -O '^64bit' to mkfs.
192 "\
193. /etc/profile
194set -e -x
195guix --version
196
197export GUIX_BUILD_OPTIONS=--no-grafts
198guix build isc-dhcp
199parted --script /dev/vdb mklabel gpt \\
200 mkpart ext2 1M 1.6G \\
201 set 1 legacy_boot on
202mkfs.ext4 -L my-root -O '^64bit' /dev/vdb1
203mount /dev/vdb1 /mnt
204df -h /mnt
205herd start cow-store /mnt
206mkdir /mnt/etc
207cp /etc/target-config.scm /mnt/etc/config.scm
208guix system init /mnt/etc/config.scm /mnt --no-substitutes
209sync
210reboot\n")
211
212(define (uefi-firmware system)
213 "Return the appropriate QEMU OVMF UEFI firmware for the given SYSTEM."
214 (cond
215 ((string-prefix? "x86_64" system)
216 (file-append ovmf "/share/firmware/ovmf_x64.bin"))
217 ((string-prefix? "i686" system)
218 (file-append ovmf "/share/firmware/ovmf_ia32.bin"))
219 (else #f)))
220
221(define* (run-install target-os target-os-source
222 #:key
223 (script %simple-installation-script)
224 (gui-test #f)
225 (packages '())
226 (os (marionette-operating-system
227 (operating-system
228 ;; Since the image has no network access, use the
229 ;; current Guix so the store items we need are in
230 ;; the image and add packages provided.
231 (inherit (operating-system-add-packages
232 (operating-system-with-current-guix
233 installation-os)
234 packages))
235 (kernel-arguments '("console=ttyS0")))
236 #:imported-modules '((gnu services herd)
237 (gnu installer tests)
238 (guix combinators))))
239 (uefi-support? #f)
240 (installation-image-type 'efi-raw)
241 (install-size 'guess)
242 (target-size (* 2200 MiB)))
243 "Run SCRIPT (a shell script following the system installation procedure) in
244OS to install TARGET-OS. Return a VM image of TARGET-SIZE bytes containing
245the installed system. The packages specified in PACKAGES will be appended to
246packages defined in installation-os."
247
248 (mlet* %store-monad ((_ (set-grafting #f))
249 (system (current-system))
250
251 (uefi-firmware -> (and uefi-support?
252 (uefi-firmware system)))
253 ;; Since the installation system has no network access,
254 ;; we cheat a little bit by adding TARGET to its GC
255 ;; roots. This way, we know 'guix system init' will
256 ;; succeed. Also add guile-final, which is pulled in
257 ;; through provenance.drv and may not always be present.
258 (target (operating-system-derivation target-os))
259 (base-image ->
260 (os->image
261 (operating-system-with-gc-roots
262 os (list target guile-final))
263 #:type (lookup-image-type-by-name
264 installation-image-type)))
265 (image ->
266 (system-image
267 (image
268 (inherit base-image)
269 (size install-size)
270
271 ;; Don't provide substitutes; too big.
272 (substitutable? #f)))))
273 (define install
274 (with-imported-modules '((guix build utils)
275 (gnu build marionette))
276 #~(begin
277 (use-modules (guix build utils)
278 (gnu build marionette))
279
280 (set-path-environment-variable "PATH" '("bin")
281 (list #$qemu-minimal))
282
283 (system* "qemu-img" "create" "-f" "qcow2"
284 #$output #$(number->string target-size))
285
286 (define marionette
287 (make-marionette
288 `(,(which #$(qemu-command system))
289 "-no-reboot"
290 "-m" "1200"
291 ,@(if #$uefi-firmware
292 '("-bios" #$uefi-firmware)
293 '())
294 #$@(cond
295 ((eq? 'efi-raw installation-image-type)
296 #~("-drive"
297 ,(string-append "file=" #$image
298 ",if=virtio,readonly")))
299 ((eq? 'uncompressed-iso9660 installation-image-type)
300 #~("-cdrom" #$image))
301 (else
302 (error
303 "unsupported installation-image-type:"
304 installation-image-type)))
305 "-drive"
306 ,(string-append "file=" #$output ",if=virtio")
307 ,@(if (file-exists? "/dev/kvm")
308 '("-enable-kvm")
309 '()))))
310
311 (pk 'uname (marionette-eval '(uname) marionette))
312
313 ;; Wait for tty1.
314 (marionette-eval '(begin
315 (use-modules (gnu services herd))
316 (start 'term-tty1))
317 marionette)
318
319 (when #$(->bool script)
320 (marionette-eval '(call-with-output-file "/etc/target-config.scm"
321 (lambda (port)
322 (write '#$target-os-source port)))
323 marionette)
324
325 ;; Run SCRIPT. It typically invokes 'reboot' as a last step and
326 ;; thus normally gets killed with SIGTERM by PID 1.
327 (let ((status (marionette-eval '(system #$script) marionette)))
328 (exit (or (eof-object? status)
329 (equal? (status:term-sig status) SIGTERM)
330 (equal? (status:exit-val status) 0)))))
331
332 (when #$(->bool gui-test)
333 (wait-for-unix-socket "/var/guix/installer-socket"
334 marionette)
335 (format #t "installer socket ready~%")
336 (force-output)
337 (exit #$(and gui-test
338 (gui-test #~marionette)))))))
339
340 (gexp->derivation "installation" install
341 #:substitutable? #f))) ;too big
342
343(define* (qemu-command/writable-image image
344 #:key
345 (uefi-support? #f)
346 (memory-size 256))
347 "Return as a monadic value the command to run QEMU on a writable copy of
348IMAGE, a disk image. The QEMU VM has access to MEMORY-SIZE MiB of RAM."
349 (mlet* %store-monad ((system (current-system))
350 (uefi-firmware -> (and uefi-support?
351 (uefi-firmware system))))
352 (return #~(let ((image #$image))
353 ;; First we need a writable copy of the image.
354 (format #t "creating writable image from '~a'...~%" image)
355 (unless (zero? (system* #+(file-append qemu-minimal
356 "/bin/qemu-img")
357 "create" "-f" "qcow2"
358 "-o"
359 (string-append "backing_file=" image)
360 "disk.img"))
361 (error "failed to create writable QEMU image" image))
362
363 (chmod "disk.img" #o644)
364 `(,(string-append #$qemu-minimal "/bin/"
365 #$(qemu-command system))
366 ,@(if (file-exists? "/dev/kvm")
367 '("-enable-kvm")
368 '())
369 ,@(if #$uefi-firmware
370 '("-bios" #$uefi-firmware)
371 '())
372 "-no-reboot" "-m" #$(number->string memory-size)
373 "-drive" "file=disk.img,if=virtio")))))
374
375(define %test-installed-os
376 (system-test
377 (name "installed-os")
378 (description
379 "Test basic functionality of an OS installed like one would do by hand.
380This test is expensive in terms of CPU and storage usage since we need to
381build (current-guix) and then store a couple of full system images.")
382 (value
383 (mlet* %store-monad ((image (run-install %minimal-os %minimal-os-source))
384 (command (qemu-command/writable-image image)))
385 (run-basic-test %minimal-os command
386 "installed-os")))))
387
388(define %test-installed-extlinux-os
389 (system-test
390 (name "installed-extlinux-os")
391 (description
392 "Test basic functionality of an OS booted with an extlinux bootloader. As
393per %test-installed-os, this test is expensive in terms of CPU and storage.")
394 (value
395 (mlet* %store-monad ((image (run-install %minimal-extlinux-os
396 %minimal-extlinux-os-source
397 #:packages
398 (list syslinux)
399 #:script
400 %extlinux-gpt-installation-script))
401 (command (qemu-command/writable-image image)))
402 (run-basic-test %minimal-extlinux-os command
403 "installed-extlinux-os")))))
404
405\f
406;;;
407;;; Installation through an ISO image.
408;;;
409
410(define-os-with-source (%minimal-os-on-vda %minimal-os-on-vda-source)
411 ;; The OS we want to install.
412 (use-modules (gnu) (gnu tests) (srfi srfi-1))
413
414 (operating-system
415 (host-name "liberigilo")
416 (timezone "Europe/Paris")
417 (locale "en_US.UTF-8")
418
419 (bootloader (bootloader-configuration
420 (bootloader grub-bootloader)
421 (target "/dev/vda")))
422 (kernel-arguments '("console=ttyS0"))
423 (file-systems (cons (file-system
424 (device (file-system-label "my-root"))
425 (mount-point "/")
426 (type "ext4"))
427 %base-file-systems))
428 (users (cons (user-account
429 (name "alice")
430 (comment "Bob's sister")
431 (group "users")
432 (supplementary-groups '("wheel" "audio" "video")))
433 %base-user-accounts))
434 (services (cons (service marionette-service-type
435 (marionette-configuration
436 (imported-modules '((gnu services herd)
437 (guix build utils)
438 (guix combinators)))))
439 %base-services))))
440
441(define %simple-installation-script-for-/dev/vda
442 ;; Shell script of a simple installation.
443 "\
444. /etc/profile
445set -e -x
446guix --version
447
448export GUIX_BUILD_OPTIONS=--no-grafts
449guix build isc-dhcp
450parted --script /dev/vda mklabel gpt \\
451 mkpart primary ext2 1M 3M \\
452 mkpart primary ext2 3M 1.6G \\
453 set 1 boot on \\
454 set 1 bios_grub on
455mkfs.ext4 -L my-root /dev/vda2
456mount /dev/vda2 /mnt
457df -h /mnt
458herd start cow-store /mnt
459mkdir /mnt/etc
460cp /etc/target-config.scm /mnt/etc/config.scm
461guix system init /mnt/etc/config.scm /mnt --no-substitutes
462sync
463reboot\n")
464
465(define %test-iso-image-installer
466 (system-test
467 (name "iso-image-installer")
468 (description
469 "")
470 (value
471 (mlet* %store-monad ((image (run-install
472 %minimal-os-on-vda
473 %minimal-os-on-vda-source
474 #:script
475 %simple-installation-script-for-/dev/vda
476 #:installation-image-type
477 'uncompressed-iso9660))
478 (command (qemu-command/writable-image image)))
479 (run-basic-test %minimal-os-on-vda command name)))))
480
481\f
482;;;
483;;; Separate /home.
484;;;
485
486(define-os-with-source (%separate-home-os %separate-home-os-source)
487 ;; The OS we want to install.
488 (use-modules (gnu) (gnu tests) (srfi srfi-1))
489
490 (operating-system
491 (host-name "liberigilo")
492 (timezone "Europe/Paris")
493 (locale "en_US.utf8")
494
495 (bootloader (bootloader-configuration
496 (bootloader grub-bootloader)
497 (target "/dev/vdb")))
498 (kernel-arguments '("console=ttyS0"))
499 (file-systems (cons* (file-system
500 (device (file-system-label "my-root"))
501 (mount-point "/")
502 (type "ext4"))
503 (file-system
504 (device "none")
505 (mount-point "/home")
506 (type "tmpfs"))
507 %base-file-systems))
508 (users (cons* (user-account
509 (name "alice")
510 (group "users"))
511 (user-account
512 (name "charlie")
513 (group "users"))
514 %base-user-accounts))
515 (services (cons (service marionette-service-type
516 (marionette-configuration
517 (imported-modules '((gnu services herd)
518 (guix combinators)))))
519 %base-services))))
520
521(define %test-separate-home-os
522 (system-test
523 (name "separate-home-os")
524 (description
525 "Test basic functionality of an installed OS with a separate /home
526partition. In particular, home directories must be correctly created (see
527<https://bugs.gnu.org/21108>).")
528 (value
529 (mlet* %store-monad ((image (run-install %separate-home-os
530 %separate-home-os-source
531 #:script
532 %simple-installation-script))
533 (command (qemu-command/writable-image image)))
534 (run-basic-test %separate-home-os command "separate-home-os")))))
535
536\f
537;;;
538;;; Separate /gnu/store partition.
539;;;
540
541(define-os-with-source (%separate-store-os %separate-store-os-source)
542 ;; The OS we want to install.
543 (use-modules (gnu) (gnu tests) (srfi srfi-1))
544
545 (operating-system
546 (host-name "liberigilo")
547 (timezone "Europe/Paris")
548 (locale "en_US.UTF-8")
549
550 (bootloader (bootloader-configuration
551 (bootloader grub-bootloader)
552 (target "/dev/vdb")))
553 (kernel-arguments '("console=ttyS0"))
554 (file-systems (cons* (file-system
555 (device (file-system-label "root-fs"))
556 (mount-point "/")
557 (type "ext4"))
558 (file-system
559 (device (file-system-label "store-fs"))
560 (mount-point "/gnu")
561 (type "ext4"))
562 %base-file-systems))
563 (users %base-user-accounts)
564 (services (cons (service marionette-service-type
565 (marionette-configuration
566 (imported-modules '((gnu services herd)
567 (guix combinators)))))
568 %base-services))))
569
570(define %separate-store-installation-script
571 ;; Installation with a separate /gnu partition.
572 "\
573. /etc/profile
574set -e -x
575guix --version
576
577export GUIX_BUILD_OPTIONS=--no-grafts
578guix build isc-dhcp
579parted --script /dev/vdb mklabel gpt \\
580 mkpart primary ext2 1M 3M \\
581 mkpart primary ext2 3M 400M \\
582 mkpart primary ext2 400M 2.1G \\
583 set 1 boot on \\
584 set 1 bios_grub on
585mkfs.ext4 -L root-fs /dev/vdb2
586mkfs.ext4 -L store-fs /dev/vdb3
587mount /dev/vdb2 /mnt
588mkdir /mnt/gnu
589mount /dev/vdb3 /mnt/gnu
590df -h /mnt
591df -h /mnt/gnu
592herd start cow-store /mnt
593mkdir /mnt/etc
594cp /etc/target-config.scm /mnt/etc/config.scm
595guix system init /mnt/etc/config.scm /mnt --no-substitutes
596sync
597reboot\n")
598
599(define %test-separate-store-os
600 (system-test
601 (name "separate-store-os")
602 (description
603 "Test basic functionality of an OS installed like one would do by hand,
604where /gnu lives on a separate partition.")
605 (value
606 (mlet* %store-monad ((image (run-install %separate-store-os
607 %separate-store-os-source
608 #:script
609 %separate-store-installation-script))
610 (command (qemu-command/writable-image image)))
611 (run-basic-test %separate-store-os command "separate-store-os")))))
612
613\f
614;;;
615;;; RAID root device.
616;;;
617
618(define-os-with-source (%raid-root-os %raid-root-os-source)
619 ;; An OS whose root partition is a RAID partition.
620 (use-modules (gnu) (gnu tests))
621
622 (operating-system
623 (host-name "raidified")
624 (timezone "Europe/Paris")
625 (locale "en_US.utf8")
626
627 (bootloader (bootloader-configuration
628 (bootloader grub-bootloader)
629 (target "/dev/vdb")))
630 (kernel-arguments '("console=ttyS0"))
631
632 ;; Add a kernel module for RAID-1 (aka. "mirror").
633 (initrd-modules (cons "raid1" %base-initrd-modules))
634
635 (mapped-devices (list (mapped-device
636 (source (list "/dev/vda2" "/dev/vda3"))
637 (target "/dev/md0")
638 (type raid-device-mapping))))
639 (file-systems (cons (file-system
640 (device (file-system-label "root-fs"))
641 (mount-point "/")
642 (type "ext4")
643 (dependencies mapped-devices))
644 %base-file-systems))
645 (users %base-user-accounts)
646 (services (cons (service marionette-service-type
647 (marionette-configuration
648 (imported-modules '((gnu services herd)
649 (guix combinators)))))
650 %base-services))))
651
652(define %raid-root-installation-script
653 ;; Installation with a separate /gnu partition. See
654 ;; <https://raid.wiki.kernel.org/index.php/RAID_setup> for more on RAID and
655 ;; mdadm.
656 "\
657. /etc/profile
658set -e -x
659guix --version
660
661export GUIX_BUILD_OPTIONS=--no-grafts
662parted --script /dev/vdb mklabel gpt \\
663 mkpart primary ext2 1M 3M \\
664 mkpart primary ext2 3M 1.6G \\
665 mkpart primary ext2 1.6G 3.2G \\
666 set 1 boot on \\
667 set 1 bios_grub on
668yes | mdadm --create /dev/md0 --verbose --level=mirror --raid-devices=2 \\
669 /dev/vdb2 /dev/vdb3
670mkfs.ext4 -L root-fs /dev/md0
671mount /dev/md0 /mnt
672df -h /mnt
673herd start cow-store /mnt
674mkdir /mnt/etc
675cp /etc/target-config.scm /mnt/etc/config.scm
676guix system init /mnt/etc/config.scm /mnt --no-substitutes
677sync
678reboot\n")
679
680(define %test-raid-root-os
681 (system-test
682 (name "raid-root-os")
683 (description
684 "Test functionality of an OS installed with a RAID root partition managed
685by 'mdadm'.")
686 (value
687 (mlet* %store-monad ((image (run-install %raid-root-os
688 %raid-root-os-source
689 #:script
690 %raid-root-installation-script
691 #:target-size (* 3200 MiB)))
692 (command (qemu-command/writable-image image)))
693 (run-basic-test %raid-root-os
694 `(,@command) "raid-root-os")))))
695
696\f
697;;;
698;;; LUKS-encrypted root file system.
699;;;
700
701(define-os-with-source (%encrypted-root-os %encrypted-root-os-source)
702 ;; The OS we want to install.
703 (use-modules (gnu) (gnu tests) (srfi srfi-1))
704
705 (operating-system
706 (host-name "liberigilo")
707 (timezone "Europe/Paris")
708 (locale "en_US.UTF-8")
709
710 (bootloader (bootloader-configuration
711 (bootloader grub-bootloader)
712 (target "/dev/vdb")))
713
714 ;; Note: Do not pass "console=ttyS0" so we can use our passphrase prompt
715 ;; detection logic in 'enter-luks-passphrase'.
716
717 (mapped-devices (list (mapped-device
718 (source (uuid "12345678-1234-1234-1234-123456789abc"))
719 (target "the-root-device")
720 (type luks-device-mapping))))
721 (file-systems (cons (file-system
722 (device "/dev/mapper/the-root-device")
723 (mount-point "/")
724 (type "ext4"))
725 %base-file-systems))
726 (users (cons (user-account
727 (name "charlie")
728 (group "users")
729 (supplementary-groups '("wheel" "audio" "video")))
730 %base-user-accounts))
731 (services (cons (service marionette-service-type
732 (marionette-configuration
733 (imported-modules '((gnu services herd)
734 (guix combinators)))))
735 %base-services))))
736
737(define %luks-passphrase
738 ;; LUKS encryption passphrase used in tests.
739 "thepassphrase")
740
741(define %encrypted-root-installation-script
742 ;; Shell script of a simple installation.
743 (string-append "\
744. /etc/profile
745set -e -x
746guix --version
747
748export GUIX_BUILD_OPTIONS=--no-grafts
749ls -l /run/current-system/gc-roots
750parted --script /dev/vdb mklabel gpt \\
751 mkpart primary ext2 1M 3M \\
752 mkpart primary ext2 3M 1.6G \\
753 set 1 boot on \\
754 set 1 bios_grub on
755echo -n " %luks-passphrase " | \\
756 cryptsetup luksFormat --uuid=12345678-1234-1234-1234-123456789abc -q /dev/vdb2 -
757echo -n " %luks-passphrase " | \\
758 cryptsetup open --type luks --key-file - /dev/vdb2 the-root-device
759mkfs.ext4 -L my-root /dev/mapper/the-root-device
760mount LABEL=my-root /mnt
761herd start cow-store /mnt
762mkdir /mnt/etc
763cp /etc/target-config.scm /mnt/etc/config.scm
764guix system build /mnt/etc/config.scm
765guix system init /mnt/etc/config.scm /mnt --no-substitutes
766sync
767reboot\n"))
768
769(define (enter-luks-passphrase marionette)
770 "Return a gexp to be inserted in the basic system test running on MARIONETTE
771to enter the LUKS passphrase."
772 (let ((ocrad (file-append ocrad "/bin/ocrad")))
773 #~(begin
774 (define (passphrase-prompt? text)
775 (string-contains (pk 'screen-text text) "Enter pass"))
776
777 (define (bios-boot-screen? text)
778 ;; Return true if TEXT corresponds to the boot screen, before GRUB's
779 ;; menu.
780 (string-prefix? "SeaBIOS" text))
781
782 (test-assert "enter LUKS passphrase for GRUB"
783 (begin
784 ;; At this point we have no choice but to use OCR to determine
785 ;; when the passphrase should be entered.
786 (wait-for-screen-text #$marionette passphrase-prompt?
787 #:ocrad #$ocrad)
788 (marionette-type #$(string-append %luks-passphrase "\n")
789 #$marionette)
790
791 ;; Now wait until we leave the boot screen. This is necessary so
792 ;; we can then be sure we match the "Enter passphrase" prompt from
793 ;; 'cryptsetup', in the initrd.
794 (wait-for-screen-text #$marionette (negate bios-boot-screen?)
795 #:ocrad #$ocrad
796 #:timeout 20)))
797
798 (test-assert "enter LUKS passphrase for the initrd"
799 (begin
800 ;; XXX: Here we use OCR as well but we could instead use QEMU
801 ;; '-serial stdio' and run it in an input pipe,
802 (wait-for-screen-text #$marionette passphrase-prompt?
803 #:ocrad #$ocrad
804 #:timeout 60)
805 (marionette-type #$(string-append %luks-passphrase "\n")
806 #$marionette)
807
808 ;; Take a screenshot for debugging purposes.
809 (marionette-control (string-append "screendump " #$output
810 "/post-initrd-passphrase.ppm")
811 #$marionette))))))
812
813(define %test-encrypted-root-os
814 (system-test
815 (name "encrypted-root-os")
816 (description
817 "Test basic functionality of an OS installed like one would do by hand.
818This test is expensive in terms of CPU and storage usage since we need to
819build (current-guix) and then store a couple of full system images.")
820 (value
821 (mlet* %store-monad ((image (run-install %encrypted-root-os
822 %encrypted-root-os-source
823 #:script
824 %encrypted-root-installation-script))
825 (command (qemu-command/writable-image image)))
826 (run-basic-test %encrypted-root-os command "encrypted-root-os"
827 #:initialization enter-luks-passphrase)))))
828
829\f
830;;;
831;;; Separate /home on LVM
832;;;
833
834;; Since LVM support in guix currently doesn't allow root-on-LVM we use /home on LVM
835(define-os-with-source (%lvm-separate-home-os %lvm-separate-home-os-source)
836 (use-modules (gnu) (gnu tests))
837
838 (operating-system
839 (host-name "separate-home-on-lvm")
840 (timezone "Europe/Paris")
841 (locale "en_US.utf8")
842
843 (bootloader (bootloader-configuration
844 (bootloader grub-bootloader)
845 (target "/dev/vdb")))
846 (kernel-arguments '("console=ttyS0"))
847
848 (mapped-devices (list (mapped-device
849 (source "vg0")
850 (target "vg0-home")
851 (type lvm-device-mapping))))
852 (file-systems (cons* (file-system
853 (device (file-system-label "root-fs"))
854 (mount-point "/")
855 (type "ext4"))
856 (file-system
857 (device "/dev/mapper/vg0-home")
858 (mount-point "/home")
859 (type "ext4")
860 (dependencies mapped-devices))
861 %base-file-systems))
862 (users %base-user-accounts)
863 (services (cons (service marionette-service-type
864 (marionette-configuration
865 (imported-modules '((gnu services herd)
866 (guix combinators)))))
867 %base-services))))
868
869(define %lvm-separate-home-installation-script
870 "\
871. /etc/profile
872set -e -x
873guix --version
874
875export GUIX_BUILD_OPTIONS=--no-grafts
876parted --script /dev/vdb mklabel gpt \\
877 mkpart primary ext2 1M 3M \\
878 mkpart primary ext2 3M 1.6G \\
879 mkpart primary 1.6G 3.2G \\
880 set 1 boot on \\
881 set 1 bios_grub on
882pvcreate /dev/vdb3
883vgcreate vg0 /dev/vdb3
884lvcreate -L 1.6G -n home vg0
885vgchange -ay
886mkfs.ext4 -L root-fs /dev/vdb2
887mkfs.ext4 /dev/mapper/vg0-home
888mount /dev/vdb2 /mnt
889mkdir /mnt/home
890mount /dev/mapper/vg0-home /mnt/home
891df -h /mnt /mnt/home
892herd start cow-store /mnt
893mkdir /mnt/etc
894cp /etc/target-config.scm /mnt/etc/config.scm
895guix system init /mnt/etc/config.scm /mnt --no-substitutes
896sync
897reboot\n")
898
899(define %test-lvm-separate-home-os
900 (system-test
901 (name "lvm-separate-home-os")
902 (description
903 "Test functionality of an OS installed with a LVM /home partition")
904 (value
905 (mlet* %store-monad ((image (run-install %lvm-separate-home-os
906 %lvm-separate-home-os-source
907 #:script
908 %lvm-separate-home-installation-script
909 #:packages (list lvm2-static)
910 #:target-size (* 3200 MiB)))
911 (command (qemu-command/writable-image image)))
912 (run-basic-test %lvm-separate-home-os
913 `(,@command) "lvm-separate-home-os")))))
914
915\f
916;;;
917;;; LUKS-encrypted root file system and /boot in a non-encrypted partition.
918;;;
919
920(define-os-with-source (%encrypted-root-not-boot-os
921 %encrypted-root-not-boot-os-source)
922 ;; The OS we want to install.
923 (use-modules (gnu) (gnu tests) (srfi srfi-1))
924
925 (operating-system
926 (host-name "bootroot")
927 (timezone "Europe/Madrid")
928 (locale "en_US.UTF-8")
929
930 (bootloader (bootloader-configuration
931 (bootloader grub-bootloader)
932 (target "/dev/vdb")))
933
934 (mapped-devices (list (mapped-device
935 (source
936 (uuid "12345678-1234-1234-1234-123456789abc"))
937 (target "root")
938 (type luks-device-mapping))))
939 (file-systems (cons* (file-system
940 (device (file-system-label "my-boot"))
941 (mount-point "/boot")
942 (type "ext4"))
943 (file-system
944 (device "/dev/mapper/root")
945 (mount-point "/")
946 (type "ext4"))
947 %base-file-systems))
948 (users (cons (user-account
949 (name "alice")
950 (group "users")
951 (supplementary-groups '("wheel" "audio" "video")))
952 %base-user-accounts))
953 (services (cons (service marionette-service-type
954 (marionette-configuration
955 (imported-modules '((gnu services herd)
956 (guix combinators)))))
957 %base-services))))
958
959(define %encrypted-root-not-boot-installation-script
960 ;; Shell script for an installation with boot not encrypted but root
961 ;; encrypted.
962 (format #f "\
963. /etc/profile
964set -e -x
965guix --version
966
967export GUIX_BUILD_OPTIONS=--no-grafts
968ls -l /run/current-system/gc-roots
969parted --script /dev/vdb mklabel gpt \\
970 mkpart primary ext2 1M 3M \\
971 mkpart primary ext2 3M 50M \\
972 mkpart primary ext2 50M 1.6G \\
973 set 1 boot on \\
974 set 1 bios_grub on
975echo -n \"~a\" | cryptsetup luksFormat --uuid=\"~a\" -q /dev/vdb3 -
976echo -n \"~a\" | cryptsetup open --type luks --key-file - /dev/vdb3 root
977mkfs.ext4 -L my-root /dev/mapper/root
978mkfs.ext4 -L my-boot /dev/vdb2
979mount LABEL=my-root /mnt
980mkdir /mnt/boot
981mount LABEL=my-boot /mnt/boot
982echo \"Checking mounts\"
983mount
984herd start cow-store /mnt
985mkdir /mnt/etc
986cp /etc/target-config.scm /mnt/etc/config.scm
987guix system build /mnt/etc/config.scm
988guix system init /mnt/etc/config.scm /mnt --no-substitutes
989sync
990echo \"Debugging info\"
991blkid
992cat /mnt/boot/grub/grub.cfg
993reboot\n"
994 %luks-passphrase "12345678-1234-1234-1234-123456789abc"
995 %luks-passphrase))
996
997(define %test-encrypted-root-not-boot-os
998 (system-test
999 (name "encrypted-root-not-boot-os")
1000 (description
1001 "Test the manual installation on an OS with / in an encrypted partition
1002but /boot on a different, non-encrypted partition. This test is expensive in
1003terms of CPU and storage usage since we need to build (current-guix) and then
1004store a couple of full system images.")
1005 (value
1006 (mlet* %store-monad
1007 ((image (run-install %encrypted-root-not-boot-os
1008 %encrypted-root-not-boot-os-source
1009 #:script
1010 %encrypted-root-not-boot-installation-script))
1011 (command (qemu-command/writable-image image)))
1012 (run-basic-test %encrypted-root-not-boot-os command
1013 "encrypted-root-not-boot-os"
1014 #:initialization enter-luks-passphrase)))))
1015
1016\f
1017;;;
1018;;; Btrfs root file system.
1019;;;
1020
1021(define-os-with-source (%btrfs-root-os %btrfs-root-os-source)
1022 ;; The OS we want to install.
1023 (use-modules (gnu) (gnu tests) (srfi srfi-1))
1024
1025 (operating-system
1026 (host-name "liberigilo")
1027 (timezone "Europe/Paris")
1028 (locale "en_US.UTF-8")
1029
1030 (bootloader (bootloader-configuration
1031 (bootloader grub-bootloader)
1032 (target "/dev/vdb")))
1033 (kernel-arguments '("console=ttyS0"))
1034 (file-systems (cons (file-system
1035 (device (file-system-label "my-root"))
1036 (mount-point "/")
1037 (type "btrfs"))
1038 %base-file-systems))
1039 (users (cons (user-account
1040 (name "charlie")
1041 (group "users")
1042 (supplementary-groups '("wheel" "audio" "video")))
1043 %base-user-accounts))
1044 (services (cons (service marionette-service-type
1045 (marionette-configuration
1046 (imported-modules '((gnu services herd)
1047 (guix combinators)))))
1048 %base-services))))
1049
1050(define %btrfs-root-installation-script
1051 ;; Shell script of a simple installation.
1052 "\
1053. /etc/profile
1054set -e -x
1055guix --version
1056
1057export GUIX_BUILD_OPTIONS=--no-grafts
1058ls -l /run/current-system/gc-roots
1059parted --script /dev/vdb mklabel gpt \\
1060 mkpart primary ext2 1M 3M \\
1061 mkpart primary ext2 3M 2G \\
1062 set 1 boot on \\
1063 set 1 bios_grub on
1064mkfs.btrfs -L my-root /dev/vdb2
1065mount /dev/vdb2 /mnt
1066btrfs subvolume create /mnt/home
1067herd start cow-store /mnt
1068mkdir /mnt/etc
1069cp /etc/target-config.scm /mnt/etc/config.scm
1070guix system build /mnt/etc/config.scm
1071guix system init /mnt/etc/config.scm /mnt --no-substitutes
1072sync
1073reboot\n")
1074
1075(define %test-btrfs-root-os
1076 (system-test
1077 (name "btrfs-root-os")
1078 (description
1079 "Test basic functionality of an OS installed like one would do by hand.
1080This test is expensive in terms of CPU and storage usage since we need to
1081build (current-guix) and then store a couple of full system images.")
1082 (value
1083 (mlet* %store-monad ((image (run-install %btrfs-root-os
1084 %btrfs-root-os-source
1085 #:script
1086 %btrfs-root-installation-script))
1087 (command (qemu-command/writable-image image)))
1088 (run-basic-test %btrfs-root-os command "btrfs-root-os")))))
1089
1090
1091\f
1092;;;
1093;;; Btrfs RAID-0 root file system.
1094;;;
1095(define-os-with-source (%btrfs-raid-root-os %btrfs-raid-root-os-source)
1096 ;; An OS whose root partition is a RAID partition.
1097 (use-modules (gnu) (gnu tests))
1098
1099 (operating-system
1100 (host-name "liberigilo")
1101 (timezone "Europe/Paris")
1102 (locale "en_US.utf8")
1103
1104 (bootloader (bootloader-configuration
1105 (bootloader grub-bootloader)
1106 (target "/dev/vdb")))
1107 (kernel-arguments '("console=ttyS0"))
1108
1109 (file-systems (cons (file-system
1110 (device (file-system-label "root-fs"))
1111 (mount-point "/")
1112 (type "btrfs"))
1113 %base-file-systems))
1114 (users %base-user-accounts)
1115 (services (cons (service marionette-service-type
1116 (marionette-configuration
1117 (imported-modules '((gnu services herd)
1118 (guix combinators)))))
1119 %base-services))))
1120
1121(define %btrfs-raid-root-installation-script
1122 "\
1123. /etc/profile
1124set -e -x
1125guix --version
1126
1127export GUIX_BUILD_OPTIONS=--no-grafts
1128parted --script /dev/vdb mklabel gpt \\
1129 mkpart primary ext2 1M 3M \\
1130 mkpart primary ext2 3M 1.4G \\
1131 mkpart primary ext2 1.4G 2.8G \\
1132 set 1 boot on \\
1133 set 1 bios_grub on
1134mkfs.btrfs -L root-fs -d raid0 -m raid0 /dev/vdb2 /dev/vdb3
1135mount /dev/vdb2 /mnt
1136df -h /mnt
1137herd start cow-store /mnt
1138mkdir /mnt/etc
1139cp /etc/target-config.scm /mnt/etc/config.scm
1140guix system init /mnt/etc/config.scm /mnt --no-substitutes
1141sync
1142reboot\n")
1143
1144(define %test-btrfs-raid-root-os
1145 (system-test
1146 (name "btrfs-raid-root-os")
1147 (description "Test functionality of an OS installed with a Btrfs
1148RAID-0 (stripe) root partition.")
1149 (value
1150 (mlet* %store-monad
1151 ((image (run-install %btrfs-raid-root-os
1152 %btrfs-raid-root-os-source
1153 #:script %btrfs-raid-root-installation-script
1154 #:target-size (* 2800 MiB)))
1155 (command (qemu-command/writable-image image)))
1156 (run-basic-test %btrfs-raid-root-os `(,@command) "btrfs-raid-root-os")))))
1157
1158\f
1159;;;
1160;;; Btrfs root file system on a subvolume.
1161;;;
1162
1163(define-os-with-source (%btrfs-root-on-subvolume-os
1164 %btrfs-root-on-subvolume-os-source)
1165 ;; The OS we want to install.
1166 (use-modules (gnu) (gnu tests) (srfi srfi-1))
1167
1168 (operating-system
1169 (host-name "hurd")
1170 (timezone "America/Montreal")
1171 (locale "en_US.UTF-8")
1172 (bootloader (bootloader-configuration
1173 (bootloader grub-bootloader)
1174 (target "/dev/vdb")))
1175 (kernel-arguments '("console=ttyS0"))
1176 (file-systems (cons* (file-system
1177 (device (file-system-label "btrfs-pool"))
1178 (mount-point "/")
1179 (options "subvol=rootfs,compress=zstd")
1180 (type "btrfs"))
1181 (file-system
1182 (device (file-system-label "btrfs-pool"))
1183 (mount-point "/home")
1184 (options "subvol=homefs,compress=lzo")
1185 (type "btrfs"))
1186 %base-file-systems))
1187 (users (cons (user-account
1188 (name "charlie")
1189 (group "users")
1190 (supplementary-groups '("wheel" "audio" "video")))
1191 %base-user-accounts))
1192 (services (cons (service marionette-service-type
1193 (marionette-configuration
1194 (imported-modules '((gnu services herd)
1195 (guix combinators)))))
1196 %base-services))))
1197
1198(define %btrfs-root-on-subvolume-installation-script
1199 ;; Shell script of a simple installation.
1200 "\
1201. /etc/profile
1202set -e -x
1203guix --version
1204
1205export GUIX_BUILD_OPTIONS=--no-grafts
1206ls -l /run/current-system/gc-roots
1207parted --script /dev/vdb mklabel gpt \\
1208 mkpart primary ext2 1M 3M \\
1209 mkpart primary ext2 3M 2G \\
1210 set 1 boot on \\
1211 set 1 bios_grub on
1212
1213# Setup the top level Btrfs file system with its subvolume.
1214mkfs.btrfs -L btrfs-pool /dev/vdb2
1215mount /dev/vdb2 /mnt
1216btrfs subvolume create /mnt/rootfs
1217btrfs subvolume create /mnt/homefs
1218umount /dev/vdb2
1219
1220# Mount the subvolumes, ready for installation.
1221mount LABEL=btrfs-pool -o 'subvol=rootfs,compress=zstd' /mnt
1222mkdir /mnt/home
1223mount LABEL=btrfs-pool -o 'subvol=homefs,compress=zstd' /mnt/home
1224
1225herd start cow-store /mnt
1226mkdir /mnt/etc
1227cp /etc/target-config.scm /mnt/etc/config.scm
1228guix system build /mnt/etc/config.scm
1229guix system init /mnt/etc/config.scm /mnt --no-substitutes
1230sync
1231reboot\n")
1232
1233(define %test-btrfs-root-on-subvolume-os
1234 (system-test
1235 (name "btrfs-root-on-subvolume-os")
1236 (description
1237 "Test basic functionality of an OS installed like one would do by hand.
1238This test is expensive in terms of CPU and storage usage since we need to
1239build (current-guix) and then store a couple of full system images.")
1240 (value
1241 (mlet* %store-monad
1242 ((image
1243 (run-install %btrfs-root-on-subvolume-os
1244 %btrfs-root-on-subvolume-os-source
1245 #:script
1246 %btrfs-root-on-subvolume-installation-script))
1247 (command (qemu-command/writable-image image)))
1248 (run-basic-test %btrfs-root-on-subvolume-os command
1249 "btrfs-root-on-subvolume-os")))))
1250
1251\f
1252;;;
1253;;; JFS root file system.
1254;;;
1255
1256(define-os-with-source (%jfs-root-os %jfs-root-os-source)
1257 ;; The OS we want to install.
1258 (use-modules (gnu) (gnu tests) (srfi srfi-1))
1259
1260 (operating-system
1261 (host-name "liberigilo")
1262 (timezone "Europe/Paris")
1263 (locale "en_US.UTF-8")
1264
1265 (bootloader (bootloader-configuration
1266 (bootloader grub-bootloader)
1267 (target "/dev/vdb")))
1268 (kernel-arguments '("console=ttyS0"))
1269 (file-systems (cons (file-system
1270 (device (file-system-label "my-root"))
1271 (mount-point "/")
1272 (type "jfs"))
1273 %base-file-systems))
1274 (users (cons (user-account
1275 (name "charlie")
1276 (group "users")
1277 (supplementary-groups '("wheel" "audio" "video")))
1278 %base-user-accounts))
1279 (services (cons (service marionette-service-type
1280 (marionette-configuration
1281 (imported-modules '((gnu services herd)
1282 (guix combinators)))))
1283 %base-services))))
1284
1285(define %jfs-root-installation-script
1286 ;; Shell script of a simple installation.
1287 "\
1288. /etc/profile
1289set -e -x
1290guix --version
1291
1292export GUIX_BUILD_OPTIONS=--no-grafts
1293ls -l /run/current-system/gc-roots
1294parted --script /dev/vdb mklabel gpt \\
1295 mkpart primary ext2 1M 3M \\
1296 mkpart primary ext2 3M 2G \\
1297 set 1 boot on \\
1298 set 1 bios_grub on
1299jfs_mkfs -L my-root -q /dev/vdb2
1300mount /dev/vdb2 /mnt
1301herd start cow-store /mnt
1302mkdir /mnt/etc
1303cp /etc/target-config.scm /mnt/etc/config.scm
1304guix system build /mnt/etc/config.scm
1305guix system init /mnt/etc/config.scm /mnt --no-substitutes
1306sync
1307reboot\n")
1308
1309(define %test-jfs-root-os
1310 (system-test
1311 (name "jfs-root-os")
1312 (description
1313 "Test basic functionality of an OS installed like one would do by hand.
1314This test is expensive in terms of CPU and storage usage since we need to
1315build (current-guix) and then store a couple of full system images.")
1316 (value
1317 (mlet* %store-monad ((image (run-install %jfs-root-os
1318 %jfs-root-os-source
1319 #:script
1320 %jfs-root-installation-script))
1321 (command (qemu-command/writable-image image)))
1322 (run-basic-test %jfs-root-os command "jfs-root-os")))))
1323
1324\f
1325;;;
1326;;; F2FS root file system.
1327;;;
1328
1329(define-os-with-source (%f2fs-root-os %f2fs-root-os-source)
1330 ;; The OS we want to install.
1331 (use-modules (gnu) (gnu tests) (srfi srfi-1))
1332
1333 (operating-system
1334 (host-name "liberigilo")
1335 (timezone "Europe/Paris")
1336 (locale "en_US.UTF-8")
1337
1338 (bootloader (bootloader-configuration
1339 (bootloader grub-bootloader)
1340 (target "/dev/vdb")))
1341 (kernel-arguments '("console=ttyS0"))
1342 (file-systems (cons (file-system
1343 (device (file-system-label "my-root"))
1344 (mount-point "/")
1345 (type "f2fs"))
1346 %base-file-systems))
1347 (users (cons (user-account
1348 (name "charlie")
1349 (group "users")
1350 (supplementary-groups '("wheel" "audio" "video")))
1351 %base-user-accounts))
1352 (services (cons (service marionette-service-type
1353 (marionette-configuration
1354 (imported-modules '((gnu services herd)
1355 (guix combinators)))))
1356 %base-services))))
1357
1358(define %f2fs-root-installation-script
1359 ;; Shell script of a simple installation.
1360 "\
1361. /etc/profile
1362set -e -x
1363guix --version
1364
1365export GUIX_BUILD_OPTIONS=--no-grafts
1366ls -l /run/current-system/gc-roots
1367parted --script /dev/vdb mklabel gpt \\
1368 mkpart primary ext2 1M 3M \\
1369 mkpart primary ext2 3M 2G \\
1370 set 1 boot on \\
1371 set 1 bios_grub on
1372mkfs.f2fs -l my-root -q /dev/vdb2
1373mount /dev/vdb2 /mnt
1374herd start cow-store /mnt
1375mkdir /mnt/etc
1376cp /etc/target-config.scm /mnt/etc/config.scm
1377guix system build /mnt/etc/config.scm
1378guix system init /mnt/etc/config.scm /mnt --no-substitutes
1379sync
1380reboot\n")
1381
1382(define %test-f2fs-root-os
1383 (system-test
1384 (name "f2fs-root-os")
1385 (description
1386 "Test basic functionality of an OS installed like one would do by hand.
1387This test is expensive in terms of CPU and storage usage since we need to
1388build (current-guix) and then store a couple of full system images.")
1389 (value
1390 (mlet* %store-monad ((image (run-install %f2fs-root-os
1391 %f2fs-root-os-source
1392 #:script
1393 %f2fs-root-installation-script))
1394 (command (qemu-command/writable-image image)))
1395 (run-basic-test %f2fs-root-os command "f2fs-root-os")))))
1396
1397\f
1398;;;
1399;;; Installation through the graphical interface.
1400;;;
1401
1402(define %syslog-conf
1403 ;; Syslog configuration that dumps to /dev/console, so we can see the
1404 ;; installer's messages during the test.
1405 (computed-file "syslog.conf"
1406 #~(begin
1407 (copy-file #$%default-syslog.conf #$output)
1408 (chmod #$output #o644)
1409 (let ((port (open-file #$output "a")))
1410 (display "\n*.info /dev/console\n" port)
1411 #t))))
1412
1413(define (operating-system-with-console-syslog os)
1414 "Return OS with a syslog service that writes to /dev/console."
1415 (operating-system
1416 (inherit os)
1417 (services (modify-services (operating-system-user-services os)
1418 (syslog-service-type config
1419 =>
1420 (syslog-configuration
1421 (inherit config)
1422 (config-file %syslog-conf)))))))
1423
1424(define %root-password "foo")
1425
1426(define* (gui-test-program marionette
1427 #:key
1428 (desktop? #f)
1429 (encrypted? #f)
1430 (uefi-support? #f)
1431 (system (%current-system)))
1432 #~(let ()
1433 (define (screenshot file)
1434 (marionette-control (string-append "screendump " file)
1435 #$marionette))
1436
1437 (define-syntax-rule (marionette-eval* exp marionette)
1438 (or (marionette-eval exp marionette)
1439 (throw 'marionette-eval-failure 'exp)))
1440
1441 (setvbuf (current-output-port) 'none)
1442 (setvbuf (current-error-port) 'none)
1443
1444 (marionette-eval* '(use-modules (gnu installer tests))
1445 #$marionette)
1446
1447 ;; Arrange so that 'converse' prints debugging output to the console.
1448 (marionette-eval* '(let ((console (open-output-file "/dev/console")))
1449 (setvbuf console 'none)
1450 (conversation-log-port console))
1451 #$marionette)
1452
1453 ;; Tell the installer to not wait for the Connman "online" status.
1454 (marionette-eval* '(call-with-output-file "/tmp/installer-assume-online"
1455 (const #t))
1456 #$marionette)
1457
1458 ;; Run 'guix system init' with '--no-grafts', to cope with the lack of
1459 ;; network access.
1460 (marionette-eval* '(call-with-output-file
1461 "/tmp/installer-system-init-options"
1462 (lambda (port)
1463 (write '("--no-grafts" "--no-substitutes")
1464 port)))
1465 #$marionette)
1466
1467 (marionette-eval* '(define installer-socket
1468 (open-installer-socket))
1469 #$marionette)
1470 (screenshot "installer-start.ppm")
1471
1472 (marionette-eval* '(choose-locale+keyboard installer-socket)
1473 #$marionette)
1474 (screenshot "installer-locale.ppm")
1475
1476 ;; Choose the host name that the "basic" test expects.
1477 (marionette-eval* '(enter-host-name+passwords installer-socket
1478 #:host-name "liberigilo"
1479 #:root-password
1480 #$%root-password
1481 #:users
1482 '(("alice" "pass1")
1483 ("bob" "pass2")))
1484 #$marionette)
1485 (screenshot "installer-services.ppm")
1486
1487 (marionette-eval* '(choose-services installer-socket
1488 #:choose-desktop-environment?
1489 (const #$desktop?)
1490 #:choose-network-service?
1491 (const #f))
1492 #$marionette)
1493 (screenshot "installer-partitioning.ppm")
1494
1495 (marionette-eval* '(choose-partitioning installer-socket
1496 #:encrypted? #$encrypted?
1497 #:passphrase #$%luks-passphrase
1498 #:uefi-support? #$uefi-support?)
1499 #$marionette)
1500 (screenshot "installer-run.ppm")
1501
1502 (unless #$encrypted?
1503 ;; At this point, user partitions are formatted and the installer is
1504 ;; waiting for us to start the final step: generating the
1505 ;; configuration file, etc. Set a fixed UUID on the swap partition
1506 ;; that matches what 'installation-target-os-for-gui-tests' expects.
1507 (marionette-eval* '(invoke #$(file-append util-linux "/sbin/swaplabel")
1508 "-U" "11111111-2222-3333-4444-123456789abc"
1509 "/dev/vda2")
1510 #$marionette))
1511
1512 (marionette-eval* '(start-installation installer-socket)
1513 #$marionette)
1514
1515 ;; XXX: The grub-install process uses efibootmgr to add an UEFI Guix
1516 ;; boot entry. The corresponding UEFI variable is stored in RAM, and
1517 ;; possibly saved persistently on QEMU reboot in a NvVars file, see:
1518 ;; https://lists.gnu.org/archive/html/qemu-discuss/2018-04/msg00045.html.
1519 ;;
1520 ;; As we are running QEMU with the no-reboot flag, this variable is
1521 ;; never saved persistently, QEMU fails to boot the installed system and
1522 ;; an UEFI shell is displayed instead.
1523 ;;
1524 ;; To make the installed UEFI system bootable, register Grub as the
1525 ;; default UEFI boot entry, in the same way as if grub-install was
1526 ;; invoked with the --removable option.
1527 (when #$uefi-support?
1528 (marionette-eval*
1529 '(begin
1530 (use-modules (ice-9 match))
1531 (let ((targets (cond
1532 ((string-prefix? "x86_64" #$system)
1533 '("grubx64.efi" "BOOTX64.EFI"))
1534 ((string-prefix? "i686" #$system)
1535 '("grubia32.efi" "BOOTIA32.EFI"))
1536 (else #f))))
1537 (match targets
1538 ((src dest)
1539 (rename-file "/mnt/boot/efi/EFI/Guix"
1540 "/mnt/boot/efi/EFI/BOOT")
1541 (rename-file
1542 (string-append "/mnt/boot/efi/EFI/BOOT/" src)
1543 (string-append "/mnt/boot/efi/EFI/BOOT/" dest)))
1544 (_ #f))))
1545 #$marionette))
1546
1547 (marionette-eval* '(complete-installation installer-socket)
1548 #$marionette)
1549 (sync)
1550 #t))
1551
1552(define %extra-packages
1553 ;; Packages needed when installing with an encrypted root.
1554 (list isc-dhcp
1555 lvm2-static cryptsetup-static e2fsck/static
1556 loadkeys-static grub-efi fatfsck/static dosfstools))
1557
1558(define installation-os-for-gui-tests
1559 ;; Operating system that contains all of %EXTRA-PACKAGES, needed for the
1560 ;; target OS, as well as syslog output redirected to the console so we can
1561 ;; see what the installer is up to.
1562 (marionette-operating-system
1563 (operating-system
1564 (inherit (operating-system-with-console-syslog
1565 (operating-system-add-packages
1566 (operating-system-with-current-guix
1567 installation-os)
1568 %extra-packages)))
1569 (kernel-arguments '("console=ttyS0")))
1570 #:imported-modules '((gnu services herd)
1571 (gnu installer tests)
1572 (guix combinators))))
1573
1574(define* (installation-target-os-for-gui-tests
1575 #:key
1576 (encrypted? #f)
1577 (uefi-support? #f))
1578 (operating-system
1579 (inherit %minimal-os-on-vda)
1580 (file-systems `(,(file-system
1581 (device (file-system-label "my-root"))
1582 (mount-point "/")
1583 (type "ext4"))
1584 ,@(if uefi-support?
1585 (list (file-system
1586 (device (uuid "1234-ABCD" 'fat))
1587 (mount-point "/boot/efi")
1588 (type "vfat")))
1589 '())
1590 ,@%base-file-systems))
1591 (users (append (list (user-account
1592 (name "alice")
1593 (comment "Bob's sister")
1594 (group "users")
1595 (supplementary-groups
1596 '("wheel" "audio" "video")))
1597 (user-account
1598 (name "bob")
1599 (comment "Alice's brother")
1600 (group "users")
1601 (supplementary-groups
1602 '("wheel" "audio" "video"))))
1603 %base-user-accounts))
1604 ;; The installer does not create a swap device in guided mode with
1605 ;; encryption support. The installer produces a UUID for the partition;
1606 ;; this "UUID" is explicitly set in 'gui-test-program' to the value shown
1607 ;; below.
1608 (swap-devices (if encrypted?
1609 '()
1610 (list (uuid "11111111-2222-3333-4444-123456789abc"))))
1611 (services (cons (service dhcp-client-service-type)
1612 (operating-system-user-services %minimal-os-on-vda)))))
1613
1614(define* (installation-target-desktop-os-for-gui-tests
1615 #:key (encrypted? #f))
1616 (operating-system
1617 (inherit (installation-target-os-for-gui-tests
1618 #:encrypted? encrypted?))
1619 (keyboard-layout (keyboard-layout "us" "altgr-intl"))
1620
1621 ;; Make sure that all the packages and services that may be used by the
1622 ;; graphical installer are available.
1623 (packages (append
1624 (list openbox awesome i3-wm i3status
1625 dmenu st ratpoison xterm
1626 emacs emacs-exwm emacs-desktop-environment)
1627 %base-packages))
1628 (services
1629 (append
1630 (list (service gnome-desktop-service-type)
1631 (service xfce-desktop-service-type)
1632 (service mate-desktop-service-type)
1633 (service enlightenment-desktop-service-type)
1634 (set-xorg-configuration
1635 (xorg-configuration
1636 (keyboard-layout keyboard-layout)))
1637 (service marionette-service-type
1638 (marionette-configuration
1639 (imported-modules '((gnu services herd)
1640 (guix build utils)
1641 (guix combinators))))))
1642 %desktop-services))))
1643
1644(define* (guided-installation-test name
1645 #:key
1646 (desktop? #f)
1647 (encrypted? #f)
1648 (uefi-support? #f)
1649 target-os
1650 (install-size 'guess)
1651 (target-size (* 2200 MiB)))
1652 (system-test
1653 (name name)
1654 (description
1655 "Install an OS using the graphical installer and test it.")
1656 (value
1657 (mlet* %store-monad
1658 ((image (run-install target-os '(this is unused)
1659 #:script #f
1660 #:os installation-os-for-gui-tests
1661 #:uefi-support? uefi-support?
1662 #:install-size install-size
1663 #:target-size target-size
1664 #:installation-image-type
1665 'uncompressed-iso9660
1666 #:gui-test
1667 (lambda (marionette)
1668 (gui-test-program
1669 marionette
1670 #:desktop? desktop?
1671 #:encrypted? encrypted?
1672 #:uefi-support? uefi-support?))))
1673 (command (qemu-command/writable-image image
1674 #:uefi-support? uefi-support?
1675 #:memory-size 512)))
1676 (run-basic-test target-os command name
1677 #:initialization (and encrypted? enter-luks-passphrase)
1678 #:root-password %root-password
1679 #:desktop? desktop?)))))
1680
1681(define %test-gui-installed-os
1682 (guided-installation-test
1683 "gui-installed-os"
1684 #:target-os (installation-target-os-for-gui-tests)))
1685
1686;; Test the UEFI installation of Guix System using the graphical installer.
1687(define %test-gui-uefi-installed-os
1688 (guided-installation-test
1689 "gui-uefi-installed-os"
1690 #:uefi-support? #t
1691 #:target-os (installation-target-os-for-gui-tests
1692 #:uefi-support? #t)
1693 #:target-size (* 3200 MiB)))
1694
1695(define %test-gui-installed-os-encrypted
1696 (guided-installation-test
1697 "gui-installed-os-encrypted"
1698 #:encrypted? #t
1699 #:target-os (installation-target-os-for-gui-tests
1700 #:encrypted? #t)))
1701
1702;; Building a desktop image is very time and space consuming. Install all
1703;; desktop environments in a single test to reduce the overhead.
1704(define %test-gui-installed-desktop-os-encrypted
1705 (guided-installation-test "gui-installed-desktop-os-encrypted"
1706 #:desktop? #t
1707 #:encrypted? #t
1708 #:target-os
1709 (installation-target-desktop-os-for-gui-tests
1710 #:encrypted? #t)
1711 ;; XXX: The disk-image size guess is too low. Use
1712 ;; a constant value until this is fixed.
1713 #:install-size (* 8000 MiB)
1714 #:target-size (* 9000 MiB)))
1715
1716;;; install.scm ends here