install.scm 75 KB

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