image.scm 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2022 Mathieu Othacehe <othacehe@gnu.org>
  3. ;;;
  4. ;;; This file is part of GNU Guix.
  5. ;;;
  6. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  7. ;;; under the terms of the GNU General Public License as published by
  8. ;;; the Free Software Foundation; either version 3 of the License, or (at
  9. ;;; your option) any later version.
  10. ;;;
  11. ;;; GNU Guix is distributed in the hope that it will be useful, but
  12. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;;; GNU General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  18. (define-module (gnu tests image)
  19. #:use-module (gnu)
  20. #:use-module (gnu image)
  21. #:use-module (gnu tests)
  22. #:autoload (gnu system image) (system-image root-offset image-with-os efi-disk-image)
  23. #:use-module (gnu system uuid)
  24. #:use-module (gnu system vm)
  25. #:use-module (gnu packages guile)
  26. #:use-module (gnu packages guile-xyz)
  27. #:use-module (guix gexp)
  28. #:use-module (guix monads)
  29. #:use-module (ice-9 format)
  30. #:export (%test-images))
  31. ;;; Commentary:
  32. ;;;
  33. ;;; This module provides tests for the image creation process that is
  34. ;;; performed by "genimage" under the hood.
  35. ;;;
  36. ;;; The image partitionment is checked using Guile-Parted. The content of the
  37. ;;; images is out of the scope of this module. Other test modules such as
  38. ;;; (gnu tests installation) make sure that the produced images are viable.
  39. ;;;
  40. ;;; Code:
  41. ;; A dummy initializer creating a simple file in the partition.
  42. (define dummy-initializer
  43. #~(lambda* (root . rest)
  44. (mkdir root)
  45. (call-with-output-file
  46. (string-append root "/test")
  47. (lambda (port)
  48. (format port "content")))))
  49. (define %simple-efi-os
  50. (operating-system
  51. (inherit %simple-os)
  52. (bootloader (bootloader-configuration
  53. (bootloader grub-efi-bootloader)
  54. (targets '("/boot/efi"))))))
  55. ;; An MBR disk image with a single ext4 partition.
  56. (define i1
  57. (image
  58. (format 'disk-image)
  59. (operating-system %simple-os)
  60. (partitions
  61. (list
  62. (partition
  63. (size (* 1024 1024)) ;1MiB
  64. (offset root-offset)
  65. (label "test")
  66. (file-system "ext4")
  67. (flags '(boot))
  68. (initializer dummy-initializer))))))
  69. ;; A GPT disk image with a single ext4 partition.
  70. (define i2
  71. (image
  72. (format 'disk-image)
  73. (operating-system %simple-efi-os)
  74. (partition-table-type 'gpt)
  75. (partitions
  76. (list
  77. (partition
  78. (size (* 1024 1024)) ;1MiB
  79. (offset root-offset)
  80. (label "test")
  81. (file-system "ext4")
  82. (flags '(boot))
  83. (initializer dummy-initializer))))))
  84. ;; An MBR disk image with multiple ext4 partitions.
  85. (define i3
  86. (image
  87. (format 'disk-image)
  88. (operating-system %simple-os)
  89. (partitions
  90. (list
  91. (partition
  92. (size (* 1024 1024)) ;1MiB
  93. (offset root-offset)
  94. (label "test")
  95. (file-system "ext4")
  96. (flags '(boot))
  97. (initializer dummy-initializer))
  98. (partition
  99. (size (* 1024 1024)) ;1MiB
  100. (label "test2")
  101. (file-system "ext4")
  102. (flags '())
  103. (initializer dummy-initializer))))))
  104. ;; A GPT disk image with multiple ext4 partitions.
  105. (define i4
  106. (image
  107. (format 'disk-image)
  108. (operating-system %simple-efi-os)
  109. (partition-table-type 'gpt)
  110. (partitions
  111. (list
  112. (partition
  113. (size (* 1024 1024)) ;1MiB
  114. (offset root-offset)
  115. (label "test")
  116. (file-system "ext4")
  117. (flags '(boot))
  118. (initializer dummy-initializer))
  119. (partition
  120. (size (* 1024 1024)) ;1MiB
  121. (label "test2")
  122. (file-system "ext4")
  123. (flags '())
  124. (initializer dummy-initializer))))))
  125. ;; A GPT disk image with fat32 and ext4 partitions.
  126. (define i5
  127. (image
  128. (format 'disk-image)
  129. (operating-system %simple-efi-os)
  130. (partition-table-type 'gpt)
  131. (partitions
  132. (list
  133. (partition
  134. (size (* 1024 1024 128)) ;128MiB
  135. (offset root-offset)
  136. (label "test")
  137. (file-system "fat32")
  138. (flags '(esp))
  139. (initializer dummy-initializer))
  140. (partition
  141. (size (* 1024 1024 256)) ;256MiB
  142. (label "test2")
  143. (file-system "ext4")
  144. (flags '(boot))
  145. (initializer dummy-initializer))))))
  146. ;; A efi disk image with default partitions
  147. (define i6
  148. (image-with-os efi-disk-image %simple-efi-os))
  149. (define (run-images-test)
  150. (define test
  151. (with-imported-modules '((srfi srfi-64)
  152. (gnu build marionette))
  153. (with-extensions (list guile-parted guile-bytestructures)
  154. #~(begin
  155. (use-modules (gnu build marionette)
  156. (srfi srfi-1)
  157. (srfi srfi-26)
  158. (srfi srfi-64)
  159. (parted))
  160. (define (image->disk img)
  161. (disk-new (get-device img)))
  162. (test-runner-current (system-test-runner #$output))
  163. (test-begin "images")
  164. ;; Image i1.
  165. (define i1-image
  166. #$(system-image i1))
  167. (define d1-device
  168. (get-device i1-image))
  169. (test-equal "msdos"
  170. (disk-type-name (disk-probe d1-device)))
  171. (test-equal 1
  172. (disk-get-primary-partition-count (disk-new d1-device)))
  173. (test-assert
  174. (let* ((disk (disk-new d1-device))
  175. (partitions (disk-partitions disk))
  176. (boot-partition (find normal-partition? partitions)))
  177. (partition-get-flag boot-partition PARTITION-FLAG-BOOT)))
  178. ;; Image i2.
  179. (define i2-image
  180. #$(system-image i2))
  181. (define d2-device
  182. (get-device i2-image))
  183. (test-equal "gpt"
  184. (disk-type-name (disk-probe d2-device)))
  185. (test-equal 1
  186. (disk-get-primary-partition-count (disk-new d2-device)))
  187. (test-equal "test"
  188. (let* ((disk (disk-new d2-device))
  189. (partitions (disk-partitions disk))
  190. (boot-partition (find normal-partition? partitions)))
  191. (partition-get-name boot-partition)))
  192. ;; Image i3.
  193. (define i3-image
  194. #$(system-image i3))
  195. (define d3-device
  196. (get-device i3-image))
  197. (test-equal "msdos"
  198. (disk-type-name (disk-probe d3-device)))
  199. (test-equal 2
  200. (disk-get-primary-partition-count (disk-new d3-device)))
  201. ;; Image i4.
  202. (define i4-image
  203. #$(system-image i4))
  204. (define d4-device
  205. (get-device i4-image))
  206. (test-equal "gpt"
  207. (disk-type-name (disk-probe d4-device)))
  208. (test-equal 2
  209. (disk-get-primary-partition-count (disk-new d4-device)))
  210. ;; Image i5.
  211. (define i5-image
  212. #$(system-image i5))
  213. (define d5-device
  214. (get-device i5-image))
  215. (define (sector->byte sector)
  216. (/ (* sector (device-sector-size d5-device))
  217. MEBIBYTE-SIZE))
  218. (test-equal "gpt"
  219. (disk-type-name (disk-probe d5-device)))
  220. (test-equal 2
  221. (disk-get-primary-partition-count (disk-new d5-device)))
  222. (test-equal '("fat32" "ext4")
  223. (map (compose filesystem-type-name partition-fs-type)
  224. (filter data-partition?
  225. (disk-partitions (disk-new d5-device)))))
  226. ;; The first partition has a 1MiB offset has a 128MiB size. The
  227. ;; second partition should then start at 129MiB.
  228. (test-equal '(1 129)
  229. (map (compose sector->byte partition-start)
  230. (filter data-partition?
  231. (disk-partitions (disk-new d5-device)))))
  232. ;; Image i6.
  233. (define i6-image
  234. #$(system-image i6))
  235. (define d6-device
  236. (get-device i6-image))
  237. (test-equal "gpt"
  238. (disk-type-name (disk-probe d6-device)))
  239. (test-end)))))
  240. (gexp->derivation "images-test" test))
  241. (define %test-images
  242. (system-test
  243. (name "images")
  244. (description "Build and test basic system images.")
  245. (value (run-images-test))))