install.scm 60 KB

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