install.scm 58 KB

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