bootloader: Add bootloader name to boot-parameters record.
[jackhill/guix/guix.git] / gnu / system.scm
CommitLineData
033adfe7 1;;; GNU Guix --- Functional package management for GNU
a43aca97 2;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
5e738ac2 3;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
5dccaffe 4;;; Copyright © 2015, 2016 Alex Kost <alezost@gmail.com>
1ef8b72a 5;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com>
c76b3046 6;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
033adfe7
LC
7;;;
8;;; This file is part of GNU Guix.
9;;;
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.
14;;;
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.
19;;;
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/>.
22
23(define-module (gnu system)
24 #:use-module (guix store)
25 #:use-module (guix monads)
02100028 26 #:use-module (guix gexp)
033adfe7
LC
27 #:use-module (guix records)
28 #:use-module (guix packages)
29 #:use-module (guix derivations)
29fce8b6 30 #:use-module (guix profiles)
84765839 31 #:use-module (guix ui)
033adfe7
LC
32 #:use-module (gnu packages base)
33 #:use-module (gnu packages bash)
bdb36958 34 #:use-module (gnu packages guile)
9de46ffb 35 #:use-module (gnu packages admin)
8a07c289 36 #:use-module (gnu packages linux)
a96a82d7 37 #:use-module (gnu packages pciutils)
033adfe7 38 #:use-module (gnu packages package-management)
6f436c54
LC
39 #:use-module (gnu packages less)
40 #:use-module (gnu packages zile)
55e70e65
LC
41 #:use-module (gnu packages nano)
42 #:use-module (gnu packages lsof)
a68c6967 43 #:use-module (gnu packages gawk)
18316d86 44 #:use-module (gnu packages man)
939c5c31 45 #:use-module (gnu packages texinfo)
a68c6967 46 #:use-module (gnu packages compression)
f34c56be 47 #:use-module (gnu packages firmware)
db4fdc04 48 #:use-module (gnu services)
0190c1c0 49 #:use-module (gnu services shepherd)
db4fdc04 50 #:use-module (gnu services base)
b09a8da4 51 #:use-module (gnu bootloader)
033adfe7 52 #:use-module (gnu system shadow)
996ed739 53 #:use-module (gnu system nss)
598e19dc 54 #:use-module (gnu system locale)
6e828634 55 #:use-module (gnu system pam)
735c6dd7 56 #:use-module (gnu system linux-initrd)
c5df1839 57 #:use-module (gnu system file-systems)
060d62a7 58 #:use-module (gnu system mapped-devices)
033adfe7
LC
59 #:use-module (ice-9 match)
60 #:use-module (srfi srfi-1)
61 #:use-module (srfi srfi-26)
598e19dc
LC
62 #:use-module (srfi srfi-34)
63 #:use-module (srfi srfi-35)
3382bfe9 64 #:use-module (rnrs bytevectors)
033adfe7
LC
65 #:export (operating-system
66 operating-system?
d5b429ab
LC
67
68 operating-system-bootloader
033adfe7 69 operating-system-services
217a5b85 70 operating-system-user-services
033adfe7 71 operating-system-packages
fd3bfc44 72 operating-system-host-name
c65e1834 73 operating-system-hosts-file
fd3bfc44 74 operating-system-kernel
44d5f54e 75 operating-system-kernel-file
33f0aa88 76 operating-system-kernel-arguments
fd3bfc44
LC
77 operating-system-initrd
78 operating-system-users
79 operating-system-groups
548d4c13 80 operating-system-issue
fd3bfc44
LC
81 operating-system-timezone
82 operating-system-locale
598e19dc 83 operating-system-locale-definitions
34760ae7 84 operating-system-locale-libcs
5dae0186 85 operating-system-mapped-devices
83bcd0b8 86 operating-system-file-systems
6b779207 87 operating-system-store-file-system
2bdd7ac1
LC
88 operating-system-user-mapped-devices
89 operating-system-boot-mapped-devices
b25937e3 90 operating-system-activation-script
b2fef041
LC
91 operating-system-user-accounts
92 operating-system-shepherd-service-names
033adfe7 93
1aa0033b 94 operating-system-derivation
83bcd0b8 95 operating-system-profile
c76b3046 96 operating-system-bootcfg
239db054
DT
97 operating-system-etc-directory
98 operating-system-locale-directory
99 operating-system-boot-script
100
43fe431c
DC
101 system-linux-image-file-name
102
b8300494
AK
103 boot-parameters
104 boot-parameters?
105 boot-parameters-label
106 boot-parameters-root-device
bcaf67c4 107 boot-parameters-boot-name
1ef8b72a
CM
108 boot-parameters-store-device
109 boot-parameters-store-mount-point
b8300494
AK
110 boot-parameters-kernel
111 boot-parameters-kernel-arguments
d7b342d8 112 boot-parameters-initrd
4e4e0185 113 read-boot-parameters
9530e73b 114 read-boot-parameters-file
b8300494 115
568841d4 116 local-host-aliases
df5ce088 117 %setuid-programs
5dae0186 118 %base-packages
374f14c2 119 %base-firmware))
033adfe7
LC
120
121;;; Commentary:
122;;;
123;;; This module supports whole-system configuration.
124;;;
125;;; Code:
126
33f0aa88
DM
127(define (bootable-kernel-arguments kernel-arguments system.drv root-device)
128 "Prepend extra arguments to KERNEL-ARGUMENTS that allow SYSTEM.DRV to be
129booted from ROOT-DEVICE"
130 (cons* (string-append "--root=" root-device)
131 #~(string-append "--system=" #$system.drv)
132 #~(string-append "--load=" #$system.drv "/boot")
133 kernel-arguments))
134
033adfe7
LC
135;; System-wide configuration.
136;; TODO: Add per-field docstrings/stexi.
137(define-record-type* <operating-system> operating-system
138 make-operating-system
139 operating-system?
140 (kernel operating-system-kernel ; package
57082417 141 (default linux-libre))
af98d25a 142 (kernel-arguments operating-system-user-kernel-arguments
ee2a6304 143 (default '())) ; list of gexps/strings
b09a8da4 144 (bootloader operating-system-bootloader) ; <bootloader-configuration>
d5b429ab 145
83bcd0b8 146 (initrd operating-system-initrd ; (list fs) -> M derivation
060238ae 147 (default base-initrd))
f34c56be
LC
148 (firmware operating-system-firmware ; list of packages
149 (default %base-firmware))
033adfe7
LC
150
151 (host-name operating-system-host-name) ; string
24e02c28 152 (hosts-file operating-system-hosts-file ; file-like | #f
c65e1834 153 (default #f))
033adfe7 154
5dae0186
LC
155 (mapped-devices operating-system-mapped-devices ; list of <mapped-device>
156 (default '()))
8a6d2731 157 (file-systems operating-system-file-systems) ; list of fs
2a13d05e
LC
158 (swap-devices operating-system-swap-devices ; list of strings
159 (default '()))
033adfe7
LC
160
161 (users operating-system-users ; list of user accounts
bf87f38a 162 (default %base-user-accounts))
033adfe7 163 (groups operating-system-groups ; list of user groups
773e956d 164 (default %base-groups))
033adfe7 165
40281c54
LC
166 (skeletons operating-system-skeletons ; list of name/monadic value
167 (default (default-skeletons)))
548d4c13
LC
168 (issue operating-system-issue ; string
169 (default %default-issue))
40281c54 170
033adfe7 171 (packages operating-system-packages ; list of (PACKAGE OUTPUT...)
6f436c54 172 (default %base-packages)) ; or just PACKAGE
033adfe7
LC
173
174 (timezone operating-system-timezone) ; string
8a6d2731 175 (locale operating-system-locale ; string
598e19dc
LC
176 (default "en_US.utf8"))
177 (locale-definitions operating-system-locale-definitions ; list of <locale-definition>
178 (default %default-locale-definitions))
34760ae7
LC
179 (locale-libcs operating-system-locale-libcs ; list of <packages>
180 (default %default-locale-libcs))
996ed739
LC
181 (name-service-switch operating-system-name-service-switch ; <name-service-switch>
182 (default %default-nss))
033adfe7 183
217a5b85 184 (services operating-system-user-services ; list of monadic services
09e028f4
LC
185 (default %base-services))
186
187 (pam-services operating-system-pam-services ; list of PAM services
188 (default (base-pam-services)))
189 (setuid-programs operating-system-setuid-programs
69689380 190 (default %setuid-programs)) ; list of string-valued gexps
033adfe7 191
f5a9ffa0
AK
192 (sudoers-file operating-system-sudoers-file ; file-like
193 (default %sudoers-specification)))
033adfe7 194
33f0aa88
DM
195(define (operating-system-kernel-arguments os system.drv root-device)
196 "Return all the kernel arguments, including the ones not specified
197directly by the user."
198 (bootable-kernel-arguments (operating-system-user-kernel-arguments os)
199 system.drv
200 root-device))
201
2717a89a 202\f
8e815c5b
LC
203;;;
204;;; Boot parameters
205;;;
206
207(define-record-type* <boot-parameters>
208 boot-parameters make-boot-parameters boot-parameters?
209 (label boot-parameters-label)
210 ;; Because we will use the 'store-device' to create the GRUB search command,
211 ;; the 'store-device' has slightly different semantics than 'root-device'.
212 ;; The 'store-device' can be a file system uuid, a file system label, or #f,
213 ;; but it cannot be a device path such as "/dev/sda3", since GRUB would not
214 ;; understand that. The 'root-device', on the other hand, corresponds
215 ;; exactly to the device field of the <file-system> object representing the
216 ;; OS's root file system, so it might be a device path like "/dev/sda3".
217 (root-device boot-parameters-root-device)
bcaf67c4 218 (boot-name boot-parameters-boot-name)
8e815c5b
LC
219 (store-device boot-parameters-store-device)
220 (store-mount-point boot-parameters-store-mount-point)
221 (kernel boot-parameters-kernel)
222 (kernel-arguments boot-parameters-kernel-arguments)
223 (initrd boot-parameters-initrd))
224
225(define (read-boot-parameters port)
226 "Read boot parameters from PORT and return the corresponding
227<boot-parameters> object or #f if the format is unrecognized."
228 (match (read port)
229 (('boot-parameters ('version 0)
230 ('label label) ('root-device root)
231 ('kernel linux)
232 rest ...)
233 (boot-parameters
234 (label label)
235 (root-device root)
236
bcaf67c4
MO
237 (boot-name
238 (match (assq 'boot-name rest)
239 ((_ args) args)
240 (#f 'grub))) ; for compatibility reasons.
241
8e815c5b
LC
242 ;; In the past, we would store the directory name of the kernel instead
243 ;; of the absolute file name of its image. Detect that and correct it.
244 (kernel (if (string=? linux (direct-store-path linux))
245 (string-append linux "/"
246 (system-linux-image-file-name))
247 linux))
248
249 (kernel-arguments
250 (match (assq 'kernel-arguments rest)
251 ((_ args) args)
252 (#f '()))) ;the old format
253
254 (initrd
255 (match (assq 'initrd rest)
256 (('initrd ('string-append directory file)) ;the old format
257 (string-append directory file))
258 (('initrd (? string? file))
259 file)))
260
261 (store-device
262 (match (assq 'store rest)
263 (('store ('device device) _ ...)
264 device)
265 (_ ;the old format
266 ;; Root might be a device path like "/dev/sda1", which is not a
267 ;; suitable GRUB device identifier.
268 (if (string-prefix? "/" root)
269 #f
270 root))))
271
272 (store-mount-point
273 (match (assq 'store rest)
274 (('store ('device _) ('mount-point mount-point) _ ...)
275 mount-point)
276 (_ ;the old format
277 "/")))))
278 (x ;unsupported format
279 (warning (G_ "unrecognized boot parameters for '~a'~%")
280 system)
281 #f)))
282
283(define (read-boot-parameters-file system)
284 "Read boot parameters from SYSTEM's (system or generation) \"parameters\"
285file and returns the corresponding <boot-parameters> object or #f if the
286format is unrecognized.
287The object has its kernel-arguments extended in order to make it bootable."
288 (let* ((file (string-append system "/parameters"))
289 (params (call-with-input-file file read-boot-parameters))
290 (root (boot-parameters-root-device params))
291 (root-device (if (bytevector? root)
292 (uuid->string root)
293 root))
294 (kernel-arguments (boot-parameters-kernel-arguments params)))
295 (if params
296 (boot-parameters
297 (inherit params)
298 (kernel-arguments (bootable-kernel-arguments kernel-arguments
299 system
300 root-device)))
301 #f)))
302\f
40281c54
LC
303;;;
304;;; Services.
305;;;
306
aa1145df
LC
307(define (non-boot-file-system-service os)
308 "Return the file system service for the file systems of OS that are not
309marked as 'needed-for-boot'."
023f391c 310 (define file-systems
4d6b879c 311 (remove file-system-needed-for-boot?
023f391c
LC
312 (operating-system-file-systems os)))
313
5dae0186 314 (define (device-mappings fs)
ab64483f 315 (let ((device (file-system-device fs)))
29824d80 316 (if (string? device) ;title is 'device
ab64483f
LC
317 (filter (lambda (md)
318 (string=? (string-append "/dev/mapper/"
319 (mapped-device-target md))
320 device))
321 (operating-system-mapped-devices os))
322 '())))
5dae0186 323
e502bf89
LC
324 (define (add-dependencies fs)
325 ;; Add the dependencies due to device mappings to FS.
326 (file-system
327 (inherit fs)
328 (dependencies
329 (delete-duplicates (append (device-mappings fs)
330 (file-system-dependencies fs))
331 eq?))))
332
aa1145df
LC
333 (service file-system-service-type
334 (map add-dependencies file-systems)))
023f391c 335
de1c158f
LC
336(define (mapped-device-user device file-systems)
337 "Return a file system among FILE-SYSTEMS that uses DEVICE, or #f."
338 (let ((target (string-append "/dev/mapper/" (mapped-device-target device))))
339 (find (lambda (fs)
2bdd7ac1
LC
340 (or (member device (file-system-dependencies fs))
341 (and (eq? 'device (file-system-title fs))
342 (string=? (file-system-device fs) target))))
de1c158f
LC
343 file-systems)))
344
345(define (operating-system-user-mapped-devices os)
346 "Return the subset of mapped devices that can be installed in
347user-land--i.e., those not needed during boot."
9cb426b8
LC
348 (let ((devices (operating-system-mapped-devices os))
349 (file-systems (operating-system-file-systems os)))
350 (filter (lambda (md)
351 (let ((user (mapped-device-user md file-systems)))
352 (or (not user)
353 (not (file-system-needed-for-boot? user)))))
354 devices)))
de1c158f
LC
355
356(define (operating-system-boot-mapped-devices os)
357 "Return the subset of mapped devices that must be installed during boot,
358from the initrd."
9cb426b8
LC
359 (let ((devices (operating-system-mapped-devices os))
360 (file-systems (operating-system-file-systems os)))
361 (filter (lambda (md)
362 (let ((user (mapped-device-user md file-systems)))
363 (and user (file-system-needed-for-boot? user))))
364 devices)))
de1c158f 365
5dae0186 366(define (device-mapping-services os)
be1c2c54 367 "Return the list of device-mapping services for OS as a list."
4da8c19e 368 (map device-mapping-service
be1c2c54 369 (operating-system-user-mapped-devices os)))
5dae0186 370
2a13d05e 371(define (swap-services os)
be1c2c54
LC
372 "Return the list of swap services for OS."
373 (map swap-service (operating-system-swap-devices os)))
2a13d05e 374
44d5f54e
LC
375(define* (system-linux-image-file-name #:optional (system (%current-system)))
376 "Return the basename of the kernel image file for SYSTEM."
377 ;; FIXME: Evaluate the conditional based on the actual current system.
43fe431c
DC
378 (cond
379 ((string-prefix? "arm" (%current-system)) "zImage")
380 ((string-prefix? "mips" (%current-system)) "vmlinuz")
381 (else "bzImage")))
44d5f54e
LC
382
383(define (operating-system-kernel-file os)
384 "Return an object representing the absolute file name of the kernel image of
385OS."
386 (file-append (operating-system-kernel os)
387 "/" (system-linux-image-file-name os)))
388
d62e201c
LC
389(define* (operating-system-directory-base-entries os #:key container?)
390 "Return the basic entries of the 'system' directory of OS for use as the
391value of the SYSTEM-SERVICE-TYPE service."
af4c3fd5 392 (mlet %store-monad ((locale (operating-system-locale-directory os)))
d62e201c 393 (if container?
af4c3fd5 394 (return `(("locale" ,locale)))
d62e201c
LC
395 (mlet %store-monad
396 ((kernel -> (operating-system-kernel os))
397 (initrd (operating-system-initrd-file os))
71d04202 398 (params (operating-system-boot-parameters-file os)))
d62e201c
LC
399 (return `(("kernel" ,kernel)
400 ("parameters" ,params)
401 ("initrd" ,initrd)
d62e201c
LC
402 ("locale" ,locale))))))) ;used by libc
403
0adfe95a 404(define* (essential-services os #:key container?)
217a5b85
LC
405 "Return the list of essential services for OS. These are special services
406that implement part of what's declared in OS are responsible for low-level
0adfe95a
LC
407bookkeeping. CONTAINER? determines whether to return the list of services for
408a container or that of a \"bare metal\" system."
d6e2a622
LC
409 (define known-fs
410 (map file-system-mount-point (operating-system-file-systems os)))
411
be1c2c54
LC
412 (let* ((mappings (device-mapping-services os))
413 (root-fs (root-file-system-service))
aa1145df 414 (other-fs (non-boot-file-system-service os))
be1c2c54
LC
415 (unmount (user-unmount-service known-fs))
416 (swaps (swap-services os))
a43aca97 417 (procs (user-processes-service))
d62e201c
LC
418 (host-name (host-name-service (operating-system-host-name os)))
419 (entries (operating-system-directory-base-entries
420 os #:container? container?)))
421 (cons* (service system-service-type entries)
422 %boot-service
0adfe95a 423
d4053c71
AK
424 ;; %SHEPHERD-ROOT-SERVICE must come first so that the gexp that
425 ;; execs shepherd comes last in the boot script (XXX). Likewise,
426 ;; the cleanup service must come last so that its gexp runs before
427 ;; activation code.
428 %shepherd-root-service
be7be9e8
LC
429 %activation-service
430 (service cleanup-service-type #f)
0adfe95a
LC
431
432 (pam-root-service (operating-system-pam-services os))
433 (account-service (append (operating-system-accounts os)
434 (operating-system-groups os))
435 (operating-system-skeletons os))
436 (operating-system-etc-service os)
e43e84ba 437 (service fstab-service-type '())
6bad7524
SB
438 (session-environment-service
439 (operating-system-environment-variables os))
0adfe95a
LC
440 host-name procs root-fs unmount
441 (service setuid-program-service-type
442 (operating-system-setuid-programs os))
af4c3fd5
LC
443 (service profile-service-type
444 (operating-system-packages os))
aa1145df
LC
445 other-fs
446 (append mappings swaps
0adfe95a
LC
447
448 ;; Add the firmware service, unless we are building for a
449 ;; container.
450 (if container?
451 '()
a241a7ac
LC
452 (list %linux-bare-metal-service
453 (service firmware-service-type
0adfe95a
LC
454 (operating-system-firmware os))))))))
455
456(define* (operating-system-services os #:key container?)
217a5b85
LC
457 "Return all the services of OS, including \"internal\" services that do not
458explicitly appear in OS."
be1c2c54 459 (append (operating-system-user-services os)
0adfe95a 460 (essential-services os #:container? container?)))
217a5b85 461
40281c54
LC
462\f
463;;;
464;;; /etc.
465;;;
466
f34c56be
LC
467(define %base-firmware
468 ;; Firmware usable by default.
52db41af
EB
469 (list ath9k-htc-firmware
470 openfwwf-firmware))
f34c56be 471
6f436c54
LC
472(define %base-packages
473 ;; Default set of packages globally visible. It should include anything
474 ;; required for basic administrator tasks.
55e70e65 475 (cons* procps psmisc which less zile nano
55e70e65 476 lsof ;for Guix's 'list-runtime-roots'
a96a82d7 477 pciutils usbutils
be681773
LC
478 util-linux inetutils isc-dhcp
479
480 ;; wireless-tools is deprecated in favor of iw, but it's still what
481 ;; many people are familiar with, so keep it around.
16cc9961 482 iw wireless-tools rfkill
be681773 483
5dccaffe 484 iproute
9b762b8d 485 net-tools ; XXX: remove when Inetutils suffices
18316d86 486 man-db
02683c33 487 info-reader ;the standalone Info reader (no Perl)
03e9998f 488
a8a086e3
LC
489 ;; The 'sudo' command is already in %SETUID-PROGRAMS, but we also
490 ;; want the other commands and the man pages (notably because
491 ;; auto-completion in Emacs shell relies on man pages.)
492 sudo
493
03e9998f
LC
494 ;; Get 'insmod' & co. from kmod, not module-init-tools, since udev
495 ;; already depends on it anyway.
255f7308 496 kmod eudev
03e9998f 497
b63dbd44 498 e2fsprogs kbd
9b762b8d 499
1d167b6e
LC
500 bash-completion
501
9b762b8d
LC
502 ;; The packages below are also in %FINAL-INPUTS, so take them from
503 ;; there to avoid duplication.
504 (map canonical-package
e162050d 505 (list guile-2.0 bash coreutils-8.27 findutils grep sed
4b164c45 506 diffutils patch gawk tar gzip bzip2 xz lzip))))
6f436c54 507
548d4c13
LC
508(define %default-issue
509 ;; Default contents for /etc/issue.
510 "
511This is the GNU system. Welcome.\n")
512
568841d4
LC
513(define (local-host-aliases host-name)
514 "Return aliases for HOST-NAME, to be used in /etc/hosts."
515 (string-append "127.0.0.1 localhost " host-name "\n"
516 "::1 localhost " host-name "\n"))
517
c65e1834
LC
518(define (default-/etc/hosts host-name)
519 "Return the default /etc/hosts file."
24e02c28 520 (plain-file "hosts" (local-host-aliases host-name)))
c65e1834 521
0adfe95a
LC
522(define* (operating-system-etc-service os)
523 "Return a <service> that builds containing the static part of the /etc
524directory."
525 (let ((login.defs (plain-file "login.defs" "# Empty for now.\n"))
526
0adfe95a
LC
527 (issue (plain-file "issue" (operating-system-issue os)))
528 (nsswitch (plain-file "nsswitch.conf"
529 (name-service-switch->string
530 (operating-system-name-service-switch os))))
531
532 ;; Startup file for POSIX-compliant login shells, which set system-wide
533 ;; environment variables.
534 (profile (mixed-text-file "profile" "\
c05c4321 535# Crucial variables that could be missing in the profiles' 'etc/profile'
d9959421
LC
536# because they would require combining both profiles.
537# FIXME: See <http://bugs.gnu.org/20255>.
97ab2c0f 538export MANPATH=$HOME/.guix-profile/share/man:/run/current-system/profile/share/man
95f92d4e 539export INFOPATH=$HOME/.guix-profile/share/info:/run/current-system/profile/share/info
00239d05
SB
540export XDG_DATA_DIRS=$HOME/.guix-profile/share:/run/current-system/profile/share
541export XDG_CONFIG_DIRS=$HOME/.guix-profile/etc/xdg:/run/current-system/profile/etc/xdg
542
d9959421
LC
543# Ignore the default value of 'PATH'.
544unset PATH
545
546# Load the system profile's settings.
547GUIX_PROFILE=/run/current-system/profile \\
669786da 548. /run/current-system/profile/etc/profile
d9959421
LC
549
550# Prepend setuid programs.
551export PATH=/run/setuid-programs:$PATH
552
cad7e6ab
CSLL
553# Since 'lshd' does not use pam_env, /etc/environment must be explicitly
554# loaded when someone logs in via SSH. See <http://bugs.gnu.org/22175>.
555# We need 'PATH' to be defined here, for 'cat' and 'cut'. Do this before
556# reading the user's 'etc/profile' to allow variables to be overridden.
557if [ -f /etc/environment -a -n \"$SSH_CLIENT\" \\
558 -a -z \"$LINUX_MODULE_DIRECTORY\" ]
559then
560 . /etc/environment
561 export `cat /etc/environment | cut -d= -f1`
562fi
563
507c71d6 564if [ -f \"$HOME/.guix-profile/etc/profile\" ]
d9959421
LC
565then
566 # Load the user profile's settings.
567 GUIX_PROFILE=\"$HOME/.guix-profile\" \\
669786da 568 . \"$HOME/.guix-profile/etc/profile\"
d9959421
LC
569else
570 # At least define this one so that basic things just work
571 # when the user installs their first package.
572 export PATH=\"$HOME/.guix-profile/bin:$PATH\"
573fi
574
11202482
LC
575# Set the umask, notably for users logging in via 'lsh'.
576# See <http://bugs.gnu.org/22650>.
577umask 022
2a5f0db4 578
4af7c83b
LC
579# Allow GStreamer-based applications to find plugins.
580export GST_PLUGIN_PATH=\"$HOME/.guix-profile/lib/gstreamer-1.0\"
581
1d167b6e
LC
582if [ -n \"$BASH_VERSION\" -a -f /etc/bashrc ]
583then
584 # Load Bash-specific initialization code.
669786da 585 . /etc/bashrc
1d167b6e 586fi
40281c54 587"))
1d167b6e 588
0adfe95a 589 (bashrc (plain-file "bashrc" "\
1d167b6e
LC
590# Bash-specific initialization.
591
592# The 'bash-completion' package.
593if [ -f /run/current-system/profile/etc/profile.d/bash_completion.sh ]
594then
595 # Bash-completion sources ~/.bash_completion. It installs a dynamic
596 # completion loader that searches its own completion files as well
597 # as those in ~/.guix-profile and /run/current-system/profile.
598 source /run/current-system/profile/etc/profile.d/bash_completion.sh
0adfe95a
LC
599fi\n")))
600 (etc-service
9e41130b
LC
601 `(("services" ,(file-append net-base "/etc/services"))
602 ("protocols" ,(file-append net-base "/etc/protocols"))
603 ("rpc" ,(file-append net-base "/etc/rpc"))
0adfe95a
LC
604 ("login.defs" ,#~#$login.defs)
605 ("issue" ,#~#$issue)
606 ("nsswitch.conf" ,#~#$nsswitch)
0adfe95a
LC
607 ("profile" ,#~#$profile)
608 ("bashrc" ,#~#$bashrc)
609 ("hosts" ,#~#$(or (operating-system-hosts-file os)
610 (default-/etc/hosts (operating-system-host-name os))))
9e41130b
LC
611 ("localtime" ,(file-append tzdata "/share/zoneinfo/"
612 (operating-system-timezone os)))
0adfe95a 613 ("sudoers" ,(operating-system-sudoers-file os))))))
033adfe7 614
ab6a279a
LC
615(define %root-account
616 ;; Default root account.
617 (user-account
618 (name "root")
619 (password "")
620 (uid 0) (group "root")
621 (comment "System administrator")
622 (home-directory "/root")))
623
0b6f49ef 624(define (operating-system-accounts os)
0adfe95a
LC
625 "Return the user accounts for OS, including an obligatory 'root' account,
626and excluding accounts requested by services."
627 ;; Make sure there's a root account.
628 (if (find (lambda (user)
629 (and=> (user-account-uid user) zero?))
630 (operating-system-users os))
631 (operating-system-users os)
632 (cons %root-account (operating-system-users os))))
0b6f49ef 633
84765839
LC
634(define (maybe-string->file file-name thing)
635 "If THING is a string, return a <plain-file> with THING as its content.
636Otherwise just return THING.
637
638This is for backward-compatibility of fields that used to be strings and are
639now file-like objects.."
640 (match thing
641 ((? string?)
69daee23 642 (warning (G_ "using a string for file '~a' is deprecated; \
84765839
LC
643use 'plain-file' instead~%")
644 file-name)
645 (plain-file file-name thing))
646 (x
647 x)))
648
24e02c28
LC
649(define (maybe-file->monadic file-name thing)
650 "If THING is a value in %STORE-MONAD, return it as is; otherwise return
651THING in the %STORE-MONAD.
652
653This is for backward-compatibility of fields that used to be monadic values
654and are now file-like objects."
655 (with-monad %store-monad
656 (match thing
657 ((? procedure?)
69daee23 658 (warning (G_ "using a monadic value for '~a' is deprecated; \
24e02c28
LC
659use 'plain-file' instead~%")
660 file-name)
661 thing)
662 (x
663 (return x)))))
664
0b6f49ef
LC
665(define (operating-system-etc-directory os)
666 "Return that static part of the /etc directory of OS."
0adfe95a
LC
667 (etc-directory
668 (fold-services (operating-system-services os)
669 #:target-type etc-service-type)))
033adfe7 670
6bad7524
SB
671(define (operating-system-environment-variables os)
672 "Return the environment variables of OS for
673@var{session-environment-service-type}, to be used in @file{/etc/environment}."
674 `(("LANG" . ,(operating-system-locale os))
675 ("TZ" . ,(operating-system-timezone os))
9e41130b 676 ("TZDIR" . ,(file-append tzdata "/share/zoneinfo"))
6bad7524
SB
677 ;; Tell 'modprobe' & co. where to look for modules.
678 ("LINUX_MODULE_DIRECTORY" . "/run/booted-system/kernel/lib/modules")
679 ;; These variables are honored by OpenSSL (libssl) and Git.
680 ("SSL_CERT_DIR" . "/etc/ssl/certs")
681 ("SSL_CERT_FILE" . "/etc/ssl/certs/ca-certificates.crt")
682 ("GIT_SSL_CAINFO" . "/etc/ssl/certs/ca-certificates.crt")
ae05e366
LC
683
684 ;; 'GTK_DATA_PREFIX' must name one directory where GTK+ themes are
685 ;; searched for.
686 ("GTK_DATA_PREFIX" . "/run/current-system/profile")
687
6bad7524
SB
688 ;; By default, applications that use D-Bus, such as Emacs, abort at startup
689 ;; when /etc/machine-id is missing. Make sure these warnings are non-fatal.
946465bb
LC
690 ("DBUS_FATAL_WARNINGS" . "0")
691
692 ;; XXX: Normally we wouldn't need to do this, but our glibc@2.23 package
693 ;; used to look things up in 'PREFIX/lib/locale' instead of
694 ;; '/run/current-system/locale' as was intended. Keep this hack around so
695 ;; that people who still have glibc@2.23-using packages in their profiles
696 ;; can use them correctly.
697 ;; TODO: Remove when glibc@2.23 is long gone.
698 ("GUIX_LOCPATH" . "/run/current-system/locale")))
6bad7524 699
09e028f4
LC
700(define %setuid-programs
701 ;; Default set of setuid-root programs.
3b65abac 702 (let ((shadow (@ (gnu packages admin) shadow)))
9e41130b
LC
703 (list (file-append shadow "/bin/passwd")
704 (file-append shadow "/bin/su")
705 (file-append inetutils "/bin/ping")
706 (file-append inetutils "/bin/ping6")
707 (file-append sudo "/bin/sudo")
708 (file-append fuse "/bin/fusermount"))))
69689380
LC
709
710(define %sudoers-specification
711 ;; Default /etc/sudoers contents: 'root' and all members of the 'wheel'
712 ;; group can do anything. See
713 ;; <http://www.sudo.ws/sudo/man/1.8.10/sudoers.man.html>.
714 ;; TODO: Add a declarative API.
84765839
LC
715 (plain-file "sudoers" "\
716root ALL=(ALL) ALL
717%wheel ALL=(ALL) ALL\n"))
09e028f4 718
239db054 719(define* (operating-system-activation-script os #:key container?)
484a2b3a
LC
720 "Return the activation script for OS---i.e., the code that \"activates\" the
721stateful part of OS, including user accounts and groups, special directories,
722etc."
0adfe95a
LC
723 (let* ((services (operating-system-services os #:container? container?))
724 (activation (fold-services services
725 #:target-type activation-service-type)))
726 (activation-service->script activation)))
484a2b3a 727
239db054 728(define* (operating-system-boot-script os #:key container?)
484a2b3a 729 "Return the boot script for OS---i.e., the code started by the initrd once
239db054
DT
730we're running in the final root. When CONTAINER? is true, skip all
731hardware-related operations as necessary when booting a Linux container."
0adfe95a 732 (let* ((services (operating-system-services os #:container? container?))
d62e201c 733 (boot (fold-services services #:target-type boot-service-type)))
0adfe95a 734 ;; BOOT is the script as a monadic value.
efe7d19a 735 (service-value boot)))
2106d3fc 736
b2fef041
LC
737(define (operating-system-user-accounts os)
738 "Return the list of user accounts of OS."
739 (let* ((services (operating-system-services os))
740 (account (fold-services services
741 #:target-type account-service-type)))
742 (filter user-account?
efe7d19a 743 (service-value account))))
b2fef041
LC
744
745(define (operating-system-shepherd-service-names os)
746 "Return the list of Shepherd service names for OS."
747 (append-map shepherd-service-provision
efe7d19a 748 (service-value
b2fef041
LC
749 (fold-services (operating-system-services os)
750 #:target-type
751 shepherd-root-service-type))))
752
d62e201c
LC
753(define* (operating-system-derivation os #:key container?)
754 "Return a derivation that builds OS."
755 (let* ((services (operating-system-services os #:container? container?))
756 (system (fold-services services)))
757 ;; SYSTEM contains the derivation as a monadic value.
efe7d19a 758 (service-value system)))
d62e201c 759
af4c3fd5
LC
760(define* (operating-system-profile os #:key container?)
761 "Return a derivation that builds the system profile of OS."
762 (mlet* %store-monad
763 ((services -> (operating-system-services os #:container? container?))
764 (profile (fold-services services
765 #:target-type profile-service-type)))
766 (match profile
767 (("profile" profile)
768 (return profile)))))
769
83bcd0b8
LC
770(define (operating-system-root-file-system os)
771 "Return the root file system of OS."
772 (find (match-lambda
856be823
LC
773 (($ <file-system> device title "/") #t)
774 (x #f))
83bcd0b8
LC
775 (operating-system-file-systems os)))
776
b4140694
LC
777(define (operating-system-initrd-file os)
778 "Return a gexp denoting the initrd file of OS."
83bcd0b8 779 (define boot-file-systems
4d6b879c 780 (filter file-system-needed-for-boot?
83bcd0b8
LC
781 (operating-system-file-systems os)))
782
de1c158f
LC
783 (define mapped-devices
784 (operating-system-boot-mapped-devices os))
785
786 (define make-initrd
787 (operating-system-initrd os))
788
789 (mlet %store-monad ((initrd (make-initrd boot-file-systems
0d275f4a 790 #:linux (operating-system-kernel os)
de1c158f 791 #:mapped-devices mapped-devices)))
ab20d74a 792 (return (file-append initrd "/initrd"))))
b4140694 793
f5582b2c
LC
794(define (locale-name->definition* name)
795 "Variant of 'locale-name->definition' that raises an error upon failure."
796 (match (locale-name->definition name)
797 (#f
798 (raise (condition
799 (&message
69daee23 800 (message (format #f (G_ "~a: invalid locale name") name))))))
f5582b2c
LC
801 (def def)))
802
598e19dc
LC
803(define (operating-system-locale-directory os)
804 "Return the directory containing the locales compiled for the definitions
805listed in OS. The C library expects to find it under
806/run/current-system/locale."
f5582b2c
LC
807 (define name
808 (operating-system-locale os))
809
810 (define definitions
811 ;; While we're at it, check whether NAME is defined and add it if needed.
812 (if (member name (map locale-definition-name
813 (operating-system-locale-definitions os)))
814 (operating-system-locale-definitions os)
815 (cons (locale-name->definition* name)
816 (operating-system-locale-definitions os))))
817
818 (locale-directory definitions
34760ae7 819 #:libcs (operating-system-locale-libcs os)))
598e19dc 820
c2e9942b
MO
821(define (kernel->boot-label kernel)
822 "Return a label for the bootloader menu entry that boots KERNEL."
42de9608 823 (string-append "GNU with "
2d23e6f0
LC
824 (string-titlecase (package-name kernel)) " "
825 (package-version kernel)
d0a65256 826 " (beta)"))
2d23e6f0 827
6b779207
LC
828(define (store-file-system file-systems)
829 "Return the file system object among FILE-SYSTEMS that contains the store."
830 (match (filter (lambda (fs)
831 (and (file-system-mount? fs)
832 (not (memq 'bind-mount (file-system-flags fs)))
833 (string-prefix? (file-system-mount-point fs)
834 (%store-prefix))))
835 file-systems)
836 ((and candidates (head . tail))
837 (reduce (lambda (fs1 fs2)
838 (if (> (string-length (file-system-mount-point fs1))
839 (string-length (file-system-mount-point fs2)))
840 fs1
841 fs2))
842 head
843 candidates))))
844
845(define (operating-system-store-file-system os)
846 "Return the file system that contains the store of OS."
847 (store-file-system (operating-system-file-systems os)))
848
c76b3046
MO
849(define* (operating-system-bootcfg os #:optional (old-entries '()))
850 "Return the bootloader configuration file for OS. Use OLD-ENTRIES to
851populate the \"old entries\" menu."
0b6f49ef 852 (mlet* %store-monad
b4140694 853 ((system (operating-system-derivation os))
83bcd0b8 854 (root-fs -> (operating-system-root-file-system os))
f453f637
LC
855 (root-device -> (if (eq? 'uuid (file-system-title root-fs))
856 (uuid->string (file-system-device root-fs))
857 (file-system-device root-fs)))
b09a8da4
MO
858 (entry (operating-system-boot-parameters os system root-device))
859 (bootloader-conf -> (operating-system-bootloader os)))
860 ((bootloader-configuration-file-generator
861 (bootloader-configuration-bootloader bootloader-conf))
862 bootloader-conf (list entry) #:old-entries old-entries)))
b4140694 863
7085ca96 864(define (fs->boot-device fs)
3382bfe9
CM
865 "Given FS, a <file-system> object, return a value suitable for use as the
866device in a <menu-entry>."
867 (case (file-system-title fs)
868 ((uuid) (file-system-device fs))
869 ((label) (file-system-device fs))
870 (else #f)))
871
360874dd
DM
872(define (operating-system-boot-parameters os system.drv root-device)
873 "Return a monadic <boot-parameters> record that describes the boot parameters
874of OS. SYSTEM.DRV is either a derivation or #f. If it's a derivation, adds
875kernel arguments for that derivation to <boot-parameters>."
40fad1c2
DM
876 (mlet* %store-monad
877 ((initrd (operating-system-initrd-file os))
878 (store -> (operating-system-store-file-system os))
bcaf67c4
MO
879 (bootloader -> (bootloader-configuration-bootloader
880 (operating-system-bootloader os)))
881 (boot-name -> (bootloader-name bootloader))
40fad1c2
DM
882 (label -> (kernel->boot-label (operating-system-kernel os))))
883 (return (boot-parameters
884 (label label)
885 (root-device root-device)
886 (kernel (operating-system-kernel-file os))
887 (kernel-arguments
360874dd
DM
888 (if system.drv
889 (operating-system-kernel-arguments os system.drv root-device)
890 (operating-system-user-kernel-arguments os)))
40fad1c2 891 (initrd initrd)
bcaf67c4 892 (boot-name boot-name)
40fad1c2
DM
893 (store-device (fs->boot-device store))
894 (store-mount-point (file-system-mount-point store))))))
895
896(define* (operating-system-boot-parameters-file os #:optional (system.drv #f))
897 "Return a file that describes the boot parameters of OS. The primary use of
898this file is the reconstruction of GRUB menu entries for old configurations.
899SYSTEM.DRV is optional. If given, adds kernel arguments for that system to the
900returned file (since the returned file is then usually stored into the
901content-addressed \"system\" directory, it's usually not a good idea
902to give it because the content hash would change by the content hash
903being stored into the \"parameters\" file)."
904 (mlet* %store-monad ((root -> (operating-system-root-file-system os))
905 (device -> (file-system-device root))
906 (params (operating-system-boot-parameters os
907 system.drv
908 device)))
909 (gexp->file "parameters"
910 #~(boot-parameters
911 (version 0)
912 (label #$(boot-parameters-label params))
913 (root-device #$(boot-parameters-root-device params))
914 (kernel #$(boot-parameters-kernel params))
915 (kernel-arguments
916 #$(boot-parameters-kernel-arguments params))
917 (initrd #$(boot-parameters-initrd params))
bcaf67c4 918 (boot-name #$(boot-parameters-boot-name params))
40fad1c2
DM
919 (store
920 (device #$(boot-parameters-store-device params))
921 (mount-point #$(boot-parameters-store-mount-point params))))
922 #:set-load-path? #f)))
64e40dbb 923
033adfe7 924;;; system.scm ends here