1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2016 Ludovic Courtès <ludo@gnu.org>
4 ;;; This file is part of GNU Guix.
6 ;;; GNU Guix is free software; you can redistribute it and/or modify it
7 ;;; under the terms of the GNU General Public License as published by
8 ;;; the Free Software Foundation; either version 3 of the License, or (at
9 ;;; your option) any later version.
11 ;;; GNU Guix is distributed in the hope that it will be useful, but
12 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;;; GNU General Public License for more details.
16 ;;; You should have received a copy of the GNU General Public License
17 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
19 (define-module (gnu tests install)
21 #:use-module (gnu tests)
22 #:use-module (gnu tests base)
23 #:use-module (gnu system)
24 #:use-module (gnu system install)
25 #:use-module (gnu system vm)
26 #:use-module ((gnu build vm) #:select (qemu-command))
27 #:use-module (gnu packages qemu)
28 #:use-module (gnu packages package-management)
29 #:use-module (guix store)
30 #:use-module (guix monads)
31 #:use-module (guix packages)
32 #:use-module (guix grafts)
33 #:use-module (guix gexp)
34 #:use-module (guix utils)
35 #:export (%test-installed-os))
39 ;;; Test the installation of GuixSD using the documented approach at the
44 (define-os-with-source (%minimal-os %minimal-os-source)
45 ;; The OS we want to install.
46 (use-modules (gnu) (gnu tests) (srfi srfi-1))
49 (host-name "liberigilo")
50 (timezone "Europe/Paris")
51 (locale "en_US.UTF-8")
53 (bootloader (grub-configuration (device "/dev/vdb")))
54 (kernel-arguments '("console=ttyS0"))
55 (file-systems (cons (file-system
61 (users (cons (user-account
63 (comment "Bob's sister")
65 (supplementary-groups '("wheel" "audio" "video"))
66 (home-directory "/home/alice"))
68 (services (cons (service marionette-service-type
73 (define (operating-system-with-current-guix os)
74 "Return a variant of OS that uses the current Guix."
77 (services (modify-services (operating-system-user-services os)
78 (guix-service-type config =>
81 (guix (current-guix))))))))
83 (define (operating-system-with-gc-roots os roots)
84 "Return a variant of OS where ROOTS are registered as GC roots."
87 (services (cons (service gc-root-service-type roots)
88 (operating-system-user-services os)))))
91 (define MiB (expt 2 20))
93 (define* (run-install #:key
94 (os (marionette-operating-system
95 ;; Since the image has no network access, use the
96 ;; current Guix so the store items we need are in
99 (inherit (operating-system-with-current-guix
101 (kernel-arguments '("console=ttyS0")))
102 #:imported-modules '((gnu services herd)
103 (guix combinators))))
104 (target-size (* 1200 MiB)))
105 "Run the GuixSD installation procedure from OS and return a VM image of
106 TARGET-SIZE bytes containing the installed system."
108 (mlet* %store-monad ((_ (set-grafting #f))
109 (system (current-system))
110 (target (operating-system-derivation %minimal-os))
112 ;; Since the installation system has no network access,
113 ;; we cheat a little bit by adding TARGET to its GC
114 ;; roots. This way, we know 'guix system init' will
116 (image (system-disk-image
117 (operating-system-with-gc-roots
119 #:disk-image-size (* 1500 MiB))))
122 (use-modules (guix build utils)
123 (gnu build marionette))
125 (set-path-environment-variable "PATH" '("bin")
126 (list #$qemu-minimal))
128 (system* "qemu-img" "create" "-f" "qcow2"
129 #$output #$(number->string target-size))
133 (cons (which #$(qemu-command system))
134 (cons* "-no-reboot" "-m" "800"
136 (string-append "file=" #$image
137 ",if=virtio,readonly")
139 (string-append "file=" #$output ",if=virtio")
140 (if (file-exists? "/dev/kvm")
144 (pk 'uname (marionette-eval '(uname) marionette))
147 (marionette-eval '(begin
148 (use-modules (gnu services herd))
152 (marionette-eval '(call-with-output-file "/etc/litl-config.scm"
154 (write '#$%minimal-os-source port)))
157 (exit (marionette-eval '(zero? (system "
161 guix gc --list-live | grep isc-dhcp
163 export GUIX_BUILD_OPTIONS=--no-grafts
165 parted --script /dev/vdb mklabel gpt \\
166 mkpart primary ext2 1M 3M \\
167 mkpart primary ext2 3M 1G \\
170 mkfs.ext4 -L my-root /dev/vdb2
174 herd start cow-store /mnt
176 cp /etc/litl-config.scm /mnt/etc/config.scm
177 guix system init /mnt/etc/config.scm /mnt --no-substitutes
182 (gexp->derivation "installation" install
183 #:modules '((guix build utils)
184 (gnu build marionette)))))
187 (define %test-installed-os
189 (name "installed-os")
191 "Test basic functionality of an OS installed like one would do by hand.
192 This test is expensive in terms of CPU and storage usage since we need to
193 build (current-guix) and then store a couple of full system images.")
195 (mlet %store-monad ((image (run-install))
196 (system (current-system)))
197 (run-basic-test %minimal-os
198 #~(let ((image #$image))
199 ;; First we need a writable copy of the image.
200 (format #t "copying image '~a'...~%" image)
201 (copy-file image "disk.img")
202 (chmod "disk.img" #o644)
203 (list (string-append #$qemu-minimal "/bin/"
204 #$(qemu-command system))
205 "-enable-kvm" "-no-reboot" "-m" "256"
206 "-drive" "file=disk.img,if=virtio"))
209 ;;; install.scm ends here