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