Commit | Line | Data |
---|---|---|
04086015 | 1 | ;;; GNU Guix --- Functional package management for GNU |
29824d80 | 2 | ;;; Copyright © 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org> |
944d2b17 CAW |
3 | ;;; Copyright © 2016 Christopher Allan Webber <cwebber@dustycloud.org> |
4 | ;;; Copyright © 2016 Leo Famulari <leo@famulari.name> | |
04086015 LC |
5 | ;;; |
6 | ;;; This file is part of GNU Guix. | |
7 | ;;; | |
8 | ;;; GNU Guix is free software; you can redistribute it and/or modify it | |
9 | ;;; under the terms of the GNU General Public License as published by | |
10 | ;;; the Free Software Foundation; either version 3 of the License, or (at | |
11 | ;;; your option) any later version. | |
12 | ;;; | |
13 | ;;; GNU Guix is distributed in the hope that it will be useful, but | |
14 | ;;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | ;;; GNU General Public License for more details. | |
17 | ;;; | |
18 | ;;; You should have received a copy of the GNU General Public License | |
19 | ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. | |
20 | ||
21 | (define-module (gnu system vm) | |
93d44bd8 | 22 | #:use-module (guix config) |
04086015 | 23 | #:use-module (guix store) |
02100028 | 24 | #:use-module (guix gexp) |
04086015 LC |
25 | #:use-module (guix derivations) |
26 | #:use-module (guix packages) | |
d9f0a237 | 27 | #:use-module (guix monads) |
fcf63cf8 LC |
28 | #:use-module (guix records) |
29 | ||
548f7a8f | 30 | #:use-module ((gnu build vm) |
66670cf3 | 31 | #:select (qemu-command)) |
bdb36958 | 32 | #:use-module (gnu packages base) |
1b89a66e | 33 | #:use-module (gnu packages guile) |
bdb36958 | 34 | #:use-module (gnu packages gawk) |
1b89a66e | 35 | #:use-module (gnu packages bash) |
4f62d8d6 | 36 | #:use-module (gnu packages less) |
04086015 | 37 | #:use-module (gnu packages qemu) |
cc4a2aeb | 38 | #:use-module (gnu packages disk) |
5b16ff09 | 39 | #:use-module (gnu packages zile) |
04086015 LC |
40 | #:use-module (gnu packages grub) |
41 | #:use-module (gnu packages linux) | |
30f25b03 | 42 | #:use-module (gnu packages package-management) |
04086015 LC |
43 | #:use-module ((gnu packages make-bootstrap) |
44 | #:select (%guile-static-stripped)) | |
9de46ffb | 45 | #:use-module (gnu packages admin) |
0ded70f3 LC |
46 | |
47 | #:use-module (gnu system shadow) | |
6e828634 | 48 | #:use-module (gnu system pam) |
735c6dd7 | 49 | #:use-module (gnu system linux-initrd) |
0ded70f3 | 50 | #:use-module (gnu system grub) |
c5df1839 | 51 | #:use-module (gnu system file-systems) |
033adfe7 | 52 | #:use-module (gnu system) |
db4fdc04 | 53 | #:use-module (gnu services) |
0ded70f3 | 54 | |
ca85d7bc | 55 | #:use-module (srfi srfi-1) |
04086015 LC |
56 | #:use-module (srfi srfi-26) |
57 | #:use-module (ice-9 match) | |
0ded70f3 | 58 | |
04086015 | 59 | #:export (expression->derivation-in-linux-vm |
aedb72fb | 60 | qemu-image |
e9f693d0 | 61 | virtualized-operating-system |
fd3bfc44 | 62 | system-qemu-image |
fcf63cf8 | 63 | |
fd3bfc44 | 64 | system-qemu-image/shared-store |
1e77fedb LC |
65 | system-qemu-image/shared-store-script |
66 | system-disk-image)) | |
04086015 LC |
67 | |
68 | \f | |
69 | ;;; Commentary: | |
70 | ;;; | |
71 | ;;; Tools to evaluate build expressions within virtual machines. | |
72 | ;;; | |
73 | ;;; Code: | |
74 | ||
83bcd0b8 LC |
75 | (define %linux-vm-file-systems |
76 | ;; File systems mounted for 'derivation-in-linux-vm'. The store and /xchg | |
77 | ;; directory are shared with the host over 9p. | |
78 | (list (file-system | |
79 | (mount-point (%store-prefix)) | |
80 | (device "store") | |
81 | (type "9p") | |
82 | (needed-for-boot? #t) | |
3c05b4bc LC |
83 | (options "trans=virtio") |
84 | (check? #f)) | |
83bcd0b8 LC |
85 | (file-system |
86 | (mount-point "/xchg") | |
87 | (device "xchg") | |
88 | (type "9p") | |
89 | (needed-for-boot? #t) | |
3c05b4bc LC |
90 | (options "trans=virtio") |
91 | (check? #f)))) | |
83bcd0b8 | 92 | |
d9f0a237 | 93 | (define* (expression->derivation-in-linux-vm name exp |
04086015 | 94 | #:key |
2455085a | 95 | (system (%current-system)) |
04086015 | 96 | (linux linux-libre) |
735c6dd7 | 97 | initrd |
06da1a6b | 98 | (qemu qemu-minimal) |
04086015 | 99 | (env-vars '()) |
1aa0033b | 100 | (modules |
548f7a8f LC |
101 | '((gnu build vm) |
102 | (gnu build install) | |
8a9e21d1 | 103 | (gnu build linux-boot) |
0e704a2d | 104 | (gnu build linux-modules) |
e2f4b305 | 105 | (gnu build file-systems) |
0e704a2d | 106 | (guix elf) |
72b891e5 | 107 | (guix records) |
6fd1a796 | 108 | (guix build utils) |
1e49bcf9 | 109 | (guix build syscalls) |
6eb43907 | 110 | (guix build bournish) |
6fd1a796 | 111 | (guix build store-copy))) |
04086015 LC |
112 | (guile-for-build |
113 | (%guile-for-build)) | |
114 | ||
115 | (make-disk-image? #f) | |
ca85d7bc | 116 | (references-graphs #f) |
defa1b9b | 117 | (memory-size 256) |
c4a74364 | 118 | (disk-image-format "qcow2") |
04086015 LC |
119 | (disk-image-size |
120 | (* 100 (expt 2 20)))) | |
735c6dd7 | 121 | "Evaluate EXP in a QEMU virtual machine running LINUX with INITRD (a |
1aa0033b | 122 | derivation). In the virtual machine, EXP has access to all its inputs from the |
735c6dd7 | 123 | store; it should put its output files in the `/xchg' directory, which is |
defa1b9b LC |
124 | copied to the derivation's output when the VM terminates. The virtual machine |
125 | runs with MEMORY-SIZE MiB of memory. | |
04086015 | 126 | |
c4a74364 LC |
127 | When MAKE-DISK-IMAGE? is true, then create a QEMU disk image of type |
128 | DISK-IMAGE-FORMAT (e.g., 'qcow2' or 'raw'), of DISK-IMAGE-SIZE bytes and | |
129 | return it. | |
ca85d7bc | 130 | |
1aa0033b | 131 | MODULES is the set of modules imported in the execution environment of EXP. |
ade5ce7a | 132 | |
ca85d7bc LC |
133 | When REFERENCES-GRAPHS is true, it must be a list of file name/store path |
134 | pairs, as for `derivation'. The files containing the reference graphs are | |
135 | made available under the /xchg CIFS share." | |
d9f0a237 | 136 | (mlet* %store-monad |
1aa0033b LC |
137 | ((module-dir (imported-modules modules)) |
138 | (compiled (compiled-modules modules)) | |
139 | (user-builder (gexp->file "builder-in-linux-vm" exp)) | |
02100028 LC |
140 | (loader (gexp->file "linux-vm-loader" |
141 | #~(begin | |
142 | (set! %load-path | |
143 | (cons #$module-dir %load-path)) | |
144 | (set! %load-compiled-path | |
145 | (cons #$compiled | |
146 | %load-compiled-path)) | |
147 | (primitive-load #$user-builder)))) | |
bdb36958 | 148 | (coreutils -> (canonical-package coreutils)) |
d4254711 | 149 | (initrd (if initrd ; use the default initrd? |
735c6dd7 | 150 | (return initrd) |
060238ae | 151 | (base-initrd %linux-vm-file-systems |
0d275f4a | 152 | #:linux linux |
24e0160a | 153 | #:virtio? #t |
6c1df081 | 154 | #:qemu-networking? #t)))) |
1aa0033b LC |
155 | |
156 | (define builder | |
157 | ;; Code that launches the VM that evaluates EXP. | |
158 | #~(begin | |
159 | (use-modules (guix build utils) | |
548f7a8f | 160 | (gnu build vm)) |
1aa0033b LC |
161 | |
162 | (let ((inputs '#$(list qemu coreutils)) | |
163 | (linux (string-append #$linux "/bzImage")) | |
164 | (initrd (string-append #$initrd "/initrd")) | |
165 | (loader #$loader) | |
166 | (graphs '#$(match references-graphs | |
167 | (((graph-files . _) ...) graph-files) | |
168 | (_ #f)))) | |
169 | ||
170 | (set-path-environment-variable "PATH" '("bin") inputs) | |
171 | ||
172 | (load-in-linux-vm loader | |
173 | #:output #$output | |
174 | #:linux linux #:initrd initrd | |
175 | #:memory-size #$memory-size | |
176 | #:make-disk-image? #$make-disk-image? | |
c4a74364 | 177 | #:disk-image-format #$disk-image-format |
1aa0033b LC |
178 | #:disk-image-size #$disk-image-size |
179 | #:references-graphs graphs)))) | |
180 | ||
181 | (gexp->derivation name builder | |
182 | ;; TODO: Require the "kvm" feature. | |
183 | #:system system | |
184 | #:env-vars env-vars | |
5ce3defe | 185 | #:modules modules |
1aa0033b LC |
186 | #:guile-for-build guile-for-build |
187 | #:references-graphs references-graphs))) | |
d9f0a237 LC |
188 | |
189 | (define* (qemu-image #:key | |
04086015 LC |
190 | (name "qemu-image") |
191 | (system (%current-system)) | |
06da1a6b | 192 | (qemu qemu-minimal) |
04086015 | 193 | (disk-image-size (* 100 (expt 2 20))) |
c4a74364 | 194 | (disk-image-format "qcow2") |
03ddfaf5 | 195 | (file-system-type "ext4") |
ef9fc40d | 196 | file-system-label |
f2c403ea | 197 | os-derivation |
0e2ddecd | 198 | grub-configuration |
150e20dd | 199 | (register-closures? #t) |
150e20dd LC |
200 | (inputs '()) |
201 | copy-inputs?) | |
c4a74364 | 202 | "Return a bootable, stand-alone QEMU image of type DISK-IMAGE-FORMAT (e.g., |
ef9fc40d LC |
203 | 'qcow2' or 'raw'), with a root partition of type FILE-SYSTEM-TYPE. |
204 | Optionally, FILE-SYSTEM-LABEL can be specified as the volume name for the root | |
f2c403ea LC |
205 | partition. The returned image is a full disk image that runs OS-DERIVATION, |
206 | with a GRUB installation that uses GRUB-CONFIGURATION as its configuration | |
207 | file (GRUB-CONFIGURATION must be the name of a file in the VM.) | |
93d44bd8 | 208 | |
150e20dd LC |
209 | INPUTS is a list of inputs (as for packages). When COPY-INPUTS? is true, copy |
210 | all of INPUTS into the image being built. When REGISTER-CLOSURES? is true, | |
211 | register INPUTS in the store database of the image so that Guix can be used in | |
b4140694 | 212 | the image." |
b53833b2 LC |
213 | (expression->derivation-in-linux-vm |
214 | name | |
215 | #~(begin | |
216 | (use-modules (gnu build vm) | |
217 | (guix build utils)) | |
1aa0033b | 218 | |
b53833b2 | 219 | (let ((inputs |
ec2406ef | 220 | '#$(append (list qemu parted grub e2fsprogs) |
b53833b2 LC |
221 | (map canonical-package |
222 | (list sed grep coreutils findutils gawk)) | |
223 | (if register-closures? (list guix) '()))) | |
1aa0033b | 224 | |
b53833b2 LC |
225 | ;; This variable is unused but allows us to add INPUTS-TO-COPY |
226 | ;; as inputs. | |
227 | (to-register | |
228 | '#$(map (match-lambda | |
229 | ((name thing) thing) | |
230 | ((name thing output) `(,thing ,output))) | |
231 | inputs))) | |
1aa0033b | 232 | |
b53833b2 | 233 | (set-path-environment-variable "PATH" '("bin" "sbin") inputs) |
1aa0033b | 234 | |
72b891e5 LC |
235 | (let* ((graphs '#$(match inputs |
236 | (((names . _) ...) | |
237 | names))) | |
238 | (initialize (root-partition-initializer | |
239 | #:closures graphs | |
240 | #:copy-closures? #$copy-inputs? | |
241 | #:register-closures? #$register-closures? | |
242 | #:system-directory #$os-derivation)) | |
243 | (partitions (list (partition | |
244 | (size #$(- disk-image-size | |
245 | (* 10 (expt 2 20)))) | |
246 | (label #$file-system-label) | |
247 | (file-system #$file-system-type) | |
248 | (bootable? #t) | |
249 | (initializer initialize))))) | |
b53833b2 | 250 | (initialize-hard-disk "/dev/vda" |
72b891e5 LC |
251 | #:partitions partitions |
252 | #:grub.cfg #$grub-configuration) | |
b53833b2 LC |
253 | (reboot)))) |
254 | #:system system | |
255 | #:make-disk-image? #t | |
256 | #:disk-image-size disk-image-size | |
257 | #:disk-image-format disk-image-format | |
258 | #:references-graphs inputs)) | |
04086015 LC |
259 | |
260 | \f | |
261 | ;;; | |
1e77fedb | 262 | ;;; VM and disk images. |
04086015 LC |
263 | ;;; |
264 | ||
1e77fedb LC |
265 | (define* (system-disk-image os |
266 | #:key | |
56ef7fcc | 267 | (name "disk-image") |
1e77fedb LC |
268 | (file-system-type "ext4") |
269 | (disk-image-size (* 900 (expt 2 20))) | |
270 | (volatile? #t)) | |
271 | "Return the derivation of a disk image of DISK-IMAGE-SIZE bytes of the | |
272 | system described by OS. Said image can be copied on a USB stick as is. When | |
273 | VOLATILE? is true, the root file system is made volatile; this is useful | |
274 | to USB sticks meant to be read-only." | |
10ace2c4 LC |
275 | (define root-label |
276 | ;; Volume name of the root file system. Since we don't know which device | |
277 | ;; will hold it, we use the volume name to find it (using the UUID would | |
278 | ;; be even better, but somewhat less convenient.) | |
279 | "gnu-disk-image") | |
280 | ||
1e77fedb LC |
281 | (define file-systems-to-keep |
282 | (remove (lambda (fs) | |
283 | (string=? (file-system-mount-point fs) "/")) | |
284 | (operating-system-file-systems os))) | |
285 | ||
286 | (let ((os (operating-system (inherit os) | |
932e1f92 | 287 | ;; Since this is meant to be used on real hardware, don't |
493c245b LC |
288 | ;; install QEMU networking or anything like that. Assume USB |
289 | ;; mass storage devices (usb-storage.ko) are available. | |
52ac153e LC |
290 | (initrd (lambda (file-systems . rest) |
291 | (apply base-initrd file-systems | |
292 | #:volatile-root? #t | |
52ac153e | 293 | rest))) |
1e77fedb LC |
294 | |
295 | ;; Force our own root file system. | |
296 | (file-systems (cons (file-system | |
297 | (mount-point "/") | |
10ace2c4 | 298 | (device root-label) |
d4c87617 | 299 | (title 'label) |
1e77fedb LC |
300 | (type file-system-type)) |
301 | file-systems-to-keep))))) | |
302 | ||
303 | (mlet* %store-monad ((os-drv (operating-system-derivation os)) | |
304 | (grub.cfg (operating-system-grub.cfg os))) | |
56ef7fcc | 305 | (qemu-image #:name name |
f2c403ea | 306 | #:os-derivation os-drv |
56ef7fcc | 307 | #:grub-configuration grub.cfg |
1e77fedb LC |
308 | #:disk-image-size disk-image-size |
309 | #:disk-image-format "raw" | |
310 | #:file-system-type file-system-type | |
10ace2c4 | 311 | #:file-system-label root-label |
1e77fedb LC |
312 | #:copy-inputs? #t |
313 | #:register-closures? #t | |
314 | #:inputs `(("system" ,os-drv) | |
315 | ("grub.cfg" ,grub.cfg)))))) | |
316 | ||
0b14d1d7 | 317 | (define* (system-qemu-image os |
66f23d66 LC |
318 | #:key |
319 | (file-system-type "ext4") | |
320 | (disk-image-size (* 900 (expt 2 20)))) | |
321 | "Return the derivation of a freestanding QEMU image of DISK-IMAGE-SIZE bytes | |
322 | of the GNU system as described by OS." | |
1eeccc2f LC |
323 | (define file-systems-to-keep |
324 | ;; Keep only file systems other than root and not normally bound to real | |
325 | ;; devices. | |
326 | (remove (lambda (fs) | |
327 | (let ((target (file-system-mount-point fs)) | |
328 | (source (file-system-device fs))) | |
329 | (or (string=? target "/") | |
330 | (string-prefix? "/dev/" source)))) | |
331 | (operating-system-file-systems os))) | |
332 | ||
66f23d66 | 333 | (let ((os (operating-system (inherit os) |
e84d8b30 | 334 | ;; Use an initrd with the whole QEMU shebang. |
52ac153e LC |
335 | (initrd (lambda (file-systems . rest) |
336 | (apply base-initrd file-systems | |
337 | #:virtio? #t | |
338 | #:qemu-networking? #t | |
339 | rest))) | |
e84d8b30 | 340 | |
1eeccc2f LC |
341 | ;; Force our own root file system. |
342 | (file-systems (cons (file-system | |
66f23d66 LC |
343 | (mount-point "/") |
344 | (device "/dev/sda1") | |
1eeccc2f LC |
345 | (type file-system-type)) |
346 | file-systems-to-keep))))) | |
66f23d66 LC |
347 | (mlet* %store-monad |
348 | ((os-drv (operating-system-derivation os)) | |
b4140694 | 349 | (grub.cfg (operating-system-grub.cfg os))) |
f2c403ea LC |
350 | (qemu-image #:os-derivation os-drv |
351 | #:grub-configuration grub.cfg | |
66f23d66 LC |
352 | #:disk-image-size disk-image-size |
353 | #:file-system-type file-system-type | |
b4140694 LC |
354 | #:inputs `(("system" ,os-drv) |
355 | ("grub.cfg" ,grub.cfg)) | |
150e20dd | 356 | #:copy-inputs? #t)))) |
04086015 | 357 | |
fcf63cf8 LC |
358 | \f |
359 | ;;; | |
360 | ;;; VMs that share file systems with the host. | |
361 | ;;; | |
362 | ||
96ffa27b LC |
363 | (define (file-system->mount-tag fs) |
364 | "Return a 9p mount tag for host file system FS." | |
365 | ;; QEMU mount tags cannot contain slashes and cannot start with '_'. | |
366 | ;; Compute an identifier that corresponds to the rules. | |
367 | (string-append "TAG" | |
368 | (string-map (match-lambda | |
369 | (#\/ #\_) | |
370 | (chr chr)) | |
371 | fs))) | |
372 | ||
fcf63cf8 LC |
373 | (define (mapping->file-system mapping) |
374 | "Return a 9p file system that realizes MAPPING." | |
375 | (match mapping | |
376 | (($ <file-system-mapping> source target writable?) | |
377 | (file-system | |
378 | (mount-point target) | |
379 | (device (file-system->mount-tag source)) | |
380 | (type "9p") | |
381 | (flags (if writable? '() '(read-only))) | |
382 | (options (string-append "trans=virtio")) | |
383 | (check? #f) | |
384 | (create-mount-point? #t))))) | |
385 | ||
386 | (define (virtualized-operating-system os mappings) | |
83bcd0b8 | 387 | "Return an operating system based on OS suitable for use in a virtualized |
fcf63cf8 LC |
388 | environment with the store shared with the host. MAPPINGS is a list of |
389 | <file-system-mapping> to realize in the virtualized OS." | |
390 | (define user-file-systems | |
391 | ;; Remove file systems that conflict with those added below, or that are | |
392 | ;; normally bound to real devices. | |
393 | (remove (lambda (fs) | |
394 | (let ((target (file-system-mount-point fs)) | |
395 | (source (file-system-device fs))) | |
396 | (or (string=? target (%store-prefix)) | |
397 | (string=? target "/") | |
29824d80 LC |
398 | (and (eq? 'device (file-system-title fs)) |
399 | (string-prefix? "/dev/" source))))) | |
fcf63cf8 LC |
400 | (operating-system-file-systems os))) |
401 | ||
83bcd0b8 | 402 | (operating-system (inherit os) |
52ac153e LC |
403 | (initrd (lambda (file-systems . rest) |
404 | (apply base-initrd file-systems | |
405 | #:volatile-root? #t | |
406 | #:virtio? #t | |
407 | #:qemu-networking? #t | |
408 | rest))) | |
65fb4515 LC |
409 | |
410 | ;; Disable swap. | |
411 | (swap-devices '()) | |
412 | ||
1eeccc2f LC |
413 | (file-systems (cons* (file-system |
414 | (mount-point "/") | |
415 | (device "/dev/vda1") | |
416 | (type "ext4")) | |
96ffa27b LC |
417 | |
418 | (file-system (inherit | |
fcf63cf8 | 419 | (mapping->file-system %store-mapping)) |
96ffa27b | 420 | (needed-for-boot? #t)) |
1eeccc2f | 421 | |
fcf63cf8 LC |
422 | (append (map mapping->file-system mappings) |
423 | user-file-systems))))) | |
83bcd0b8 | 424 | |
fd3bfc44 | 425 | (define* (system-qemu-image/shared-store |
0b14d1d7 | 426 | os |
6aa260af LC |
427 | #:key |
428 | full-boot? | |
4c0416ae | 429 | (disk-image-size (* (if full-boot? 500 30) (expt 2 20)))) |
fd3bfc44 | 430 | "Return a derivation that builds a QEMU image of OS that shares its store |
6aa260af LC |
431 | with the host. |
432 | ||
433 | When FULL-BOOT? is true, return an image that does a complete boot sequence, | |
434 | bootloaded included; thus, make a disk image that contains everything the | |
435 | bootloader refers to: OS kernel, initrd, bootloader data, etc." | |
436 | (mlet* %store-monad ((os-drv (operating-system-derivation os)) | |
437 | (grub.cfg (operating-system-grub.cfg os))) | |
438 | ;; XXX: When FULL-BOOT? is true, we end up creating an image that contains | |
439 | ;; GRUB.CFG and all its dependencies, including the output of OS-DRV. | |
440 | ;; This is more than needed (we only need the kernel, initrd, GRUB for its | |
441 | ;; font, and the background image), but it's hard to filter that. | |
f2c403ea LC |
442 | (qemu-image #:os-derivation os-drv |
443 | #:grub-configuration grub.cfg | |
150e20dd | 444 | #:disk-image-size disk-image-size |
6aa260af LC |
445 | #:inputs (if full-boot? |
446 | `(("grub.cfg" ,grub.cfg)) | |
447 | '()) | |
150e20dd LC |
448 | |
449 | ;; XXX: Passing #t here is too slow, so let it off by default. | |
450 | #:register-closures? #f | |
6aa260af | 451 | #:copy-inputs? full-boot?))) |
fd3bfc44 | 452 | |
96ffa27b LC |
453 | (define* (common-qemu-options image shared-fs) |
454 | "Return the a string-value gexp with the common QEMU options to boot IMAGE, | |
455 | with '-virtfs' options for the host file systems listed in SHARED-FS." | |
456 | (define (virtfs-option fs) | |
457 | #~(string-append "-virtfs local,path=\"" #$fs | |
458 | "\",security_model=none,mount_tag=\"" | |
459 | #$(file-system->mount-tag fs) | |
460 | "\" ")) | |
461 | ||
462 | #~(string-append | |
944d2b17 CAW |
463 | ;; Only enable kvm if we see /dev/kvm exists. |
464 | ;; This allows users without hardware virtualization to still use these | |
465 | ;; commands. | |
466 | #$(if (file-exists? "/dev/kvm") | |
467 | " -enable-kvm " | |
468 | "") | |
469 | " -no-reboot -net nic,model=virtio \ | |
96ffa27b | 470 | " #$@(map virtfs-option shared-fs) " \ |
3c1f0e3b | 471 | -net user \ |
957afcae | 472 | -vga std \ |
3c1f0e3b LC |
473 | -drive file=" #$image |
474 | ",if=virtio,cache=writeback,werror=report,readonly \ | |
810568b3 | 475 | -m 256")) |
3c1f0e3b | 476 | |
ab11f0be LC |
477 | (define* (system-qemu-image/shared-store-script os |
478 | #:key | |
479 | (qemu qemu) | |
480 | (graphic? #t) | |
fcf63cf8 | 481 | (mappings '()) |
6aa260af LC |
482 | full-boot? |
483 | (disk-image-size | |
4c0416ae | 484 | (* (if full-boot? 500 30) |
6aa260af | 485 | (expt 2 20)))) |
fd3bfc44 | 486 | "Return a derivation that builds a script to run a virtual machine image of |
6aa260af LC |
487 | OS that shares its store with the host. |
488 | ||
fcf63cf8 LC |
489 | MAPPINGS is a list of <file-system-mapping> specifying mapping of host file |
490 | systems into the guest. | |
491 | ||
6aa260af LC |
492 | When FULL-BOOT? is true, the returned script runs everything starting from the |
493 | bootloader; otherwise it directly starts the operating system kernel. The | |
494 | DISK-IMAGE-SIZE parameter specifies the size in bytes of the root disk image; | |
495 | it is mostly useful when FULL-BOOT? is true." | |
fcf63cf8 | 496 | (mlet* %store-monad ((os -> (virtualized-operating-system os mappings)) |
6aa260af LC |
497 | (os-drv (operating-system-derivation os)) |
498 | (image (system-qemu-image/shared-store | |
499 | os | |
500 | #:full-boot? full-boot? | |
501 | #:disk-image-size disk-image-size))) | |
fd3bfc44 | 502 | (define builder |
02100028 LC |
503 | #~(call-with-output-file #$output |
504 | (lambda (port) | |
505 | (display | |
506 | (string-append "#!" #$bash "/bin/sh | |
66670cf3 | 507 | exec " #$qemu "/bin/" #$(qemu-command (%current-system)) |
ab11f0be LC |
508 | |
509 | #$@(if full-boot? | |
510 | #~() | |
511 | #~(" -kernel " #$(operating-system-kernel os) "/bzImage \ | |
512 | -initrd " #$os-drv "/initrd \ | |
513 | -append \"" #$(if graphic? "" "console=ttyS0 ") | |
ee2a6304 LC |
514 | "--system=" #$os-drv " --load=" #$os-drv "/boot --root=/dev/vda1 " |
515 | (string-join (list #+@(operating-system-kernel-arguments os))) "\" ")) | |
fcf63cf8 LC |
516 | #$(common-qemu-options image |
517 | (map file-system-mapping-source | |
518 | (cons %store-mapping mappings))) | |
810568b3 | 519 | " \"$@\"\n") |
02100028 LC |
520 | port) |
521 | (chmod port #o555)))) | |
522 | ||
523 | (gexp->derivation "run-vm.sh" builder))) | |
fd3bfc44 | 524 | |
04086015 | 525 | ;;; vm.scm ends here |