aboutsummaryrefslogtreecommitdiff
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2020, 2022 Mathieu Othacehe <othacehe@gnu.org>
;;; Copyright © 2023 Oleg Pykhalov <go.wigust@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu image)
  #:use-module (guix platform)
  #:use-module (guix records)
  #:use-module (guix diagnostics)
  #:use-module (guix i18n)
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-34)
  #:use-module (srfi srfi-35)
  #:export (partition
            partition?
            partition-device
            partition-size
            partition-offset
            partition-file-system
            partition-file-system-options
            partition-label
            partition-uuid
            partition-flags
            partition-initializer

            image
            image?
            image-name
            image-format
            image-platform
            image-size
            image-max-layers
            image-operating-system
            image-partition-table-type
            image-partitions
            image-compression?
            image-volatile-root?
            image-shared-store?
            image-shared-network?
            image-substitutable?

            image-type
            image-type?
            image-type-name
            image-type-constructor

            os->image
            os+platform->image))


;;;
;;; Sanitizers.
;;;

;; Image and partition sizes can be either be a size in bytes or the 'guess
;; symbol denoting that the size should be estimated by Guix, according to the
;; image content.
(define-with-syntax-properties (validate-size (value properties))
  (unless (and value
               (or (eq? value 'guess) (integer? value)))
    (raise
       (make-compound-condition
        (condition
         (&error-location
          (location (source-properties->location properties))))
        (formatted-message
         (G_ "size (~a) can only be 'guess or a numeric expression ~%")
         value 'field))))
  value)


;;;
;;; Partition record.
;;;

;; The partition offset should be a bytes count as an integer.
(define-with-syntax-properties (validate-partition-offset (value properties))
  (unless (and value (integer? value))
    (raise
       (make-compound-condition
        (condition
         (&error-location
          (location (source-properties->location properties))))
        (formatted-message
         (G_ "the partition offset (~a) can only be a \
numeric expression ~%") value 'field))))
  value)

;; The supported partition flags.
(define-with-syntax-properties (validate-partition-flags (value properties))
  (let ((bad-flags (lset-difference eq? value '(boot esp))))
    (unless (and (list? value) (null? bad-flags))
      (raise
       (make-compound-condition
        (condition
         (&error-location
          (location (source-properties->location properties))))
        (formatted-message
         (G_ "unsupported partition flag(s): ~a ~%") bad-flags)))))
  value)

(define-record-type* <partition> partition make-partition
  partition?
  (size                 partition-size   ;size in bytes as integer or 'guess
                        (default 'guess)
                        (sanitize validate-size))
  (offset               partition-offset
                        (default 0)   ;offset in bytes as integer
                        (sanitize validate-partition-offset))
  (file-system          partition-file-system
                        (default "ext4"))  ;string
  (file-system-options  partition-file-system-options
                        (default '()))  ;list of strings
  (label                partition-label)  ;string
  (uuid                 partition-uuid
                        (default #false))  ;<uuid>
  (flags                partition-flags
                        (default '())  ;list of symbols
                        (sanitize validate-partition-flags))
  (initializer          partition-initializer
                        (default #false))) ;gexp | #false


;;;
;;; Image record.
;;;

(define-syntax-rule (define-set-sanitizer name field set)
  "Define NAME as a procedure or macro that raises an error if passed a value
that is not in SET, mentioning FIELD in the error message."
  (define-with-syntax-properties (name (value properties))
    (unless (memq value 'set)
      (raise
       (make-compound-condition
        (condition
         (&error-location
          (location (source-properties->location properties))))
        (formatted-message (G_ "~s: invalid '~a' value") value 'field))))
    value))

;; The supported image formats.
(define-set-sanitizer validate-image-format format
  (disk-image compressed-qcow2 docker iso9660 tarball wsl2))

;; The supported partition table types.
(define-set-sanitizer validate-partition-table-type partition-table-type
  (mbr gpt))

(define-record-type* <image>
  image make-image
  image?
  (name               image-name ;symbol
                      (default #false))
  (format             image-format                ;symbol
                      (sanitize validate-image-format))
  (platform           image-platform ;<platform>
                      (default #false))
  (size               image-size  ;size in bytes as integer
                      (default 'guess)
                      (sanitize validate-size))
  (max-layers         image-max-layers  ;number of layers as integer
                      (default #false))
  (operating-system   image-operating-system)  ;<operating-system>
  (partition-table-type image-partition-table-type ; 'mbr or 'gpt
                      (default 'mbr)
                      (sanitize validate-partition-table-type))
  (partitions         image-partitions ;list of <partition>
                      (default '()))
  (compression?       image-compression? ;boolean
                      (default #true))
  (volatile-root?     image-volatile-root? ;boolean
                      (default #true))
  (shared-store?      image-shared-store? ;boolean
                      (default #false))
  (shared-network?    image-shared-network? ;boolean
                      (default #false))
  (substitutable?     image-substitutable? ;boolean
                      (default #true)))


;;;
;;; Image type.
;;;

;; The role of this record is to provide a constructor that is able to turn an
;; <operating-system> record into an <image> record.  Some basic <image-type>
;; records are defined in the (gnu system image) module.  They are able to
;; turn an <operating-system> record into an EFI or an ISO 9660 bootable
;; image, a Docker image or even a QCOW2 image.
;;
;; Other <image-type> records are defined in the (gnu system images ...)
;; modules.  They are dedicated to specific machines such as Novena and Pine64
;; SoC boards that require specific images.
;;
;; All the available <image-type> records are collected by the 'image-modules'
;; procedure.  This allows the "guix system image" command to turn a given
;; <operating-system> record into an image, thanks to the specified
;; <image-type>.  In that case, the <image-type> look up is done using the
;; name field of the <image-type> record.

(define-record-type* <image-type>
  image-type make-image-type
  image-type?
  (name           image-type-name) ;symbol
  (constructor    image-type-constructor)) ;<operating-system> -> <image>


;;;
;;; Image creation.
;;;

(define* (os->image os #:key type)
  "Use the image constructor from TYPE, an <image-type> record to turn the
given OS, an <operating-system> record into an image and return it."
  (let ((constructor (image-type-constructor type)))
    (constructor os)))

(define* (os+platform->image os platform #:key type)
  "Use the image constructor from TYPE, an <image-type> record to turn the
given OS, an <operating-system> record into an image targeting PLATFORM, a
<platform> record and return it."
  (image
   (inherit (os->image os #:type type))
   (platform platform)))
er-program)[init-gettext]: Change locale from C, installed at the program start. Miguel Ángel Arruga Vivas 2020-09-23installer: Fix docstring typo....* gnu/installer.scm (build-compiled-file): Fix a typo in the docstring. Tobias Geerinckx-Rice 2020-08-25Remove "guile-zlib" extension when unused....This is a follow-up of 755f365b02b42a5d1e8ef3000dadef069553a478. As (zlib) is autoloaded in (gnu build linux-modules), "guile-zlib" is needed as an extension only when it is effectively used. * gnu/installer.scm (installer-program): Remove "guile-zlib" from the extensions. * gnu/machine/ssh.scm (machine-check-initrd-modules): Ditto. * gnu/services.scm (activation-script): Ditto. * gnu/services/base.scm (default-serial-port): Ditto, (agetty-shepherd-service): ditto, (udev-service-type): ditto. * gnu/system/image.scm (gcrypt-sqlite3&co): Ditto. * gnu/system/shadow.scm (account-shepherd-service): Ditto. Mathieu Othacehe 2020-08-25linux-libre: Support module compression....This commit adds support for GZIP compression for linux-libre kernel modules. The initrd modules are kept uncompressed as the initrd is already compressed as a whole. The linux-libre kernel also supports XZ compression, but as Guix does not have any available bindings for now, and the compression time is far more significant, GZIP seems to be a better option. * gnu/build/linux-modules.scm (modinfo-section-contents): Use 'call-with-gzip-input-port' to read from a module file using '.gz' extension, (strip-extension): new procedure, (dot-ko): adapt to support compression, (ensure-dot-ko): ditto, (file-name->module-name): ditto, (find-module-file): ditto, (load-linux-module*): ditto, (module-name->file-name/guess): ditto, (module-name-lookup): ditto, (write-module-name-database): ditto, (write-module-alias-database): ditto, (write-module-device-database): ditto. * gnu/installer.scm (installer-program): Add "guile-zlib" to the extensions. * gnu/machine/ssh.scm (machine-check-initrd-modules): Ditto. * gnu/services.scm (activation-script): Ditto. * gnu/services/base.scm (default-serial-port): Ditto, (agetty-shepherd-service): ditto, (udev-service-type): ditto. * gnu/system/image.scm (gcrypt-sqlite3&co): Ditto. * gnu/system/linux-initrd.scm (flat-linux-module-directory): Add "guile-zlib" to the extensions and make sure that the initrd only contains uncompressed module files. * gnu/system/shadow.scm (account-shepherd-service): Add "guile-zlib" to the extensions. * guix/profiles.scm (linux-module-database): Ditto. Mathieu Othacehe 2020-08-06installer: Remove logical devices....If a device contains an active logical volume, BLKRRPART will report that the device is busy. This will cause this device to be filtered by "non-install-devices" procedure, which is not desired. Make sure to deactivate all logical volumes before device probing. Fixes <https://issues.guix.gnu.org/42683>. * gnu/installer.scm (installer-program): Add lvm2-static to the inputs. * gnu/installer/parted.scm (remove-logical-devices): New procedure, (init-parted): call it. Mathieu Othacehe 2020-07-26installer: Add NTFS support....This adds support for creating and editing NTFS partitions. It is however not possible yet to create root NTFS partitions, as overlaying on top of a fuse partition does not seem supported. * gnu/installer.scm (installer-program): Add "ntfs-3g" to the inputs. * gnu/installer/parted.scm (user-fs-type-name, user-fs-type->mount-type, partition-filesystem-user-type, create-ntfs-file-system, format-user-partitions): Add NTFS support. * gnu/installer/newt/partition.scm (run-fs-type-page): Add NTFS support. Mathieu Othacehe 2020-06-26installer: Use latest Guile....Since the installer is loading Guix modules built with Guile 3.0.4, the installer script must be run by the same Guile version to avoid a bytecode incompatibility. This is a follow-up of a2991de0f44a5f4db71ddad67e914fe3344a4505. * gnu/installer.scm (installer-program): Use guile3.0-latest for the installation script. Mathieu Othacehe 2020-04-19Merge branch 'master' into core-updatesMarius Bakke 2020-04-18installer: Fix backtrace display....The 'syslog' macro cannot be resolved in the pre-unwind-handler context. Failed to resolve 'syslog' in this context resulted in the swallowing of all installation errors. Fixes 5c04b00cf463a543b8ffc9eb55991f6b4cc145dd. * gnu/installer.scm (installer-program): Use (gnu installer utils) module. Mathieu Othacehe 2020-04-16installer: Remove guile-newt definition....This is no longer necessary since 0.0.2 release of Guile-Newt. * gnu/installer.scm (guile-newt): Remove variable. Mathieu Othacehe 2020-04-15Merge branch 'master' into core-updatesMarius Bakke 2020-04-14installer: Open manual in the selected language on tty2....Fixes <https://bugs.gnu.org/40624>. Reported by Florian Pelz <pelzflorian@pelzflorian.de>. Regression introduced in b5c2d93d7a223155898dd0ed6932f6acf78ac454. * gnu/installer.scm (apply-locale): Remove 'lambda' around 'stop-service' and 'start-service' calls. Ludovic Courtès 2020-04-11Merge branch 'master' into core-updatesMarius Bakke 2020-04-09installer: Allow Alt+Shift toggle from non-Latin keyboard layouts....Fixes <https://bugs.gnu.org/40493>. * gnu/installer/newt/keymap.scm (%non-latin-layouts): New variable. (%non-latin-variants): New variable. (%latin-layout+variants): New variable. (toggleable-latin-layout): New procedure to compute combined layouts. (run-keymap-page): Use it. (keyboard-layout->configuration): Apply it in config.scm. (run-layout-page): Mention Alt+Shift. * gnu/installer/keymap.scm (kmscon-update-keymap): Pass on XKB options. * gnu/installer/record.scm (<installer>): Adjust code comments. * gnu/installer.scm (apply-keymap): Pass on XKB options. (installer-steps): Adjust code comments. * gnu/packages/patches/kmscon-runtime-keymap-switch.patch: Apply XKB options. Florian Pelz 2020-04-08Merge branch 'master' into core-updates... Conflicts: etc/news.scm gnu/local.mk gnu/packages/check.scm gnu/packages/cross-base.scm gnu/packages/gimp.scm gnu/packages/java.scm gnu/packages/mail.scm gnu/packages/sdl.scm gnu/packages/texinfo.scm gnu/packages/tls.scm gnu/packages/version-control.scm Marius Bakke 2020-04-08installer: Turn help menu into parameters menu....* gnu/local.mk (INSTALLER_MODULES): Rename help.scm into parameters.scm. * po/guix/POTFILES.in: Ditto. * gnu/installer/record.scm (<installer>): Rename help-menu into parameter-menu and help-page into parameters-page. * gnu/installer/newt/parameters.scm: Renamed from help.scm. Update information messages. * gnu/installer/newt.scm: Update accordingly. * gnu/installer/newt/keymap.scm: Ditto. Mathieu Othacehe 2020-04-06installer: Hide shepherd messages....* gnu/installer.scm (apply-locale): Set "shepherd-message-port" instead of redirecting stderr to make sure that nothing is printed on console. Mathieu Othacehe 2020-04-06installer: Add a help page....* gnu/installer/newt/help.scm: New file. * gnu/local.mk (INSTALLER_MODULES): Add it. * po/guix/POTFILES.in: Add it. * gnu/installer/record.scm (<installer>): Add 'help-menu' and 'help-page' fields, (installer-help-menu, installer-help-page): new exported procedures. * gnu/installer/newt.scm (init): Set the help line, (help-menu, help-page): new procedures used ... (newt-installer): ... here. * gnu/installer/newt/keymap.scm (run-layout-page): Add a context argument to differenciate the help context from the main one, (run-keymap-page): add a context argument and pass it to run-layout-page. * gnu/installer.scm (compute-keymap-step): Add a context argument and pass it to 'installer-keymap-page', (installer-steps): set the help menu and pass the appropriate context to compute-keymap-step calls, (guile-newt): update to revision 2. Mathieu Othacehe 2020-04-06installer: Remove trailing tabs....* gnu/installer.scm (installer-steps): Remove trailing tabs. Mathieu Othacehe 2020-03-27Merge branch 'master' into core-updates... Conflicts: gnu/packages/icu4c.scm gnu/packages/man.scm gnu/packages/python-xyz.scm guix/scripts/environment.scm guix/scripts/pack.scm guix/scripts/package.scm guix/scripts/pull.scm guix/store.scm Marius Bakke 2020-03-22installer: Do not include the host (guix config)....Previously, "locales.drv" would depend on the host's (guix config). Thus, the derivation would depend on details of the user's installation. * gnu/installer.scm (not-config?): New procedure. (build-compiled-file): Pass it to 'source-module-closure' and use 'make-config.scm'. Ludovic Courtès