1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
4 ;;; Copyright © 2015, 2016 Alex Kost <alezost@gmail.com>
5 ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com>
6 ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
8 ;;; This file is part of GNU Guix.
10 ;;; GNU Guix is free software; you can redistribute it and/or modify it
11 ;;; under the terms of the GNU General Public License as published by
12 ;;; the Free Software Foundation; either version 3 of the License, or (at
13 ;;; your option) any later version.
15 ;;; GNU Guix is distributed in the hope that it will be useful, but
16 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;;; GNU General Public License for more details.
20 ;;; You should have received a copy of the GNU General Public License
21 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
23 (define-module (gnu system)
24 #:use-module (guix store)
25 #:use-module (guix monads)
26 #:use-module (guix gexp)
27 #:use-module (guix records)
28 #:use-module (guix packages)
29 #:use-module (guix derivations)
30 #:use-module (guix profiles)
31 #:use-module (guix ui)
32 #:use-module (gnu packages base)
33 #:use-module (gnu packages bash)
34 #:use-module (gnu packages guile)
35 #:use-module (gnu packages admin)
36 #:use-module (gnu packages linux)
37 #:use-module (gnu packages pciutils)
38 #:use-module (gnu packages package-management)
39 #:use-module (gnu packages less)
40 #:use-module (gnu packages zile)
41 #:use-module (gnu packages nano)
42 #:use-module (gnu packages lsof)
43 #:use-module (gnu packages gawk)
44 #:use-module (gnu packages man)
45 #:use-module (gnu packages texinfo)
46 #:use-module (gnu packages compression)
47 #:use-module (gnu packages firmware)
48 #:use-module (gnu services)
49 #:use-module (gnu services shepherd)
50 #:use-module (gnu services base)
51 #:use-module (gnu bootloader)
52 #:use-module (gnu system shadow)
53 #:use-module (gnu system nss)
54 #:use-module (gnu system locale)
55 #:use-module (gnu system pam)
56 #:use-module (gnu system linux-initrd)
57 #:use-module (gnu system uuid)
58 #:use-module (gnu system file-systems)
59 #:use-module (gnu system mapped-devices)
60 #:use-module (ice-9 match)
61 #:use-module (srfi srfi-1)
62 #:use-module (srfi srfi-26)
63 #:use-module (srfi srfi-34)
64 #:use-module (srfi srfi-35)
65 #:use-module (rnrs bytevectors)
66 #:export (operating-system
69 operating-system-bootloader
70 operating-system-services
71 operating-system-user-services
72 operating-system-packages
73 operating-system-host-name
74 operating-system-hosts-file
75 operating-system-kernel
76 operating-system-kernel-file
77 operating-system-kernel-arguments
78 operating-system-initrd
79 operating-system-users
80 operating-system-groups
81 operating-system-issue
82 operating-system-timezone
83 operating-system-locale
84 operating-system-locale-definitions
85 operating-system-locale-libcs
86 operating-system-mapped-devices
87 operating-system-file-systems
88 operating-system-store-file-system
89 operating-system-user-mapped-devices
90 operating-system-boot-mapped-devices
91 operating-system-activation-script
92 operating-system-user-accounts
93 operating-system-shepherd-service-names
95 operating-system-derivation
96 operating-system-profile
97 operating-system-bootcfg
98 operating-system-etc-directory
99 operating-system-locale-directory
100 operating-system-boot-script
102 system-linux-image-file-name
106 boot-parameters-label
107 boot-parameters-root-device
108 boot-parameters-bootloader-name
109 boot-parameters-store-device
110 boot-parameters-store-mount-point
111 boot-parameters-kernel
112 boot-parameters-kernel-arguments
113 boot-parameters-initrd
115 read-boot-parameters-file
116 boot-parameters->menu-entry
125 ;;; This module supports whole-system configuration.
129 (define (bootable-kernel-arguments kernel-arguments system.drv root-device)
130 "Prepend extra arguments to KERNEL-ARGUMENTS that allow SYSTEM.DRV to be
131 booted from ROOT-DEVICE"
132 (cons* (string-append "--root="
133 (if (uuid? root-device)
135 ;; Note: Always use the DCE format because that's
136 ;; what (gnu build linux-boot) expects for the
137 ;; '--root' kernel command-line option.
138 (uuid->string (uuid-bytevector root-device) 'dce)
140 #~(string-append "--system=" #$system.drv)
141 #~(string-append "--load=" #$system.drv "/boot")
144 ;; System-wide configuration.
145 ;; TODO: Add per-field docstrings/stexi.
146 (define-record-type* <operating-system> operating-system
147 make-operating-system
149 (kernel operating-system-kernel ; package
150 (default linux-libre))
151 (kernel-arguments operating-system-user-kernel-arguments
152 (default '())) ; list of gexps/strings
153 (bootloader operating-system-bootloader) ; <bootloader-configuration>
155 (initrd operating-system-initrd ; (list fs) -> M derivation
156 (default base-initrd))
157 (firmware operating-system-firmware ; list of packages
158 (default %base-firmware))
160 (host-name operating-system-host-name) ; string
161 (hosts-file operating-system-hosts-file ; file-like | #f
164 (mapped-devices operating-system-mapped-devices ; list of <mapped-device>
166 (file-systems operating-system-file-systems) ; list of fs
167 (swap-devices operating-system-swap-devices ; list of strings
170 (users operating-system-users ; list of user accounts
171 (default %base-user-accounts))
172 (groups operating-system-groups ; list of user groups
173 (default %base-groups))
175 (skeletons operating-system-skeletons ; list of name/monadic value
176 (default (default-skeletons)))
177 (issue operating-system-issue ; string
178 (default %default-issue))
180 (packages operating-system-packages ; list of (PACKAGE OUTPUT...)
181 (default %base-packages)) ; or just PACKAGE
183 (timezone operating-system-timezone) ; string
184 (locale operating-system-locale ; string
185 (default "en_US.utf8"))
186 (locale-definitions operating-system-locale-definitions ; list of <locale-definition>
187 (default %default-locale-definitions))
188 (locale-libcs operating-system-locale-libcs ; list of <packages>
189 (default %default-locale-libcs))
190 (name-service-switch operating-system-name-service-switch ; <name-service-switch>
191 (default %default-nss))
193 (services operating-system-user-services ; list of monadic services
194 (default %base-services))
196 (pam-services operating-system-pam-services ; list of PAM services
197 (default (base-pam-services)))
198 (setuid-programs operating-system-setuid-programs
199 (default %setuid-programs)) ; list of string-valued gexps
201 (sudoers-file operating-system-sudoers-file ; file-like
202 (default %sudoers-specification)))
204 (define (operating-system-kernel-arguments os system.drv root-device)
205 "Return all the kernel arguments, including the ones not specified
206 directly by the user."
207 (bootable-kernel-arguments (operating-system-user-kernel-arguments os)
216 (define-record-type* <boot-parameters>
217 boot-parameters make-boot-parameters boot-parameters?
218 (label boot-parameters-label)
219 ;; Because we will use the 'store-device' to create the GRUB search command,
220 ;; the 'store-device' has slightly different semantics than 'root-device'.
221 ;; The 'store-device' can be a file system uuid, a file system label, or #f,
222 ;; but it cannot be a device path such as "/dev/sda3", since GRUB would not
223 ;; understand that. The 'root-device', on the other hand, corresponds
224 ;; exactly to the device field of the <file-system> object representing the
225 ;; OS's root file system, so it might be a device path like "/dev/sda3".
226 (root-device boot-parameters-root-device)
227 (bootloader-name boot-parameters-bootloader-name)
228 (store-device boot-parameters-store-device)
229 (store-mount-point boot-parameters-store-mount-point)
230 (kernel boot-parameters-kernel)
231 (kernel-arguments boot-parameters-kernel-arguments)
232 (initrd boot-parameters-initrd))
234 (define (read-boot-parameters port)
235 "Read boot parameters from PORT and return the corresponding
236 <boot-parameters> object or #f if the format is unrecognized."
237 (define device-sexp->device
239 (('uuid (? symbol? type) (? bytevector? bv))
240 (bytevector->uuid bv type))
241 ((? bytevector? bv) ;old format
242 (bytevector->uuid bv 'dce))
246 (define (ensure-not-/dev device)
247 (if (and (string? device) (string-prefix? "/" device))
252 (('boot-parameters ('version 0)
253 ('label label) ('root-device root)
258 (root-device (device-sexp->device root))
261 (match (assq 'bootloader-name rest)
263 (#f 'grub))) ; for compatibility reasons.
265 ;; In the past, we would store the directory name of the kernel instead
266 ;; of the absolute file name of its image. Detect that and correct it.
267 (kernel (if (string=? linux (direct-store-path linux))
268 (string-append linux "/"
269 (system-linux-image-file-name))
273 (match (assq 'kernel-arguments rest)
275 (#f '()))) ;the old format
278 (match (assq 'initrd rest)
279 (('initrd ('string-append directory file)) ;the old format
280 (string-append directory file))
281 (('initrd (? string? file))
285 ;; Linux device names like "/dev/sda1" are not suitable GRUB device
286 ;; identifiers, so we just filter them out.
288 (match (assq 'store rest)
289 (('store ('device #f) _ ...)
291 (('store ('device device) _ ...)
292 (device-sexp->device device))
297 (match (assq 'store rest)
298 (('store ('device _) ('mount-point mount-point) _ ...)
302 (x ;unsupported format
303 (warning (G_ "unrecognized boot parameters for '~a'~%")
307 (define (read-boot-parameters-file system)
308 "Read boot parameters from SYSTEM's (system or generation) \"parameters\"
309 file and returns the corresponding <boot-parameters> object or #f if the
310 format is unrecognized.
311 The object has its kernel-arguments extended in order to make it bootable."
312 (let* ((file (string-append system "/parameters"))
313 (params (call-with-input-file file read-boot-parameters))
314 (root (boot-parameters-root-device params))
315 (kernel-arguments (boot-parameters-kernel-arguments params)))
319 (kernel-arguments (bootable-kernel-arguments kernel-arguments
323 (define (boot-parameters->menu-entry conf)
325 (label (boot-parameters-label conf))
326 (device (boot-parameters-store-device conf))
327 (device-mount-point (boot-parameters-store-mount-point conf))
328 (linux (boot-parameters-kernel conf))
329 (linux-arguments (boot-parameters-kernel-arguments conf))
330 (initrd (boot-parameters-initrd conf))))
338 (define (non-boot-file-system-service os)
339 "Return the file system service for the file systems of OS that are not
340 marked as 'needed-for-boot'."
342 (remove file-system-needed-for-boot?
343 (operating-system-file-systems os)))
345 (define (device-mappings fs)
346 (let ((device (file-system-device fs)))
347 (if (string? device) ;title is 'device
349 (string=? (string-append "/dev/mapper/"
350 (mapped-device-target md))
352 (operating-system-mapped-devices os))
355 (define (add-dependencies fs)
356 ;; Add the dependencies due to device mappings to FS.
360 (delete-duplicates (append (device-mappings fs)
361 (file-system-dependencies fs))
364 (service file-system-service-type
365 (map add-dependencies file-systems)))
367 (define (mapped-device-user device file-systems)
368 "Return a file system among FILE-SYSTEMS that uses DEVICE, or #f."
369 (let ((target (string-append "/dev/mapper/" (mapped-device-target device))))
371 (or (member device (file-system-dependencies fs))
372 (and (eq? 'device (file-system-title fs))
373 (string=? (file-system-device fs) target))))
376 (define (operating-system-user-mapped-devices os)
377 "Return the subset of mapped devices that can be installed in
378 user-land--i.e., those not needed during boot."
379 (let ((devices (operating-system-mapped-devices os))
380 (file-systems (operating-system-file-systems os)))
382 (let ((user (mapped-device-user md file-systems)))
384 (not (file-system-needed-for-boot? user)))))
387 (define (operating-system-boot-mapped-devices os)
388 "Return the subset of mapped devices that must be installed during boot,
390 (let ((devices (operating-system-mapped-devices os))
391 (file-systems (operating-system-file-systems os)))
393 (let ((user (mapped-device-user md file-systems)))
394 (and user (file-system-needed-for-boot? user))))
397 (define (device-mapping-services os)
398 "Return the list of device-mapping services for OS as a list."
399 (map device-mapping-service
400 (operating-system-user-mapped-devices os)))
402 (define (swap-services os)
403 "Return the list of swap services for OS."
404 (map swap-service (operating-system-swap-devices os)))
406 (define* (system-linux-image-file-name #:optional (system (%current-system)))
407 "Return the basename of the kernel image file for SYSTEM."
408 ;; FIXME: Evaluate the conditional based on the actual current system.
410 ((string-prefix? "arm" (%current-system)) "zImage")
411 ((string-prefix? "mips" (%current-system)) "vmlinuz")
412 ((string-prefix? "aarch64" (%current-system)) "Image")
415 (define (operating-system-kernel-file os)
416 "Return an object representing the absolute file name of the kernel image of
418 (file-append (operating-system-kernel os)
419 "/" (system-linux-image-file-name os)))
421 (define* (operating-system-directory-base-entries os #:key container?)
422 "Return the basic entries of the 'system' directory of OS for use as the
423 value of the SYSTEM-SERVICE-TYPE service."
424 (let ((locale (operating-system-locale-directory os)))
425 (with-monad %store-monad
427 (return `(("locale" ,locale)))
429 ((kernel -> (operating-system-kernel os))
430 (initrd (operating-system-initrd-file os))
431 (params (operating-system-boot-parameters-file os)))
432 (return `(("kernel" ,kernel)
433 ("parameters" ,params)
435 ("locale" ,locale)))))))) ;used by libc
437 (define* (essential-services os #:key container?)
438 "Return the list of essential services for OS. These are special services
439 that implement part of what's declared in OS are responsible for low-level
440 bookkeeping. CONTAINER? determines whether to return the list of services for
441 a container or that of a \"bare metal\" system."
443 (map file-system-mount-point (operating-system-file-systems os)))
445 (let* ((mappings (device-mapping-services os))
446 (root-fs (root-file-system-service))
447 (other-fs (non-boot-file-system-service os))
448 (unmount (user-unmount-service known-fs))
449 (swaps (swap-services os))
450 (procs (user-processes-service))
451 (host-name (host-name-service (operating-system-host-name os)))
452 (entries (operating-system-directory-base-entries
453 os #:container? container?)))
454 (cons* (service system-service-type entries)
457 ;; %SHEPHERD-ROOT-SERVICE must come first so that the gexp that
458 ;; execs shepherd comes last in the boot script (XXX). Likewise,
459 ;; the cleanup service must come last so that its gexp runs before
461 %shepherd-root-service
463 (service cleanup-service-type #f)
465 (pam-root-service (operating-system-pam-services os))
466 (account-service (append (operating-system-accounts os)
467 (operating-system-groups os))
468 (operating-system-skeletons os))
469 (operating-system-etc-service os)
470 (service fstab-service-type '())
471 (session-environment-service
472 (operating-system-environment-variables os))
473 host-name procs root-fs unmount
474 (service setuid-program-service-type
475 (operating-system-setuid-programs os))
476 (service profile-service-type
477 (operating-system-packages os))
479 (append mappings swaps
481 ;; Add the firmware service, unless we are building for a
485 (list %linux-bare-metal-service
486 (service firmware-service-type
487 (operating-system-firmware os))))))))
489 (define* (operating-system-services os #:key container?)
490 "Return all the services of OS, including \"internal\" services that do not
491 explicitly appear in OS."
492 (append (operating-system-user-services os)
493 (essential-services os #:container? container?)))
500 (define %base-firmware
501 ;; Firmware usable by default.
502 (list ath9k-htc-firmware
505 (define %base-packages
506 ;; Default set of packages globally visible. It should include anything
507 ;; required for basic administrator tasks.
508 (cons* procps psmisc which less zile nano
509 lsof ;for Guix's 'list-runtime-roots'
511 util-linux inetutils isc-dhcp
512 (@ (gnu packages admin) shadow) ;for 'passwd'
514 ;; wireless-tools is deprecated in favor of iw, but it's still what
515 ;; many people are familiar with, so keep it around.
516 iw wireless-tools rfkill
519 net-tools ; XXX: remove when Inetutils suffices
521 info-reader ;the standalone Info reader (no Perl)
523 ;; The 'sudo' command is already in %SETUID-PROGRAMS, but we also
524 ;; want the other commands and the man pages (notably because
525 ;; auto-completion in Emacs shell relies on man pages.)
528 ;; Get 'insmod' & co. from kmod, not module-init-tools, since udev
529 ;; already depends on it anyway.
536 ;; XXX: We don't use (canonical-package guile-2.2) here because that
537 ;; would create a collision in the global profile between the GMP
538 ;; variant propagated by 'guile-final' and the GMP variant propagated
539 ;; by 'gnutls', itself propagated by 'guix'.
542 ;; The packages below are also in %FINAL-INPUTS, so take them from
543 ;; there to avoid duplication.
544 (map canonical-package
545 (list bash coreutils findutils grep sed
546 diffutils patch gawk tar gzip bzip2 xz lzip))))
548 (define %default-issue
549 ;; Default contents for /etc/issue.
551 This is the GNU system. Welcome.\n")
553 (define (local-host-aliases host-name)
554 "Return aliases for HOST-NAME, to be used in /etc/hosts."
555 (string-append "127.0.0.1 localhost " host-name "\n"
556 "::1 localhost " host-name "\n"))
558 (define (default-/etc/hosts host-name)
559 "Return the default /etc/hosts file."
560 (plain-file "hosts" (local-host-aliases host-name)))
562 (define* (operating-system-etc-service os)
563 "Return a <service> that builds containing the static part of the /etc
565 (let ((login.defs (plain-file "login.defs" "# Empty for now.\n"))
567 (issue (plain-file "issue" (operating-system-issue os)))
568 (nsswitch (plain-file "nsswitch.conf"
569 (name-service-switch->string
570 (operating-system-name-service-switch os))))
572 ;; Startup file for POSIX-compliant login shells, which set system-wide
573 ;; environment variables.
574 (profile (mixed-text-file "profile" "\
575 # Crucial variables that could be missing in the profiles' 'etc/profile'
576 # because they would require combining both profiles.
577 # FIXME: See <http://bugs.gnu.org/20255>.
578 export MANPATH=$HOME/.guix-profile/share/man:/run/current-system/profile/share/man
579 export INFOPATH=$HOME/.guix-profile/share/info:/run/current-system/profile/share/info
580 export XDG_DATA_DIRS=$HOME/.guix-profile/share:/run/current-system/profile/share
581 export XDG_CONFIG_DIRS=$HOME/.guix-profile/etc/xdg:/run/current-system/profile/etc/xdg
583 # Ignore the default value of 'PATH'.
586 # Load the system profile's settings.
587 GUIX_PROFILE=/run/current-system/profile \\
588 . /run/current-system/profile/etc/profile
590 # Prepend setuid programs.
591 export PATH=/run/setuid-programs:$PATH
593 # Since 'lshd' does not use pam_env, /etc/environment must be explicitly
594 # loaded when someone logs in via SSH. See <http://bugs.gnu.org/22175>.
595 # We need 'PATH' to be defined here, for 'cat' and 'cut'. Do this before
596 # reading the user's 'etc/profile' to allow variables to be overridden.
597 if [ -f /etc/environment -a -n \"$SSH_CLIENT\" \\
598 -a -z \"$LINUX_MODULE_DIRECTORY\" ]
601 export `cat /etc/environment | cut -d= -f1`
604 if [ -f \"$HOME/.guix-profile/etc/profile\" ]
606 # Load the user profile's settings.
607 GUIX_PROFILE=\"$HOME/.guix-profile\" \\
608 . \"$HOME/.guix-profile/etc/profile\"
610 # At least define this one so that basic things just work
611 # when the user installs their first package.
612 export PATH=\"$HOME/.guix-profile/bin:$PATH\"
615 # Set the umask, notably for users logging in via 'lsh'.
616 # See <http://bugs.gnu.org/22650>.
619 # Allow Hunspell-based applications (IceCat, LibreOffice, etc.) to
621 export DICPATH=\"$HOME/.guix-profile/share/hunspell:/run/current-system/profile/share/hunspell\"
623 # Allow GStreamer-based applications to find plugins.
624 export GST_PLUGIN_PATH=\"$HOME/.guix-profile/lib/gstreamer-1.0\"
626 if [ -n \"$BASH_VERSION\" -a -f /etc/bashrc ]
628 # Load Bash-specific initialization code.
633 (bashrc (plain-file "bashrc" "\
634 # Bash-specific initialization.
636 # The 'bash-completion' package.
637 if [ -f /run/current-system/profile/etc/profile.d/bash_completion.sh ]
639 # Bash-completion sources ~/.bash_completion. It installs a dynamic
640 # completion loader that searches its own completion files as well
641 # as those in ~/.guix-profile and /run/current-system/profile.
642 source /run/current-system/profile/etc/profile.d/bash_completion.sh
645 `(("services" ,(file-append net-base "/etc/services"))
646 ("protocols" ,(file-append net-base "/etc/protocols"))
647 ("rpc" ,(file-append net-base "/etc/rpc"))
648 ("login.defs" ,#~#$login.defs)
650 ("nsswitch.conf" ,#~#$nsswitch)
651 ("profile" ,#~#$profile)
652 ("bashrc" ,#~#$bashrc)
653 ("hosts" ,#~#$(or (operating-system-hosts-file os)
654 (default-/etc/hosts (operating-system-host-name os))))
655 ;; Write the operating-system-host-name to /etc/hostname to prevent
656 ;; NetworkManager from changing the system's hostname when connecting
657 ;; to certain networks. Some discussion at
658 ;; https://lists.gnu.org/archive/html/help-guix/2017-09/msg00037.html
659 ("hostname" ,(plain-file "hostname" (operating-system-host-name os)))
660 ("localtime" ,(file-append tzdata "/share/zoneinfo/"
661 (operating-system-timezone os)))
662 ("sudoers" ,(operating-system-sudoers-file os))))))
664 (define %root-account
665 ;; Default root account.
669 (uid 0) (group "root")
670 (comment "System administrator")
671 (home-directory "/root")))
673 (define (operating-system-accounts os)
674 "Return the user accounts for OS, including an obligatory 'root' account,
675 and excluding accounts requested by services."
676 ;; Make sure there's a root account.
677 (if (find (lambda (user)
678 (and=> (user-account-uid user) zero?))
679 (operating-system-users os))
680 (operating-system-users os)
681 (cons %root-account (operating-system-users os))))
683 (define (maybe-string->file file-name thing)
684 "If THING is a string, return a <plain-file> with THING as its content.
685 Otherwise just return THING.
687 This is for backward-compatibility of fields that used to be strings and are
688 now file-like objects.."
691 (warning (G_ "using a string for file '~a' is deprecated; \
692 use 'plain-file' instead~%")
694 (plain-file file-name thing))
698 (define (maybe-file->monadic file-name thing)
699 "If THING is a value in %STORE-MONAD, return it as is; otherwise return
700 THING in the %STORE-MONAD.
702 This is for backward-compatibility of fields that used to be monadic values
703 and are now file-like objects."
704 (with-monad %store-monad
707 (warning (G_ "using a monadic value for '~a' is deprecated; \
708 use 'plain-file' instead~%")
714 (define (operating-system-etc-directory os)
715 "Return that static part of the /etc directory of OS."
717 (fold-services (operating-system-services os)
718 #:target-type etc-service-type)))
720 (define (operating-system-environment-variables os)
721 "Return the environment variables of OS for
722 @var{session-environment-service-type}, to be used in @file{/etc/environment}."
723 `(("LANG" . ,(operating-system-locale os))
724 ("TZ" . ,(operating-system-timezone os))
725 ("TZDIR" . ,(file-append tzdata "/share/zoneinfo"))
726 ;; Tell 'modprobe' & co. where to look for modules.
727 ("LINUX_MODULE_DIRECTORY" . "/run/booted-system/kernel/lib/modules")
728 ;; These variables are honored by OpenSSL (libssl) and Git.
729 ("SSL_CERT_DIR" . "/etc/ssl/certs")
730 ("SSL_CERT_FILE" . "/etc/ssl/certs/ca-certificates.crt")
731 ("GIT_SSL_CAINFO" . "/etc/ssl/certs/ca-certificates.crt")
733 ;; 'GTK_DATA_PREFIX' must name one directory where GTK+ themes are
735 ("GTK_DATA_PREFIX" . "/run/current-system/profile")
737 ;; By default, applications that use D-Bus, such as Emacs, abort at startup
738 ;; when /etc/machine-id is missing. Make sure these warnings are non-fatal.
739 ("DBUS_FATAL_WARNINGS" . "0")
741 ;; XXX: Normally we wouldn't need to do this, but our glibc@2.23 package
742 ;; used to look things up in 'PREFIX/lib/locale' instead of
743 ;; '/run/current-system/locale' as was intended. Keep this hack around so
744 ;; that people who still have glibc@2.23-using packages in their profiles
745 ;; can use them correctly.
746 ;; TODO: Remove when glibc@2.23 is long gone.
747 ("GUIX_LOCPATH" . "/run/current-system/locale")))
749 (define %setuid-programs
750 ;; Default set of setuid-root programs.
751 (let ((shadow (@ (gnu packages admin) shadow)))
752 (list (file-append shadow "/bin/passwd")
753 (file-append shadow "/bin/su")
754 (file-append shadow "/bin/newuidmap")
755 (file-append shadow "/bin/newgidmap")
756 (file-append inetutils "/bin/ping")
757 (file-append inetutils "/bin/ping6")
758 (file-append sudo "/bin/sudo")
759 (file-append fuse "/bin/fusermount"))))
761 (define %sudoers-specification
762 ;; Default /etc/sudoers contents: 'root' and all members of the 'wheel'
763 ;; group can do anything. See
764 ;; <http://www.sudo.ws/sudo/man/1.8.10/sudoers.man.html>.
765 ;; TODO: Add a declarative API.
766 (plain-file "sudoers" "\
768 %wheel ALL=(ALL) ALL\n"))
770 (define* (operating-system-activation-script os #:key container?)
771 "Return the activation script for OS---i.e., the code that \"activates\" the
772 stateful part of OS, including user accounts and groups, special directories,
774 (let* ((services (operating-system-services os #:container? container?))
775 (activation (fold-services services
776 #:target-type activation-service-type)))
777 (activation-service->script activation)))
779 (define* (operating-system-boot-script os #:key container?)
780 "Return the boot script for OS---i.e., the code started by the initrd once
781 we're running in the final root. When CONTAINER? is true, skip all
782 hardware-related operations as necessary when booting a Linux container."
783 (let* ((services (operating-system-services os #:container? container?))
784 (boot (fold-services services #:target-type boot-service-type)))
785 ;; BOOT is the script as a monadic value.
786 (service-value boot)))
788 (define (operating-system-user-accounts os)
789 "Return the list of user accounts of OS."
790 (let* ((services (operating-system-services os))
791 (account (fold-services services
792 #:target-type account-service-type)))
793 (filter user-account?
794 (service-value account))))
796 (define (operating-system-shepherd-service-names os)
797 "Return the list of Shepherd service names for OS."
798 (append-map shepherd-service-provision
800 (fold-services (operating-system-services os)
802 shepherd-root-service-type))))
804 (define* (operating-system-derivation os #:key container?)
805 "Return a derivation that builds OS."
806 (let* ((services (operating-system-services os #:container? container?))
807 (system (fold-services services)))
808 ;; SYSTEM contains the derivation as a monadic value.
809 (service-value system)))
811 (define* (operating-system-profile os #:key container?)
812 "Return a derivation that builds the system profile of OS."
814 ((services -> (operating-system-services os #:container? container?))
815 (profile (fold-services services
816 #:target-type profile-service-type)))
821 (define (operating-system-root-file-system os)
822 "Return the root file system of OS."
824 (($ <file-system> device title "/") #t)
826 (operating-system-file-systems os)))
828 (define (operating-system-initrd-file os)
829 "Return a gexp denoting the initrd file of OS."
830 (define boot-file-systems
831 (filter file-system-needed-for-boot?
832 (operating-system-file-systems os)))
834 (define mapped-devices
835 (operating-system-boot-mapped-devices os))
838 (operating-system-initrd os))
840 (mlet %store-monad ((initrd (make-initrd boot-file-systems
841 #:linux (operating-system-kernel os)
842 #:mapped-devices mapped-devices)))
843 (return (file-append initrd "/initrd"))))
845 (define (locale-name->definition* name)
846 "Variant of 'locale-name->definition' that raises an error upon failure."
847 (match (locale-name->definition name)
851 (message (format #f (G_ "~a: invalid locale name") name))))))
854 (define (operating-system-locale-directory os)
855 "Return the directory containing the locales compiled for the definitions
856 listed in OS. The C library expects to find it under
857 /run/current-system/locale."
859 (operating-system-locale os))
862 ;; While we're at it, check whether NAME is defined and add it if needed.
863 (if (member name (map locale-definition-name
864 (operating-system-locale-definitions os)))
865 (operating-system-locale-definitions os)
866 (cons (locale-name->definition* name)
867 (operating-system-locale-definitions os))))
869 (locale-directory definitions
870 #:libcs (operating-system-locale-libcs os)))
872 (define (kernel->boot-label kernel)
873 "Return a label for the bootloader menu entry that boots KERNEL."
874 (string-append "GNU with "
875 (string-titlecase (package-name kernel)) " "
876 (package-version kernel)
879 (define (store-file-system file-systems)
880 "Return the file system object among FILE-SYSTEMS that contains the store."
881 (match (filter (lambda (fs)
882 (and (file-system-mount? fs)
883 (not (memq 'bind-mount (file-system-flags fs)))
884 (string-prefix? (file-system-mount-point fs)
887 ((and candidates (head . tail))
888 (reduce (lambda (fs1 fs2)
889 (if (> (string-length (file-system-mount-point fs1))
890 (string-length (file-system-mount-point fs2)))
896 (define (operating-system-store-file-system os)
897 "Return the file system that contains the store of OS."
898 (store-file-system (operating-system-file-systems os)))
900 (define* (operating-system-bootcfg os #:optional (old-entries '()))
901 "Return the bootloader configuration file for OS. Use OLD-ENTRIES
902 (which is a list of <menu-entry>) to populate the \"old entries\" menu."
904 ((system (operating-system-derivation os))
905 (root-fs -> (operating-system-root-file-system os))
906 (root-device -> (file-system-device root-fs))
907 (params (operating-system-boot-parameters os system root-device))
908 (entry -> (boot-parameters->menu-entry params))
909 (bootloader-conf -> (operating-system-bootloader os)))
910 ((bootloader-configuration-file-generator
911 (bootloader-configuration-bootloader bootloader-conf))
912 bootloader-conf (list entry) #:old-entries old-entries)))
914 (define (fs->boot-device fs)
915 "Given FS, a <file-system> object, return a value suitable for use as the
916 device in a <menu-entry>."
917 (case (file-system-title fs)
918 ((uuid label device) (file-system-device fs))
921 (define (operating-system-boot-parameters os system.drv root-device)
922 "Return a monadic <boot-parameters> record that describes the boot parameters
923 of OS. SYSTEM.DRV is either a derivation or #f. If it's a derivation, adds
924 kernel arguments for that derivation to <boot-parameters>."
926 ((initrd (operating-system-initrd-file os))
927 (store -> (operating-system-store-file-system os))
928 (bootloader -> (bootloader-configuration-bootloader
929 (operating-system-bootloader os)))
930 (bootloader-name -> (bootloader-name bootloader))
931 (label -> (kernel->boot-label (operating-system-kernel os))))
932 (return (boot-parameters
934 (root-device root-device)
935 (kernel (operating-system-kernel-file os))
938 (operating-system-kernel-arguments os system.drv root-device)
939 (operating-system-user-kernel-arguments os)))
941 (bootloader-name bootloader-name)
942 (store-device (fs->boot-device store))
943 (store-mount-point (file-system-mount-point store))))))
945 (define (device->sexp device)
946 "Serialize DEVICE as an sexp (really, as an object with a read syntax.)"
949 `(uuid ,(uuid-type uuid) ,(uuid-bytevector uuid)))
953 (define* (operating-system-boot-parameters-file os #:optional (system.drv #f))
954 "Return a file that describes the boot parameters of OS. The primary use of
955 this file is the reconstruction of GRUB menu entries for old configurations.
956 SYSTEM.DRV is optional. If given, adds kernel arguments for that system to the
957 returned file (since the returned file is then usually stored into the
958 content-addressed \"system\" directory, it's usually not a good idea
959 to give it because the content hash would change by the content hash
960 being stored into the \"parameters\" file)."
961 (mlet* %store-monad ((root -> (operating-system-root-file-system os))
962 (device -> (file-system-device root))
963 (params (operating-system-boot-parameters os
966 (gexp->file "parameters"
969 (label #$(boot-parameters-label params))
972 (boot-parameters-root-device params)))
973 (kernel #$(boot-parameters-kernel params))
975 #$(boot-parameters-kernel-arguments params))
976 (initrd #$(boot-parameters-initrd params))
977 (bootloader-name #$(boot-parameters-bootloader-name params))
980 #$(device->sexp (boot-parameters-store-device params)))
981 (mount-point #$(boot-parameters-store-mount-point params))))
982 #:set-load-path? #f)))
984 (define-gexp-compiler (operating-system-compiler (os <operating-system>)
988 ;; XXX: This is not super elegant but we can't pass SYSTEM and TARGET to
989 ;; 'operating-system-derivation'.
990 (run-with-store store (operating-system-derivation os)
994 ;;; system.scm ends here