aboutsummaryrefslogtreecommitdiff
path: root/gnu/system
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/system')
-rw-r--r--gnu/system/hurd.scm225
-rw-r--r--gnu/system/image.scm532
-rw-r--r--gnu/system/install.scm14
-rw-r--r--gnu/system/linux-initrd.scm8
-rw-r--r--gnu/system/locale.scm9
-rw-r--r--gnu/system/pam.scm10
-rw-r--r--gnu/system/shadow.scm5
-rw-r--r--gnu/system/vm.scm260
8 files changed, 844 insertions, 219 deletions
diff --git a/gnu/system/hurd.scm b/gnu/system/hurd.scm
new file mode 100644
index 0000000000..58bfdf88f6
--- /dev/null
+++ b/gnu/system/hurd.scm
@@ -0,0 +1,225 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2020 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+;;;
+;;; 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 system hurd)
+ #:use-module (guix gexp)
+ #:use-module (guix profiles)
+ #:use-module (guix utils)
+ #:use-module (gnu bootloader grub)
+ #:use-module (gnu packages admin)
+ #:use-module (gnu packages base)
+ #:use-module (gnu packages bash)
+ #:use-module (gnu packages cross-base)
+ #:use-module (gnu packages file)
+ #:use-module (gnu packages guile)
+ #:use-module (gnu packages guile-xyz)
+ #:use-module (gnu packages hurd)
+ #:use-module (gnu packages less)
+ #:use-module (gnu system vm)
+ #:export (cross-hurd-image))
+
+;;; Commentary:
+;;;
+;;; This module provides tools to (cross-)build GNU/Hurd virtual machine
+;;; images.
+;;;
+;;; Code:
+
+;; XXX: Surely this belongs in (guix profiles), but perhaps we need high-level
+;; <profile> objects so one can specify hooks, etc.?
+(define-gexp-compiler (compile-manifest (manifest
+ (@@ (guix profiles) <manifest>))
+ system target)
+ "Lower MANIFEST as a profile."
+ (profile-derivation manifest
+ #:system system
+ #:target target))
+
+(define %base-packages/hurd
+ (list hurd bash coreutils file findutils grep sed
+ guile-3.0 guile-colorized guile-readline
+ net-base inetutils less which))
+
+(define* (cross-hurd-image #:key (hurd hurd) (gnumach gnumach))
+ "Return a cross-built GNU/Hurd image."
+
+ (define (cross-built thing)
+ (with-parameters ((%current-target-system "i586-pc-gnu"))
+ thing))
+
+ (define (cross-built-entry entry)
+ (manifest-entry
+ (inherit entry)
+ (item (cross-built (manifest-entry-item entry)))
+ (dependencies (map cross-built-entry
+ (manifest-entry-dependencies entry)))))
+
+ (define system-profile
+ (map-manifest-entries cross-built-entry
+ (packages->manifest %base-packages/hurd)))
+
+ (define grub.cfg
+ (let ((hurd (cross-built hurd))
+ (mach (with-parameters ((%current-system "i686-linux"))
+ gnumach))
+ (libc (cross-libc "i586-pc-gnu")))
+ (computed-file "grub.cfg"
+ #~(call-with-output-file #$output
+ (lambda (port)
+ (format port "
+set timeout=2
+search.file ~a/boot/gnumach
+
+menuentry \"GNU\" {
+ multiboot ~a/boot/gnumach root=device:hd0s1
+ module ~a/hurd/ext2fs.static ext2fs \\
+ --multiboot-command-line='${kernel-command-line}' \\
+ --host-priv-port='${host-port}' \\
+ --device-master-port='${device-port}' \\
+ --exec-server-task='${exec-task}' -T typed '${root}' \\
+ '$(task-create)' '$(task-resume)'
+ module ~a/lib/ld.so.1 exec ~a/hurd/exec '$(exec-task=task-create)'
+}\n"
+ #+mach #+mach #+hurd
+ #+libc #+hurd))))))
+
+ (define fstab
+ (plain-file "fstab"
+ "# This file was generated from your Guix configuration. Any changes
+# will be lost upon reboot or reconfiguration.
+
+/dev/hd0s1 / ext2 defaults
+"))
+
+ (define passwd
+ (plain-file "passwd"
+ "root:x:0:0:root:/root:/bin/sh
+guixbuilder:x:1:1:guixbuilder:/var/empty:/bin/no-sh
+"))
+
+ (define group
+ (plain-file "group"
+ "guixbuild:x:1:guixbuilder
+"))
+
+ (define shadow
+ (plain-file "shadow"
+ "root::0:0:0:0:::
+"))
+
+ (define etc-profile
+ (plain-file "profile"
+ "\
+export PS1='\\u@\\h\\$ '
+
+GUIX_PROFILE=\"/run/current-system/profile\"
+. \"$GUIX_PROFILE/etc/profile\"
+
+GUIX_PROFILE=\"$HOME/.guix-profile\"
+if [ -f \"$GUIX_PROFILE/etc/profile\" ]; then
+ . \"$GUIX_PROFILE/etc/profile\"
+fi\n"))
+
+ (define hurd-directives
+ `((directory "/servers")
+ ,@(map (lambda (server)
+ `(file ,(string-append "/servers/" server)))
+ '("startup" "exec" "proc" "password"
+ "default-pager" "crash-dump-core"
+ "kill" "suspend"))
+ ("/servers/crash" -> "crash-dump-core")
+ (directory "/servers/socket")
+ (file "/servers/socket/1")
+ (file "/servers/socket/2")
+ (file "/servers/socket/16")
+ ("/servers/socket/local" -> "1")
+ ("/servers/socket/inet" -> "2")
+ ("/servers/socket/inet6" -> "16")
+ (directory "/boot")
+ ("/boot/grub.cfg" -> ,grub.cfg) ;XXX: not strictly needed
+ ("/hurd" -> ,(file-append (with-parameters ((%current-target-system
+ "i586-pc-gnu"))
+ hurd)
+ "/hurd"))
+
+ ;; TODO: Create those during activation, eventually.
+ (directory "/root")
+ (file "/root/.guile"
+ ,(object->string
+ '(begin
+ (use-modules (ice-9 readline) (ice-9 colorized))
+ (activate-readline) (activate-colorized))))
+ (directory "/run")
+ (directory "/run/current-system")
+ ("/run/current-system/profile" -> ,system-profile)
+ ("/etc/profile" -> ,etc-profile)
+ ("/etc/fstab" -> ,fstab)
+ ("/etc/group" -> ,group)
+ ("/etc/passwd" -> ,passwd)
+ ("/etc/shadow" -> ,shadow)
+ (file "/etc/hostname" "guixygnu")
+ (file "/etc/resolv.conf"
+ "nameserver 10.0.2.3\n")
+ ("/etc/services" -> ,(file-append (with-parameters ((%current-target-system
+ "i586-pc-gnu"))
+ net-base)
+ "/etc/services"))
+ ("/etc/protocols" -> ,(file-append (with-parameters ((%current-target-system
+ "i586-pc-gnu"))
+ net-base)
+ "/etc/protocols"))
+ ("/etc/motd" -> ,(file-append (with-parameters ((%current-target-system
+ "i586-pc-gnu"))
+ hurd)
+ "/etc/motd"))
+ ("/etc/login" -> ,(file-append (with-parameters ((%current-target-system
+ "i586-pc-gnu"))
+ hurd)
+ "/etc/login"))
+
+
+ ;; XXX can we instead, harmlessly set _PATH_TTYS (from glibc) in runttys.c?
+ ("/etc/ttys" -> ,(file-append (with-parameters ((%current-target-system
+ "i586-pc-gnu"))
+ hurd)
+ "/etc/ttys"))
+ ("/bin/sh" -> ,(file-append (with-parameters ((%current-target-system
+ "i586-pc-gnu"))
+ bash)
+ "/bin/sh"))))
+
+ (qemu-image #:file-system-type "ext2"
+ #:file-system-options '("-o" "hurd")
+ #:device-nodes 'hurd
+ #:inputs `(("system" ,system-profile)
+ ("grub.cfg" ,grub.cfg)
+ ("fstab" ,fstab)
+ ("passwd" ,passwd)
+ ("group" ,group)
+ ("etc-profile" ,etc-profile)
+ ("shadow" ,shadow))
+ #:copy-inputs? #t
+ #:os system-profile
+ #:bootcfg-drv grub.cfg
+ #:bootloader grub-bootloader
+ #:register-closures? #f
+ #:extra-directives hurd-directives))
+
+;; Return this thunk so one can type "guix build -f gnu/system/hurd.scm".
+cross-hurd-image
diff --git a/gnu/system/image.scm b/gnu/system/image.scm
new file mode 100644
index 0000000000..571b7af5f3
--- /dev/null
+++ b/gnu/system/image.scm
@@ -0,0 +1,532 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2020 Mathieu Othacehe <m.othacehe@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 system image)
+ #:use-module (guix gexp)
+ #:use-module (guix modules)
+ #:use-module (guix monads)
+ #:use-module (guix records)
+ #:use-module (guix store)
+ #:use-module (guix ui)
+ #:use-module (guix utils)
+ #:use-module ((guix self) #:select (make-config.scm))
+ #:use-module (gnu bootloader)
+ #:use-module (gnu bootloader grub)
+ #:use-module (gnu image)
+ #:use-module (gnu services)
+ #:use-module (gnu services base)
+ #:use-module (gnu system)
+ #:use-module (gnu system file-systems)
+ #:use-module (gnu system uuid)
+ #:use-module (gnu system vm)
+ #:use-module (guix packages)
+ #:use-module (gnu packages base)
+ #:use-module (gnu packages bootloaders)
+ #:use-module (gnu packages cdrom)
+ #:use-module (gnu packages disk)
+ #:use-module (gnu packages gawk)
+ #:use-module (gnu packages genimage)
+ #:use-module (gnu packages guile)
+ #:autoload (gnu packages gnupg) (guile-gcrypt)
+ #:use-module (gnu packages linux)
+ #:use-module (gnu packages mtools)
+ #:use-module ((srfi srfi-1) #:prefix srfi-1:)
+ #:use-module (srfi srfi-11)
+ #:use-module (srfi srfi-26)
+ #:use-module (srfi srfi-35)
+ #:use-module (rnrs bytevectors)
+ #:use-module (ice-9 match)
+ #:export (esp-partition
+ root-partition
+
+ efi-disk-image
+ iso9660-image
+
+ find-image
+ system-image))
+
+
+;;;
+;;; Images definitions.
+;;;
+
+(define esp-partition
+ (partition
+ (size (* 40 (expt 2 20)))
+ (label "GNU-ESP") ;cosmetic only
+ ;; Use "vfat" here since this property is used when mounting. The actual
+ ;; FAT-ness is based on file system size (16 in this case).
+ (file-system "vfat")
+ (flags '(esp))
+ (initializer (gexp initialize-efi-partition))))
+
+(define root-partition
+ (partition
+ (size 'guess)
+ (label "Guix_image")
+ (file-system "ext4")
+ (flags '(boot))
+ (initializer (gexp initialize-root-partition))))
+
+(define efi-disk-image
+ (image
+ (format 'disk-image)
+ (partitions (list esp-partition root-partition))))
+
+(define iso9660-image
+ (image
+ (format 'iso9660)
+ (partitions
+ (list (partition
+ (size 'guess)
+ (label "GUIX_IMAGE")
+ (flags '(boot)))))
+ ;; XXX: Temporarily disable compression to speed-up the tests.
+ (compression? #f)))
+
+
+;;
+;; Helpers.
+;;
+
+(define not-config?
+ ;; Select (guix …) and (gnu …) modules, except (guix config).
+ (match-lambda
+ (('guix 'config) #f)
+ (('guix rest ...) #t)
+ (('gnu rest ...) #t)
+ (rest #f)))
+
+(define (partition->gexp partition)
+ "Turn PARTITION, a <partition> object, into a list-valued gexp suitable for
+'make-partition-image'."
+ #~'(#$@(list (partition-size partition))
+ #$(partition-file-system partition)
+ #$(partition-label partition)
+ #$(and=> (partition-uuid partition)
+ uuid-bytevector)))
+
+(define gcrypt-sqlite3&co
+ ;; Guile-Gcrypt, Guile-SQLite3, and their propagated inputs.
+ (srfi-1:append-map
+ (lambda (package)
+ (cons package
+ (match (package-transitive-propagated-inputs package)
+ (((labels packages) ...)
+ packages))))
+ (list guile-gcrypt guile-sqlite3)))
+
+(define-syntax-rule (with-imported-modules* gexp* ...)
+ (with-extensions gcrypt-sqlite3&co
+ (with-imported-modules `(,@(source-module-closure
+ '((gnu build vm)
+ (gnu build image)
+ (guix store database))
+ #:select? not-config?)
+ ((guix config) => ,(make-config.scm)))
+ #~(begin
+ (use-modules (gnu build vm)
+ (gnu build image)
+ (guix store database)
+ (guix build utils))
+ gexp* ...))))
+
+
+;;
+;; Disk image.
+;;
+
+(define* (system-disk-image image
+ #:key
+ (name "disk-image")
+ bootcfg
+ bootloader
+ register-closures?
+ (inputs '()))
+ "Return as a file-like object, the disk-image described by IMAGE. Said
+image can be copied on a USB stick as is. BOOTLOADER is the bootloader that
+will be installed and configured according to BOOTCFG parameter.
+
+Raw images of the IMAGE partitions are first created. Then, genimage is used
+to assemble the partition images into a disk-image without resorting to a
+virtual machine.
+
+INPUTS is a list of inputs (as for packages). When REGISTER-CLOSURES? is
+true, register INPUTS in the store database of the image so that Guix can be
+used in the image."
+
+ (define genimage-name "image")
+
+ (define (image->genimage-cfg image)
+ ;; Return as a file-like object, the genimage configuration file
+ ;; describing the given IMAGE.
+ (define (format->image-type format)
+ ;; Return the genimage format corresponding to FORMAT. For now, only
+ ;; the hdimage format (raw disk-image) is supported.
+ (case format
+ ((disk-image) "hdimage")
+ (else
+ (raise (condition
+ (&message
+ (message
+ (format #f (G_ "Unsupported image type ~a~%.") format))))))))
+
+ (define (partition->dos-type partition)
+ ;; Return the MBR partition type corresponding to the given PARTITION.
+ ;; See: https://en.wikipedia.org/wiki/Partition_type.
+ (let ((flags (partition-flags partition)))
+ (cond
+ ((member 'esp flags) "0xEF")
+ (else "0x83"))))
+
+ (define (partition-image partition)
+ ;; Return as a file-like object, an image of the given PARTITION. A
+ ;; directory, filled by calling the PARTITION initializer procedure, is
+ ;; first created within the store. Then, an image of this directory is
+ ;; created using tools such as 'mke2fs' or 'mkdosfs', depending on the
+ ;; partition file-system type.
+ (let* ((os (image-operating-system image))
+ (schema (local-file (search-path %load-path
+ "guix/store/schema.sql")))
+ (graph (match inputs
+ (((names . _) ...)
+ names)))
+ (root-builder
+ (with-imported-modules*
+ (let* ((initializer #$(partition-initializer partition)))
+ (sql-schema #$schema)
+
+ ;; Allow non-ASCII file names--e.g., 'nss-certs'--to be
+ ;; decoded.
+ (setenv "GUIX_LOCPATH"
+ #+(file-append glibc-utf8-locales "/lib/locale"))
+ (setlocale LC_ALL "en_US.utf8")
+
+ (initializer #$output
+ #:references-graphs '#$graph
+ #:deduplicate? #f
+ #:system-directory #$os
+ #:bootloader-package
+ #$(bootloader-package bootloader)
+ #:bootcfg #$bootcfg
+ #:bootcfg-location
+ #$(bootloader-configuration-file bootloader)))))
+ (image-root
+ (computed-file "partition-image-root" root-builder
+ #:options `(#:references-graphs ,inputs)))
+ (type (partition-file-system partition))
+ (image-builder
+ (with-imported-modules*
+ (let ((inputs '#$(list e2fsprogs dosfstools mtools)))
+ (set-path-environment-variable "PATH" '("bin" "sbin") inputs)
+ (make-partition-image #$(partition->gexp partition)
+ #$output
+ #$image-root)))))
+ (computed-file "partition.img" image-builder)))
+
+ (define (partition->config partition)
+ ;; Return the genimage partition configuration for PARTITION.
+ (let ((label (partition-label partition))
+ (dos-type (partition->dos-type partition))
+ (image (partition-image partition)))
+ #~(format #f "~/partition ~a {
+ ~/~/partition-type = ~a
+ ~/~/image = \"~a\"
+ ~/}" #$label #$dos-type #$image)))
+
+ (let* ((format (image-format image))
+ (image-type (format->image-type format))
+ (partitions (image-partitions image))
+ (partitions-config (map partition->config partitions))
+ (builder
+ #~(begin
+ (let ((format (@ (ice-9 format) format)))
+ (call-with-output-file #$output
+ (lambda (port)
+ (format port
+ "\
+image ~a {
+~/~a {}
+~{~a~^~%~}
+}~%" #$genimage-name #$image-type (list #$@partitions-config))))))))
+ (computed-file "genimage.cfg" builder)))
+
+ (let* ((substitutable? (image-substitutable? image))
+ (builder
+ (with-imported-modules*
+ (let ((inputs '#$(list genimage coreutils findutils)))
+ (set-path-environment-variable "PATH" '("bin" "sbin") inputs)
+ (genimage #$(image->genimage-cfg image) #$output))))
+ (image-dir (computed-file "image-dir" builder)))
+ (computed-file name
+ #~(symlink
+ (string-append #$image-dir "/" #$genimage-name)
+ #$output)
+ #:options `(#:substitutable? ,substitutable?))))
+
+
+;;
+;; ISO9660 image.
+;;
+
+(define (has-guix-service-type? os)
+ "Return true if OS contains a service of the type GUIX-SERVICE-TYPE."
+ (not (not (srfi-1:find (lambda (service)
+ (eq? (service-kind service) guix-service-type))
+ (operating-system-services os)))))
+
+(define* (system-iso9660-image image
+ #:key
+ (name "iso9660-image")
+ bootcfg
+ bootloader
+ register-closures?
+ (inputs '())
+ (grub-mkrescue-environment '()))
+ "Return as a file-like object a bootable, stand-alone iso9660 image.
+
+INPUTS is a list of inputs (as for packages). When REGISTER-CLOSURES? is
+true, register INPUTS in the store database of the image so that Guix can be
+used in the image. "
+ (define root-label
+ (match (image-partitions image)
+ ((partition)
+ (partition-label partition))))
+
+ (define root-uuid
+ (match (image-partitions image)
+ ((partition)
+ (uuid-bytevector (partition-uuid partition)))))
+
+ (let* ((os (image-operating-system image))
+ (bootloader (bootloader-package bootloader))
+ (compression? (image-compression? image))
+ (substitutable? (image-substitutable? image))
+ (schema (local-file (search-path %load-path
+ "guix/store/schema.sql")))
+ (graph (match inputs
+ (((names . _) ...)
+ names)))
+ (root-builder
+ (with-imported-modules*
+ (sql-schema #$schema)
+
+ ;; Allow non-ASCII file names--e.g., 'nss-certs'--to be decoded.
+ (setenv "GUIX_LOCPATH"
+ #+(file-append glibc-utf8-locales "/lib/locale"))
+ (setlocale LC_ALL "en_US.utf8")
+
+ (initialize-root-partition #$output
+ #:references-graphs '#$graph
+ #:deduplicate? #f
+ #:system-directory #$os)))
+ (image-root
+ (computed-file "image-root" root-builder
+ #:options `(#:references-graphs ,inputs)))
+ (builder
+ (with-imported-modules*
+ (let* ((inputs '#$(list parted e2fsprogs dosfstools xorriso
+ sed grep coreutils findutils gawk)))
+ (set-path-environment-variable "PATH" '("bin" "sbin") inputs)
+ (make-iso9660-image #$xorriso
+ '#$grub-mkrescue-environment
+ #$bootloader
+ #$bootcfg
+ #$os
+ #$image-root
+ #$output
+ #:references-graphs '#$graph
+ #:register-closures? #$register-closures?
+ #:compression? #$compression?
+ #:volume-id #$root-label
+ #:volume-uuid #$root-uuid)))))
+ (computed-file name builder
+ #:options `(#:references-graphs ,inputs
+ #:substitutable? ,substitutable?))))
+
+
+;;
+;; Image creation.
+;;
+
+(define (root-partition? partition)
+ "Return true if PARTITION is the root partition, false otherwise."
+ (member 'boot (partition-flags partition)))
+
+(define (find-root-partition image)
+ "Return the root partition of the given IMAGE."
+ (srfi-1:find root-partition? (image-partitions image)))
+
+(define (image->root-file-system image)
+ "Return the IMAGE root partition file-system type."
+ (let ((format (image-format image)))
+ (if (eq? format 'iso9660)
+ "iso9660"
+ (partition-file-system (find-root-partition image)))))
+
+(define (root-size image)
+ "Return the root partition size of IMAGE."
+ (let* ((image-size (image-size image))
+ (root-partition (find-root-partition image))
+ (root-size (partition-size root-partition)))
+ (cond
+ ((and (eq? root-size 'guess) image-size)
+ image-size)
+ (else root-size))))
+
+(define* (image-with-os base-image os)
+ "Return an image based on BASE-IMAGE but with the operating-system field set
+to OS. Also set the UUID and the size of the root partition."
+ (define root-file-system
+ (srfi-1:find
+ (lambda (fs)
+ (string=? (file-system-mount-point fs) "/"))
+ (operating-system-file-systems os)))
+
+ (let*-values (((partitions) (image-partitions base-image))
+ ((root-partition other-partitions)
+ (srfi-1:partition root-partition? partitions)))
+ (image
+ (inherit base-image)
+ (operating-system os)
+ (partitions
+ (cons (partition
+ (inherit (car root-partition))
+ (uuid (file-system-device root-file-system))
+ (size (root-size base-image)))
+ other-partitions)))))
+
+(define (operating-system-for-image image)
+ "Return an operating-system based on the one specified in IMAGE, but
+suitable for image creation. Assign an UUID to the root file-system, so that
+it can be used for bootloading."
+ (define volatile-root? (image-volatile-root? image))
+
+ (define (root-uuid os)
+ ;; UUID of the root file system, computed in a deterministic fashion.
+ ;; This is what we use to locate the root file system so it has to be
+ ;; different from the user's own file system UUIDs.
+ (let ((type (if (eq? (image-format image) 'iso9660)
+ 'iso9660
+ 'dce)))
+ (operating-system-uuid os type)))
+
+ (let* ((root-file-system-type (image->root-file-system image))
+ (base-os (image-operating-system image))
+ (file-systems-to-keep
+ (srfi-1:remove
+ (lambda (fs)
+ (string=? (file-system-mount-point fs) "/"))
+ (operating-system-file-systems base-os)))
+ (format (image-format image))
+ (os
+ (operating-system
+ (inherit base-os)
+ (initrd (lambda (file-systems . rest)
+ (apply (operating-system-initrd base-os)
+ file-systems
+ #:volatile-root? volatile-root?
+ rest)))
+ (bootloader (if (eq? format 'iso9660)
+ (bootloader-configuration
+ (inherit
+ (operating-system-bootloader base-os))
+ (bootloader grub-mkrescue-bootloader))
+ (operating-system-bootloader base-os)))
+ (file-systems (cons (file-system
+ (mount-point "/")
+ (device "/dev/placeholder")
+ (type root-file-system-type))
+ file-systems-to-keep))))
+ (uuid (root-uuid os)))
+ (operating-system
+ (inherit os)
+ (file-systems (cons (file-system
+ (mount-point "/")
+ (device uuid)
+ (type root-file-system-type))
+ file-systems-to-keep)))))
+
+(define* (make-system-image image)
+ "Return the derivation of IMAGE. It can be a raw disk-image or an ISO9660
+image, depending on IMAGE format."
+ (define substitutable? (image-substitutable? image))
+
+ (let* ((os (operating-system-for-image image))
+ (image* (image-with-os image os))
+ (register-closures? (has-guix-service-type? os))
+ (bootcfg (operating-system-bootcfg os))
+ (bootloader (bootloader-configuration-bootloader
+ (operating-system-bootloader os))))
+ (case (image-format image)
+ ((disk-image)
+ (system-disk-image image*
+ #:bootcfg bootcfg
+ #:bootloader bootloader
+ #:register-closures? register-closures?
+ #:inputs `(("system" ,os)
+ ("bootcfg" ,bootcfg))))
+ ((iso9660)
+ (system-iso9660-image image*
+ #:bootcfg bootcfg
+ #:bootloader bootloader
+ #:register-closures? register-closures?
+ #:inputs `(("system" ,os)
+ ("bootcfg" ,bootcfg))
+ #:grub-mkrescue-environment
+ '(("MKRESCUE_SED_MODE" . "mbr_hfs")))))))
+
+(define (find-image file-system-type)
+ "Find and return an image that could match the given FILE-SYSTEM-TYPE. This
+is useful to adapt to interfaces written before the addition of the <image>
+record."
+ ;; XXX: Add support for system and target here, or in the caller.
+ (match file-system-type
+ ("iso9660" iso9660-image)
+ (_ efi-disk-image)))
+
+(define (system-image image)
+ "Wrap 'make-system-image' call, so that it is used only if the given IMAGE
+is supported. Otherwise, fallback to image creation in a VM. This is
+temporary and should be removed once 'make-system-image' is able to deal with
+all types of images."
+ (define substitutable? (image-substitutable? image))
+ (define volatile-root? (image-volatile-root? image))
+
+ (let* ((image-os (image-operating-system image))
+ (image-root-filesystem-type (image->root-file-system image))
+ (bootloader (bootloader-configuration-bootloader
+ (operating-system-bootloader image-os)))
+ (bootloader-name (bootloader-name bootloader))
+ (size (image-size image))
+ (format (image-format image)))
+ (mbegin %store-monad
+ (if (and (or (eq? bootloader-name 'grub)
+ (eq? bootloader-name 'extlinux))
+ (eq? format 'disk-image))
+ ;; Fallback to image creation in a VM when it is not yet supported
+ ;; by this module.
+ (system-disk-image-in-vm image-os
+ #:disk-image-size size
+ #:file-system-type image-root-filesystem-type
+ #:volatile? volatile-root?
+ #:substitutable? substitutable?)
+ (lower-object
+ (make-system-image image))))))
+
+;;; image.scm ends here
diff --git a/gnu/system/install.scm b/gnu/system/install.scm
index d31ed9a197..fe49ffdb94 100644
--- a/gnu/system/install.scm
+++ b/gnu/system/install.scm
@@ -419,8 +419,7 @@ Access documentation at any time by pressing Alt-F2.\x1b[0m
;; Having /bin/sh is a good idea. In particular it allows Tramp
;; connections to this system to work.
(service special-files-service-type
- `(("/bin/sh" ,(file-append (canonical-package bash)
- "/bin/sh"))))
+ `(("/bin/sh" ,(file-append bash "/bin/sh"))))
;; Loopback device, needed by OpenSSH notably.
(service static-networking-service-type
@@ -443,7 +442,7 @@ Access documentation at any time by pressing Alt-F2.\x1b[0m
(list bare-bones-os
glibc-utf8-locales
texinfo
- (canonical-package guile-2.2)))
+ guile-3.0))
;; Machines without Kernel Mode Setting (those with many old and
;; current AMD GPUs, SiS GPUs, ...) need uvesafb to show the GUI
@@ -471,12 +470,6 @@ Access documentation at any time by pressing Alt-F2.\x1b[0m
(label (string-append "GNU Guix installation "
(package-version guix)))
- ;; XXX: The AMD Radeon driver is reportedly broken, which makes kmscon
- ;; non-functional:
- ;; <https://lists.gnu.org/archive/html/guix-devel/2019-03/msg00441.html>.
- ;; Thus, blacklist it.
- (kernel-arguments '("quiet" "modprobe.blacklist=radeon"))
-
(file-systems
;; Note: the disk image build code overrides this root file system with
;; the appropriate one.
@@ -521,7 +514,7 @@ Access documentation at any time by pressing Alt-F2.\x1b[0m
;; Explicitly allow for empty passwords.
(base-pam-services #:allow-empty-passwords? #t))
- (packages (cons* (canonical-package glibc) ;for 'tzselect' & co.
+ (packages (cons* glibc ;for 'tzselect' & co.
parted gptfdisk ddrescue
fontconfig
font-dejavu font-gnu-unifont
@@ -530,6 +523,7 @@ Access documentation at any time by pressing Alt-F2.\x1b[0m
mdadm
dosfstools ;mkfs.fat, for the UEFI boot partition
btrfs-progs
+ f2fs-tools
jfsutils
openssh ;we already have sshd, having ssh/scp can help
wireless-tools iw wpa-supplicant-minimal iproute
diff --git a/gnu/system/linux-initrd.scm b/gnu/system/linux-initrd.scm
index dcc9b6b937..c43d53a210 100644
--- a/gnu/system/linux-initrd.scm
+++ b/gnu/system/linux-initrd.scm
@@ -36,7 +36,7 @@
#:use-module ((gnu packages xorg)
#:select (console-setup xkeyboard-config))
#:use-module ((gnu packages make-bootstrap)
- #:select (%guile-static-stripped))
+ #:select (%guile-3.0-static-stripped))
#:use-module (gnu system file-systems)
#:use-module (gnu system mapped-devices)
#:use-module (gnu system keyboard)
@@ -62,7 +62,7 @@
(define* (expression->initrd exp
#:key
- (guile %guile-static-stripped)
+ (guile %guile-3.0-static-stripped)
(gzip gzip)
(name "guile-initrd")
(system (%current-system)))
@@ -245,6 +245,9 @@ FILE-SYSTEMS."
'())
,@(if (find (file-system-type-predicate "jfs") file-systems)
(list jfs_fsck/static)
+ '())
+ ,@(if (find (file-system-type-predicate "f2fs") file-systems)
+ (list f2fs-fsck/static)
'())))
(define-syntax vhash ;TODO: factorize
@@ -275,6 +278,7 @@ FILE-SYSTEMS."
("btrfs" => '("btrfs"))
("iso9660" => '("isofs"))
("jfs" => '("jfs"))
+ ("f2fs" => '("f2fs" "crc32_generic"))
(else '())))
(define (file-system-modules file-systems)
diff --git a/gnu/system/locale.scm b/gnu/system/locale.scm
index 8466d5b07d..689d238d1a 100644
--- a/gnu/system/locale.scm
+++ b/gnu/system/locale.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2014, 2015, 2016, 2017, 2019 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2014, 2015, 2016, 2017, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2018 Mark H Weaver <mhw@netris.org>
;;;
;;; This file is part of GNU Guix.
@@ -86,7 +86,7 @@ or #f on failure."
#f)))
(define* (single-locale-directory locales
- #:key (libc (canonical-package glibc)))
+ #:key (libc glibc))
"Return a directory containing all of LOCALES for LIBC compiled.
Because locale data formats are incompatible when switching from one libc to
@@ -106,7 +106,7 @@ of LIBC."
;; 'localedef' executes 'gzip' to access compressed locale sources.
(setenv "PATH"
- (string-append #$gzip "/bin:" #$libc "/bin"))
+ (string-append #+gzip "/bin:" #+libc "/bin"))
(setvbuf (current-output-port) 'line)
(setvbuf (current-error-port) 'line)
@@ -147,7 +147,8 @@ data format changes between libc versions."
(define %default-locale-libcs
;; The libcs for which we build locales by default.
- (list (canonical-package glibc)))
+ ;; List the previous and current libc to ease transition.
+ (list glibc-2.29 glibc))
(define %default-locale-definitions
;; Arbitrary set of locales that are built by default. They are here mostly
diff --git a/gnu/system/pam.scm b/gnu/system/pam.scm
index 85f75517b1..ad02586be8 100644
--- a/gnu/system/pam.scm
+++ b/gnu/system/pam.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -367,7 +367,13 @@ strings or string-valued gexps."
;; Arguments include <pam-service> as well as procedures.
(compose concatenate)
- (extend extend-configuration)))
+ (extend extend-configuration)
+ (description
+ "Configure the Pluggable Authentication Modules (PAM) for all
+the specified @dfn{PAM services}. Each PAM service corresponds to a program,
+such as @command{login} or @command{sshd}, and specifies for instance how the
+program may authenticate users or what it should do when opening a new
+session.")))
(define* (pam-root-service base #:key (transform identity))
"The \"root\" PAM service, which collects <pam-service> instance and turns
diff --git a/gnu/system/shadow.scm b/gnu/system/shadow.scm
index a6f1d806cf..a69339bc07 100644
--- a/gnu/system/shadow.scm
+++ b/gnu/system/shadow.scm
@@ -378,7 +378,10 @@ the /etc/skel directory for those."
(service-extension user-processes-service-type
(const '(user-homes)))
(service-extension etc-service-type
- etc-files)))))
+ etc-files)))
+ (description
+ "Ensure the specified user accounts and groups exist, as well
+as each account home directory.")))
(define (account-service accounts+groups skeletons)
"Return a <service> that takes care of user accounts and user groups, with
diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm
index 6f81ac16ff..163e8b4e9c 100644
--- a/gnu/system/vm.scm
+++ b/gnu/system/vm.scm
@@ -77,7 +77,7 @@
system-qemu-image/shared-store
system-qemu-image/shared-store-script
- system-disk-image
+ system-disk-image-in-vm
system-docker-image
virtual-machine
@@ -269,95 +269,6 @@ substitutable."
(eq? (service-kind service) guix-service-type))
(operating-system-services os)))))
-(define* (iso9660-image #:key
- (name "iso9660-image")
- file-system-label
- file-system-uuid
- (system (%current-system))
- (target (%current-target-system))
- (qemu qemu-minimal)
- os
- bootcfg-drv
- bootloader
- (register-closures? (has-guix-service-type? os))
- (inputs '())
- (grub-mkrescue-environment '())
- (substitutable? #t))
- "Return a bootable, stand-alone iso9660 image.
-
-INPUTS is a list of inputs (as for packages)."
- (define schema
- (and register-closures?
- (local-file (search-path %load-path
- "guix/store/schema.sql"))))
-
- (expression->derivation-in-linux-vm
- name
- (with-extensions gcrypt-sqlite3&co
- (with-imported-modules `(,@(source-module-closure '((gnu build vm)
- (guix store database)
- (guix build utils))
- #:select? not-config?)
- ((guix config) => ,(make-config.scm)))
- #~(begin
- (use-modules (gnu build vm)
- (guix store database)
- (guix build utils))
-
- (sql-schema #$schema)
-
- ;; Allow non-ASCII file names--e.g., 'nss-certs'--to be decoded.
- (setenv "GUIX_LOCPATH"
- #+(file-append glibc-utf8-locales "/lib/locale"))
- (setlocale LC_ALL "en_US.utf8")
-
- (let ((inputs
- '#$(append (list parted e2fsprogs dosfstools xorriso)
- (map canonical-package
- (list sed grep coreutils findutils gawk))))
-
-
- (graphs '#$(match inputs
- (((names . _) ...)
- names)))
- ;; This variable is unused but allows us to add INPUTS-TO-COPY
- ;; as inputs.
- (to-register
- '#$(map (match-lambda
- ((name thing) thing)
- ((name thing output) `(,thing ,output)))
- inputs)))
-
- (set-path-environment-variable "PATH" '("bin" "sbin") inputs)
- (make-iso9660-image #$xorriso
- '#$grub-mkrescue-environment
- #$(bootloader-package bootloader)
- #$bootcfg-drv
- #$os
- "/xchg/guixsd.iso"
- #:register-closures? #$register-closures?
- #:closures graphs
- #:volume-id #$file-system-label
- #:volume-uuid #$(and=> file-system-uuid
- uuid-bytevector))))))
- #:system system
- #:target target
-
- ;; Keep a local file system for /tmp so that we can populate it directly as
- ;; root and have files owned by root. See <https://bugs.gnu.org/31752>.
- #:file-systems (remove (lambda (file-system)
- (string=? (file-system-mount-point file-system)
- "/tmp"))
- %linux-vm-file-systems)
-
- #:make-disk-image? #f
- #:single-file-output? #t
- #:references-graphs inputs
- #:substitutable? substitutable?
-
- ;; Xorriso seems to be quite memory-hungry, so increase the VM's RAM size.
- #:memory-size 512))
-
(define* (qemu-image #:key
(name "qemu-image")
(system (%current-system))
@@ -366,6 +277,9 @@ INPUTS is a list of inputs (as for packages)."
(disk-image-size 'guess)
(disk-image-format "qcow2")
(file-system-type "ext4")
+ (file-system-options '())
+ (device-nodes 'linux)
+ (extra-directives '())
file-system-label
file-system-uuid
os
@@ -379,7 +293,8 @@ INPUTS is a list of inputs (as for packages)."
'qcow2' or 'raw'), with a root partition of type FILE-SYSTEM-TYPE.
Optionally, FILE-SYSTEM-LABEL can be specified as the volume name for the root
partition; likewise FILE-SYSTEM-UUID, if true, specifies the UUID of the root
-partition (a UUID object).
+partition (a UUID object). FILE-SYSTEM-OPTIONS is an optional list of
+command-line options passed to 'mkfs.ext4' (or similar).
The returned image is a full disk image that runs OS-DERIVATION,
with a GRUB installation that uses GRUB-CONFIGURATION as its configuration
@@ -390,7 +305,13 @@ all of INPUTS into the image being built. When REGISTER-CLOSURES? is true,
register INPUTS in the store database of the image so that Guix can be used in
the image. By default, REGISTER-CLOSURES? is set to true only if a service of
type GUIX-SERVICE-TYPE is present in the services definition of the operating
-system."
+system.
+
+When DEVICE-NODES is 'linux, create Linux-device block and character devices
+under /dev. When it is 'hurd, do Hurdish things.
+
+EXTRA-DIRECTIVES is an optional list of directives to populate the root file
+system that is passed to 'populate-root-file-system'."
(define schema
(and register-closures?
(local-file (search-path %load-path
@@ -408,6 +329,9 @@ system."
#~(begin
(use-modules (gnu build bootloader)
(gnu build vm)
+ ((gnu build linux-boot)
+ #:select (make-essential-device-nodes
+ make-hurd-device-nodes))
(guix store database)
(guix build utils)
(srfi srfi-26)
@@ -439,11 +363,17 @@ system."
(((names . _) ...)
names)))
(initialize (root-partition-initializer
+ #:extra-directives '#$extra-directives
#:closures graphs
#:copy-closures? #$copy-inputs?
#:register-closures? #$register-closures?
#:system-directory #$os
+ #:make-device-nodes
+ #$(match device-nodes
+ ('linux #~make-essential-device-nodes)
+ ('hurd #~make-hurd-device-nodes))
+
;; Disable deduplication to speed things up,
;; and because it doesn't help much for a
;; single system generation.
@@ -465,6 +395,7 @@ system."
(uuid #$(and=> file-system-uuid
uuid-bytevector))
(file-system #$file-system-type)
+ (file-system-options '#$file-system-options)
(flags '(boot))
(initializer initialize)))
;; Append a small EFI System Partition for use with UEFI
@@ -508,13 +439,17 @@ system."
(define* (system-docker-image os
#:key
(name "guix-docker-image")
- (register-closures? (has-guix-service-type? os)))
+ (register-closures? (has-guix-service-type? os))
+ shared-network?)
"Build a docker image. OS is the desired <operating-system>. NAME is the
-base name to use for the output file. When REGISTER-CLOSURES? is true,
-register the closure of OS with Guix in the resulting Docker image. By
-default, REGISTER-CLOSURES? is set to true only if a service of type
-GUIX-SERVICE-TYPE is present in the services definition of the operating
-system."
+base name to use for the output file. When SHARED-NETWORK? is true, assume
+that the container will share network with the host and thus doesn't need a
+DHCP client, nscd, and so on.
+
+When REGISTER-CLOSURES? is true, register the closure of OS with Guix in the
+resulting Docker image. By default, REGISTER-CLOSURES? is set to true only if
+a service of type GUIX-SERVICE-TYPE is present in the services definition of
+the operating system."
(define schema
(and register-closures?
(local-file (search-path %load-path
@@ -531,7 +466,9 @@ system."
(let ((os (operating-system-with-gc-roots
- (containerized-operating-system os '())
+ (containerized-operating-system os '()
+ #:shared-network?
+ shared-network?)
(list boot-program)))
(name (string-append name ".tar.gz"))
(graph "system-graph"))
@@ -604,62 +541,13 @@ system."
;;; VM and disk images.
;;;
-(define* (operating-system-uuid os #:optional (type 'dce))
- "Compute UUID object with a deterministic \"UUID\" for OS, of the given
-TYPE (one of 'iso9660 or 'dce). Return a UUID object."
- ;; Note: For this to be deterministic, we must not hash things that contains
- ;; (directly or indirectly) procedures, for example. That rules out
- ;; anything that contains gexps, thunk or delayed record fields, etc.
-
- (define service-name
- (compose service-type-name service-kind))
-
- (define (file-system-digest fs)
- ;; Return a hashable digest that does not contain 'dependencies' since
- ;; this field can contain procedures.
- (let ((device (file-system-device fs)))
- (list (file-system-mount-point fs)
- (file-system-type fs)
- (file-system-device->string device)
- (file-system-options fs))))
-
- (if (eq? type 'iso9660)
- (let ((pad (compose (cut string-pad <> 2 #\0)
- number->string))
- (h (hash (map service-name (operating-system-services os))
- 3600)))
- (bytevector->uuid
- (string->iso9660-uuid
- (string-append "1970-01-01-"
- (pad (hash (operating-system-host-name os) 24)) "-"
- (pad (quotient h 60)) "-"
- (pad (modulo h 60)) "-"
- (pad (hash (map file-system-digest
- (operating-system-file-systems os))
- 100))))
- 'iso9660))
- (bytevector->uuid
- (uint-list->bytevector
- (list (hash (map file-system-digest
- (operating-system-file-systems os))
- (- (expt 2 32) 1))
- (hash (operating-system-host-name os)
- (- (expt 2 32) 1))
- (hash (map service-name (operating-system-services os))
- (- (expt 2 32) 1))
- (hash (map file-system-digest (operating-system-file-systems os))
- (- (expt 2 32) 1)))
- (endianness little)
- 4)
- type)))
-
-(define* (system-disk-image os
- #:key
- (name "disk-image")
- (file-system-type "ext4")
- (disk-image-size (* 900 (expt 2 20)))
- (volatile? #t)
- (substitutable? #t))
+(define* (system-disk-image-in-vm os
+ #:key
+ (name "disk-image")
+ (file-system-type "ext4")
+ (disk-image-size (* 900 (expt 2 20)))
+ (volatile? #t)
+ (substitutable? #t))
"Return the derivation of a disk image of DISK-IMAGE-SIZE bytes of the
system described by OS. Said image can be copied on a USB stick as is. When
VOLATILE? is true, the root file system is made volatile; this is useful
@@ -667,25 +555,14 @@ to USB sticks meant to be read-only.
SUBSTITUTABLE? determines whether the returned derivation should be marked as
substitutable."
- (define normalize-label
- ;; ISO labels are all-caps (case-insensitive), but since
- ;; 'find-partition-by-label' is case-sensitive, make it all-caps here.
- (if (string=? "iso9660" file-system-type)
- string-upcase
- identity))
-
(define root-label
- ;; Volume name of the root file system.
- (normalize-label "Guix_image"))
+ "Guix_image")
(define (root-uuid os)
;; UUID of the root file system, computed in a deterministic fashion.
;; This is what we use to locate the root file system so it has to be
;; different from the user's own file system UUIDs.
- (operating-system-uuid os
- (if (string=? file-system-type "iso9660")
- 'iso9660
- 'dce)))
+ (operating-system-uuid os 'dce))
(define file-systems-to-keep
(remove (lambda (fs)
@@ -702,11 +579,7 @@ substitutable."
#:volatile-root? volatile?
rest)))
- (bootloader (if (string=? "iso9660" file-system-type)
- (bootloader-configuration
- (inherit (operating-system-bootloader os))
- (bootloader grub-mkrescue-bootloader))
- (operating-system-bootloader os)))
+ (bootloader (operating-system-bootloader os))
;; Force our own root file system. (We need a "/" file system
;; to call 'root-uuid'.)
@@ -724,33 +597,20 @@ substitutable."
(type file-system-type))
file-systems-to-keep))))
(bootcfg (operating-system-bootcfg os)))
- (if (string=? "iso9660" file-system-type)
- (iso9660-image #:name name
- #:file-system-label root-label
- #:file-system-uuid uuid
- #:os os
- #:bootcfg-drv bootcfg
- #:bootloader (bootloader-configuration-bootloader
- (operating-system-bootloader os))
- #:inputs `(("system" ,os)
- ("bootcfg" ,bootcfg))
- #:grub-mkrescue-environment
- '(("MKRESCUE_SED_MODE" . "mbr_hfs"))
- #:substitutable? substitutable?)
- (qemu-image #:name name
- #:os os
- #:bootcfg-drv bootcfg
- #:bootloader (bootloader-configuration-bootloader
- (operating-system-bootloader os))
- #:disk-image-size disk-image-size
- #:disk-image-format "raw"
- #:file-system-type file-system-type
- #:file-system-label root-label
- #:file-system-uuid uuid
- #:copy-inputs? #t
- #:inputs `(("system" ,os)
- ("bootcfg" ,bootcfg))
- #:substitutable? substitutable?))))
+ (qemu-image #:name name
+ #:os os
+ #:bootcfg-drv bootcfg
+ #:bootloader (bootloader-configuration-bootloader
+ (operating-system-bootloader os))
+ #:disk-image-size disk-image-size
+ #:disk-image-format "raw"
+ #:file-system-type file-system-type
+ #:file-system-label root-label
+ #:file-system-uuid uuid
+ #:copy-inputs? #t
+ #:inputs `(("system" ,os)
+ ("bootcfg" ,bootcfg))
+ #:substitutable? substitutable?)))
(define* (system-qemu-image os
#:key