image.scm 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2020, 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 image)
  19. #:use-module (guix platform)
  20. #:use-module (guix records)
  21. #:use-module (guix diagnostics)
  22. #:use-module (guix i18n)
  23. #:use-module (srfi srfi-1)
  24. #:use-module (srfi srfi-34)
  25. #:use-module (srfi srfi-35)
  26. #:export (partition
  27. partition?
  28. partition-device
  29. partition-size
  30. partition-offset
  31. partition-file-system
  32. partition-file-system-options
  33. partition-label
  34. partition-uuid
  35. partition-flags
  36. partition-initializer
  37. image
  38. image?
  39. image-name
  40. image-format
  41. image-platform
  42. image-size
  43. image-operating-system
  44. image-partition-table-type
  45. image-partitions
  46. image-compression?
  47. image-volatile-root?
  48. image-shared-store?
  49. image-shared-network?
  50. image-substitutable?
  51. image-type
  52. image-type?
  53. image-type-name
  54. image-type-constructor
  55. os->image
  56. os+platform->image))
  57. ;;;
  58. ;;; Sanitizers.
  59. ;;;
  60. ;; Image and partition sizes can be either be a size in bytes or the 'guess
  61. ;; symbol denoting that the size should be estimated by Guix, according to the
  62. ;; image content.
  63. (define-with-syntax-properties (validate-size (value properties))
  64. (unless (and value
  65. (or (eq? value 'guess) (integer? value)))
  66. (raise
  67. (make-compound-condition
  68. (condition
  69. (&error-location
  70. (location (source-properties->location properties))))
  71. (formatted-message
  72. (G_ "size (~a) can only be 'guess or a numeric expression ~%")
  73. value 'field))))
  74. value)
  75. ;;;
  76. ;;; Partition record.
  77. ;;;
  78. ;; The partition offset should be a bytes count as an integer.
  79. (define-with-syntax-properties (validate-partition-offset (value properties))
  80. (unless (and value (integer? value))
  81. (raise
  82. (make-compound-condition
  83. (condition
  84. (&error-location
  85. (location (source-properties->location properties))))
  86. (formatted-message
  87. (G_ "the partition offset (~a) can only be a \
  88. numeric expression ~%") value 'field))))
  89. value)
  90. ;; The supported partition flags.
  91. (define-with-syntax-properties (validate-partition-flags (value properties))
  92. (let ((bad-flags (lset-difference eq? value '(boot esp))))
  93. (unless (and (list? value) (null? bad-flags))
  94. (raise
  95. (make-compound-condition
  96. (condition
  97. (&error-location
  98. (location (source-properties->location properties))))
  99. (formatted-message
  100. (G_ "unsupported partition flag(s): ~a ~%") bad-flags)))))
  101. value)
  102. (define-record-type* <partition> partition make-partition
  103. partition?
  104. (size partition-size ;size in bytes as integer or 'guess
  105. (default 'guess)
  106. (sanitize validate-size))
  107. (offset partition-offset
  108. (default 0) ;offset in bytes as integer
  109. (sanitize validate-partition-offset))
  110. (file-system partition-file-system
  111. (default "ext4")) ;string
  112. (file-system-options partition-file-system-options
  113. (default '())) ;list of strings
  114. (label partition-label) ;string
  115. (uuid partition-uuid
  116. (default #false)) ;<uuid>
  117. (flags partition-flags
  118. (default '()) ;list of symbols
  119. (sanitize validate-partition-flags))
  120. (initializer partition-initializer
  121. (default #false))) ;gexp | #false
  122. ;;;
  123. ;;; Image record.
  124. ;;;
  125. (define-syntax-rule (define-set-sanitizer name field set)
  126. "Define NAME as a procedure or macro that raises an error if passed a value
  127. that is not in SET, mentioning FIELD in the error message."
  128. (define-with-syntax-properties (name (value properties))
  129. (unless (memq value 'set)
  130. (raise
  131. (make-compound-condition
  132. (condition
  133. (&error-location
  134. (location (source-properties->location properties))))
  135. (formatted-message (G_ "~s: invalid '~a' value") value 'field))))
  136. value))
  137. ;; The supported image formats.
  138. (define-set-sanitizer validate-image-format format
  139. (disk-image compressed-qcow2 docker iso9660 tarball wsl2))
  140. ;; The supported partition table types.
  141. (define-set-sanitizer validate-partition-table-type partition-table-type
  142. (mbr gpt))
  143. (define-record-type* <image>
  144. image make-image
  145. image?
  146. (name image-name ;symbol
  147. (default #false))
  148. (format image-format ;symbol
  149. (sanitize validate-image-format))
  150. (platform image-platform ;<platform>
  151. (default #false))
  152. (size image-size ;size in bytes as integer
  153. (default 'guess)
  154. (sanitize validate-size))
  155. (operating-system image-operating-system) ;<operating-system>
  156. (partition-table-type image-partition-table-type ; 'mbr or 'gpt
  157. (default 'mbr)
  158. (sanitize validate-partition-table-type))
  159. (partitions image-partitions ;list of <partition>
  160. (default '()))
  161. (compression? image-compression? ;boolean
  162. (default #true))
  163. (volatile-root? image-volatile-root? ;boolean
  164. (default #true))
  165. (shared-store? image-shared-store? ;boolean
  166. (default #false))
  167. (shared-network? image-shared-network? ;boolean
  168. (default #false))
  169. (substitutable? image-substitutable? ;boolean
  170. (default #true)))
  171. ;;;
  172. ;;; Image type.
  173. ;;;
  174. ;; The role of this record is to provide a constructor that is able to turn an
  175. ;; <operating-system> record into an <image> record. Some basic <image-type>
  176. ;; records are defined in the (gnu system image) module. They are able to
  177. ;; turn an <operating-system> record into an EFI or an ISO 9660 bootable
  178. ;; image, a Docker image or even a QCOW2 image.
  179. ;;
  180. ;; Other <image-type> records are defined in the (gnu system images ...)
  181. ;; modules. They are dedicated to specific machines such as Novena and Pine64
  182. ;; SoC boards that require specific images.
  183. ;;
  184. ;; All the available <image-type> records are collected by the 'image-modules'
  185. ;; procedure. This allows the "guix system image" command to turn a given
  186. ;; <operating-system> record into an image, thanks to the specified
  187. ;; <image-type>. In that case, the <image-type> look up is done using the
  188. ;; name field of the <image-type> record.
  189. (define-record-type* <image-type>
  190. image-type make-image-type
  191. image-type?
  192. (name image-type-name) ;symbol
  193. (constructor image-type-constructor)) ;<operating-system> -> <image>
  194. ;;;
  195. ;;; Image creation.
  196. ;;;
  197. (define* (os->image os #:key type)
  198. "Use the image constructor from TYPE, an <image-type> record to turn the
  199. given OS, an <operating-system> record into an image and return it."
  200. (let ((constructor (image-type-constructor type)))
  201. (constructor os)))
  202. (define* (os+platform->image os platform #:key type)
  203. "Use the image constructor from TYPE, an <image-type> record to turn the
  204. given OS, an <operating-system> record into an image targeting PLATFORM, a
  205. <platform> record and return it."
  206. (image
  207. (inherit (os->image os #:type type))
  208. (platform platform)))