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)))
ltip'>* gnu/services/samba.scm: New file. * gnu/tests/samba.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Add them. * po/guix/POTFILES.in Add 'gnu/services/samba.scm'. * doc/guix.texi: Document it. Signed-off-by: Lars-Dominik Braun <lars@6xq.net> Simon Streit 2022-09-04nls: Update translations.Julien Lepiller 2022-08-11po: Add 'guix/read-print.scm'....This is a followup to b21d05d232ec0aba5abec20e83cc52c1d5163cc3. * po/guix/POTFILES.in: Add 'guix/read-print.scm'. Ludovic Courtès 2022-08-10nls: Update translations....po/guix/bn.po: New file. po/guix/LINGUAS: Add it. Julien Lepiller 2022-07-09nls: Update translations....po/guix/tr.po: New file. po/guix/LINGUAS: Add it. Julien Lepiller 2022-06-24services: configuration: Report the location of field type errors....Previously field type errors would be reported in a non-standard way, and without any source location information. This fixes it. * gnu/services/configuration.scm (configuration-field-error): Add a 'loc' parameter and honor it. Use 'formatted-message' instead of plain 'format'. (define-configuration-helper)[field-sanitizer]: New procedure. Use it. Use STEM as the identifier of the syntactic constructor of the record type. Add a 'sanitize' property to each field. Remove now useless STEM macro that would call 'validate-configuration'. * gnu/services/mail.scm (serialize-listener-configuration): Adjust to new 'configuration-field-error' prototype. * tests/services/configuration.scm ("wrong type for a field"): New test. * po/guix/POTFILES.in: Add gnu/services/configuration.scm. Ludovic Courtès 2022-06-17home: Add OpenSSH service....* gnu/home/services/ssh.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Add it. * po/guix/POTFILES.in: Add it. * doc/guix.texi (Secure Shell): New section. Ludovic Courtès 2022-06-04nls: Update translations....po/packages/tr.po: New file. po/packages/LINGUAS: Add it. Julien Lepiller 2022-06-04guix home: Add 'edit' sub-command....* guix/scripts/home/edit.scm: New file. * Makefile.am (MODULES): Add it. * guix/scripts/home.scm (show-help): Add "edit". (process-command): Handle it. (guix-home): Add it. * po/guix/POTFILES.in: Add 'guix/scripts/home/edit.scm'. * doc/guix.texi (Invoking guix home): Document it. Ludovic Courtès 2022-06-04guix system: Add 'edit' sub-command....* guix/scripts/system/edit.scm: New file. * Makefile.am (MODULES): Add it. * guix/scripts/system.scm (show-help): Mention "edit". (actions): Add it. (process-command): Handle it. * doc/guix.texi (Invoking guix system): Document it. * po/guix/POTFILES.in: Add guix/scripts/system/edit.scm. Ludovic Courtès 2022-05-01nls: Update translations....po/guix/ja.po: New file. po/guix/LINGUAS: Add it. Julien Lepiller 2022-04-02nls: Update translations....* po/packages/fi.po: New file. * po/packages/LINGUAS: Add it. Julien Lepiller 2022-03-18graph: Factorize 'lookup-backend'....* guix/graph.scm (lookup-backend): New procedure. * guix/scripts/graph.scm (lookup-backend): Remove. * guix/scripts/system.scm (lookup-backend): Remove. * po/guix/POTFILES.in: Add 'guix/graph.scm'. Ludovic Courtès 2022-03-01nls: Update translations....* po/doc/guix-cookbook.uk.po: New file. * po/doc/local.mk: Add uk cookbook. * doc/local.mk: Add uk cookbook. * po/guix/fa.po: New file. * po/guix/uk.po: New file. * po/guix/LINGUAS: Add fa and uk. Julien Lepiller 2022-02-04nls: Update translations....* po/doc/guix-cookbook.pt_BR.po: New file. * po/doc/local.mk: Add it. * doc/local.mk: Add pt_BR cookbook. Julien Lepiller 2022-01-09nls: Update translations....* po/doc/guix-cookbook.fi.po: New file. * po/doc/guix-manual.fi.po: New file. * po/doc/local.mk: Add them. * doc/local.mk: Add them. * po/guix/fi.po: New file. * po/guix/LINGUAS: Add it. Julien Lepiller 2022-01-03home: services: Make strings in Gexps translateble....* gnu/home/services.scm (%initialize-gettext): New variable. (compute-on-first-login-script): Use it. (compute-on-change-gexp): Likewise. * gnu/home/services/symlink-manager.scm (update-symlinks-script): Likewise. * po/guix/POTFILES.in: Add gnu/home-services.scm and gnu/home/services/symlink-manager.scm. Suggested-by: Ludovic Courtès <ludo@gnu.org> Link: <https://yhetil.org/guix-bugs/87sfvy8k1u.fsf@gnu.org> Signed-off-by: Ludovic Courtès <ludo@gnu.org> Xinglu Chen 2021-12-10Merge remote-tracking branch 'signed/master' into core-updatesMathieu Othacehe 2021-12-08nls: Update 'es' translation.Julien Lepiller 2021-12-05Merge remote-tracking branch 'origin/master' into core-updates-frozenRicardo Wurmus 2021-12-04nls: Update translations.Julien Lepiller 2021-11-08Merge remote-tracking branch 'origin/master' into core-updates-frozenEfraim Flashner 2021-11-06nls: Update translations....* po/doc/guix-cookbook.es.po: New file. * po/doc/local.mk: Add 'es' cookbook. * doc/local.mk: Add 'es' cookbook. Julien Lepiller 2021-10-31Merge remote-tracking branch 'origin/master' into core-updates-frozenEfraim Flashner 2021-10-25Add 'guix shell'....* guix/scripts/shell.scm, tests/guix-shell.sh: New files. * Makefile.am (MODULES): Add 'shell.scm'. (SH_TESTS): Add 'tests/guix-shell.sh'. * guix/scripts/environment.scm (show-environment-options-help): New procedure. (show-help): Use it. (guix-environment*): New procedure. (guix-environment): Use it. * po/guix/POTFILES.in: Add it. * doc/guix.texi (Features): Refer to "guix shell" (Invoking guix package): Likewise. (Development): Likewise. (Invoking guix shell): New node. (Invoking guix environment): Add deprecation warning. (Debugging Build Failures): Use 'guix shell' in examples. (Invoking guix container): Refer to 'guix shell'. (Invoking guix processes, Virtualization Services): Adjust examples to use 'guix shell'. * doc/contributing.texi (Building from Git): Refer to 'guix shell'. * etc/completion/bash/guix: Handle "shell". Ludovic Courtès 2021-10-18Merge remote-tracking branch 'signed/master' into core-updatesMathieu Othacehe 2021-10-17nls: Update translations.Julien Lepiller 2021-10-12Merge remote-tracking branch 'origin/master' into core-updates-frozen.Mathieu Othacehe