gnu: gnupg: Update to 2.2.25.
[jackhill/guix/guix.git] / gnu / services / base.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2015, 2016 Alex Kost <alezost@gmail.com>
4 ;;; Copyright © 2015, 2016, 2020 Mark H Weaver <mhw@netris.org>
5 ;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
6 ;;; Copyright © 2016, 2017 Leo Famulari <leo@famulari.name>
7 ;;; Copyright © 2016 David Craven <david@craven.ch>
8 ;;; Copyright © 2016 Ricardo Wurmus <rekado@elephly.net>
9 ;;; Copyright © 2018 Mathieu Othacehe <m.othacehe@gmail.com>
10 ;;; Copyright © 2019 Efraim Flashner <efraim@flashner.co.il>
11 ;;; Copyright © 2019 Tobias Geerinckx-Rice <me@tobias.gr>
12 ;;; Copyright © 2019 John Soo <jsoo1@asu.edu>
13 ;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
14 ;;; Copyright © 2020 Florian Pelz <pelzflorian@pelzflorian.de>
15 ;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
16 ;;;
17 ;;; This file is part of GNU Guix.
18 ;;;
19 ;;; GNU Guix is free software; you can redistribute it and/or modify it
20 ;;; under the terms of the GNU General Public License as published by
21 ;;; the Free Software Foundation; either version 3 of the License, or (at
22 ;;; your option) any later version.
23 ;;;
24 ;;; GNU Guix is distributed in the hope that it will be useful, but
25 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
26 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 ;;; GNU General Public License for more details.
28 ;;;
29 ;;; You should have received a copy of the GNU General Public License
30 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
31
32 (define-module (gnu services base)
33 #:use-module (guix store)
34 #:use-module (guix deprecation)
35 #:use-module (gnu services)
36 #:use-module (gnu services admin)
37 #:use-module (gnu services shepherd)
38 #:use-module (gnu system pam)
39 #:use-module (gnu system shadow) ; 'user-account', etc.
40 #:use-module (gnu system uuid)
41 #:use-module (gnu system file-systems) ; 'file-system', etc.
42 #:use-module (gnu system mapped-devices)
43 #:use-module ((gnu system linux-initrd)
44 #:select (file-system-packages))
45 #:use-module (gnu packages admin)
46 #:use-module ((gnu packages linux)
47 #:select (alsa-utils crda eudev e2fsprogs fuse gpm kbd lvm2 rng-tools))
48 #:use-module (gnu packages bash)
49 #:use-module ((gnu packages base)
50 #:select (coreutils glibc glibc-utf8-locales))
51 #:use-module (gnu packages package-management)
52 #:use-module ((gnu packages gnupg) #:select (guile-gcrypt))
53 #:use-module (gnu packages linux)
54 #:use-module (gnu packages terminals)
55 #:use-module ((gnu build file-systems)
56 #:select (mount-flags->bit-mask))
57 #:use-module (guix gexp)
58 #:use-module (guix records)
59 #:use-module (guix modules)
60 #:use-module ((guix self) #:select (make-config.scm))
61 #:use-module (srfi srfi-1)
62 #:use-module (srfi srfi-26)
63 #:use-module (ice-9 match)
64 #:use-module (ice-9 format)
65 #:re-export (user-processes-service-type ;backwards compatibility
66 %default-substitute-urls)
67 #:export (fstab-service-type
68 root-file-system-service
69 file-system-service-type
70 swap-service
71 host-name-service
72 console-keymap-service
73 %default-console-font
74 console-font-service-type
75 console-font-service
76 virtual-terminal-service-type
77
78 static-networking
79
80 static-networking?
81 static-networking-interface
82 static-networking-ip
83 static-networking-netmask
84 static-networking-gateway
85 static-networking-requirement
86
87 static-networking-service
88 static-networking-service-type
89
90 udev-configuration
91 udev-configuration?
92 udev-configuration-rules
93 udev-service-type
94 udev-service
95 udev-rule
96 file->udev-rule
97 udev-rules-service
98
99 login-configuration
100 login-configuration?
101 login-service-type
102 login-service
103
104 agetty-configuration
105 agetty-configuration?
106 agetty-service
107 agetty-service-type
108
109 mingetty-configuration
110 mingetty-configuration-tty
111 mingetty-configuration-auto-login
112 mingetty-configuration-login-program
113 mingetty-configuration-login-pause?
114 mingetty-configuration-clear-on-logout?
115 mingetty-configuration-mingetty
116 mingetty-configuration?
117 mingetty-service
118 mingetty-service-type
119
120 %nscd-default-caches
121 %nscd-default-configuration
122
123 nscd-configuration
124 nscd-configuration?
125
126 nscd-cache
127 nscd-cache?
128
129 nscd-service-type
130 nscd-service
131
132 syslog-configuration
133 syslog-configuration?
134 syslog-service
135 syslog-service-type
136 %default-syslog.conf
137
138 %default-authorized-guix-keys
139 guix-configuration
140 guix-configuration?
141
142 guix-configuration-guix
143 guix-configuration-build-group
144 guix-configuration-build-accounts
145 guix-configuration-authorize-key?
146 guix-configuration-authorized-keys
147 guix-configuration-use-substitutes?
148 guix-configuration-substitute-urls
149 guix-configuration-extra-options
150 guix-configuration-log-file
151
152 guix-service
153 guix-service-type
154 guix-publish-configuration
155 guix-publish-configuration?
156 guix-publish-configuration-guix
157 guix-publish-configuration-port
158 guix-publish-configuration-host
159 guix-publish-configuration-compression
160 guix-publish-configuration-compression-level ;deprecated
161 guix-publish-configuration-nar-path
162 guix-publish-configuration-cache
163 guix-publish-configuration-ttl
164 guix-publish-service
165 guix-publish-service-type
166
167 gpm-configuration
168 gpm-configuration?
169 gpm-service-type
170 gpm-service
171
172 urandom-seed-service-type
173 urandom-seed-service
174
175 rngd-configuration
176 rngd-configuration?
177 rngd-service-type
178 rngd-service
179
180 kmscon-configuration
181 kmscon-configuration?
182 kmscon-service-type
183
184 pam-limits-service-type
185 pam-limits-service
186
187 references-file
188
189 %base-services))
190
191 ;;; Commentary:
192 ;;;
193 ;;; Base system services---i.e., services that 99% of the users will want to
194 ;;; use.
195 ;;;
196 ;;; Code:
197
198
199 \f
200 ;;;
201 ;;; File systems.
202 ;;;
203
204 (define (file-system->fstab-entry file-system)
205 "Return a @file{/etc/fstab} entry for @var{file-system}."
206 (string-append (match (file-system-device file-system)
207 ((? file-system-label? label)
208 (string-append "LABEL="
209 (file-system-label->string label)))
210 ((? uuid? uuid)
211 (string-append "UUID=" (uuid->string uuid)))
212 ((? string? device)
213 device))
214 "\t"
215 (file-system-mount-point file-system) "\t"
216 (file-system-type file-system) "\t"
217 (or (file-system-options file-system) "defaults") "\t"
218
219 ;; XXX: Omit the 'fs_freq' and 'fs_passno' fields because we
220 ;; don't have anything sensible to put in there.
221 ))
222
223 (define (file-systems->fstab file-systems)
224 "Return a @file{/etc} entry for an @file{fstab} describing
225 @var{file-systems}."
226 `(("fstab" ,(plain-file "fstab"
227 (string-append
228 "\
229 # This file was generated from your Guix configuration. Any changes
230 # will be lost upon reboot or reconfiguration.\n\n"
231 (string-join (map file-system->fstab-entry
232 file-systems)
233 "\n")
234 "\n")))))
235
236 (define fstab-service-type
237 ;; The /etc/fstab service.
238 (service-type (name 'fstab)
239 (extensions
240 (list (service-extension etc-service-type
241 file-systems->fstab)))
242 (compose concatenate)
243 (extend append)
244 (description
245 "Populate the @file{/etc/fstab} based on the given file
246 system objects.")))
247
248 (define %root-file-system-shepherd-service
249 (shepherd-service
250 (documentation "Take care of the root file system.")
251 (provision '(root-file-system))
252 (start #~(const #t))
253 (stop #~(lambda _
254 ;; Return #f if successfully stopped.
255 (sync)
256
257 (call-with-blocked-asyncs
258 (lambda ()
259 (let ((null (%make-void-port "w")))
260 ;; Close 'shepherd.log'.
261 (display "closing log\n")
262 ((@ (shepherd comm) stop-logging))
263
264 ;; Redirect the default output ports..
265 (set-current-output-port null)
266 (set-current-error-port null)
267
268 ;; Close /dev/console.
269 (for-each close-fdes '(0 1 2))
270
271 ;; At this point, there are no open files left, so the
272 ;; root file system can be re-mounted read-only.
273 (mount #f "/" #f
274 (logior MS_REMOUNT MS_RDONLY)
275 #:update-mtab? #f)
276
277 #f)))))
278 (respawn? #f)))
279
280 (define root-file-system-service-type
281 (shepherd-service-type 'root-file-system
282 (const %root-file-system-shepherd-service)))
283
284 (define (root-file-system-service)
285 "Return a service whose sole purpose is to re-mount read-only the root file
286 system upon shutdown (aka. cleanly \"umounting\" root.)
287
288 This service must be the root of the service dependency graph so that its
289 'stop' action is invoked when shepherd is the only process left."
290 (service root-file-system-service-type #f))
291
292 (define (file-system->shepherd-service-name file-system)
293 "Return the symbol that denotes the service mounting and unmounting
294 FILE-SYSTEM."
295 (symbol-append 'file-system-
296 (string->symbol (file-system-mount-point file-system))))
297
298 (define (mapped-device->shepherd-service-name md)
299 "Return the symbol that denotes the shepherd service of MD, a <mapped-device>."
300 (symbol-append 'device-mapping-
301 (string->symbol (mapped-device-target md))))
302
303 (define dependency->shepherd-service-name
304 (match-lambda
305 ((? mapped-device? md)
306 (mapped-device->shepherd-service-name md))
307 ((? file-system? fs)
308 (file-system->shepherd-service-name fs))))
309
310 (define (file-system-shepherd-service file-system)
311 "Return the shepherd service for @var{file-system}, or @code{#f} if
312 @var{file-system} is not auto-mounted upon boot."
313 (let ((target (file-system-mount-point file-system))
314 (create? (file-system-create-mount-point? file-system))
315 (dependencies (file-system-dependencies file-system))
316 (packages (file-system-packages (list file-system))))
317 (and (file-system-mount? file-system)
318 (with-imported-modules (source-module-closure
319 '((gnu build file-systems)))
320 (shepherd-service
321 (provision (list (file-system->shepherd-service-name file-system)))
322 (requirement `(root-file-system udev
323 ,@(map dependency->shepherd-service-name dependencies)))
324 (documentation "Check, mount, and unmount the given file system.")
325 (start #~(lambda args
326 #$(if create?
327 #~(mkdir-p #$target)
328 #t)
329
330 (let (($PATH (getenv "PATH")))
331 ;; Make sure fsck.ext2 & co. can be found.
332 (dynamic-wind
333 (lambda ()
334 ;; Don’t display the PATH settings.
335 (with-output-to-port (%make-void-port "w")
336 (lambda ()
337 (set-path-environment-variable "PATH"
338 '("bin" "sbin")
339 '#$packages))))
340 (lambda ()
341 (mount-file-system
342 (spec->file-system
343 '#$(file-system->spec file-system))
344 #:root "/"))
345 (lambda ()
346 (setenv "PATH" $PATH)))
347 #t)))
348 (stop #~(lambda args
349 ;; Normally there are no processes left at this point, so
350 ;; TARGET can be safely unmounted.
351
352 ;; Make sure PID 1 doesn't keep TARGET busy.
353 (chdir "/")
354
355 (umount #$target)
356 #f))
357
358 ;; We need additional modules.
359 (modules `(((gnu build file-systems)
360 #:select (mount-file-system))
361 (gnu system file-systems)
362 ,@%default-modules)))))))
363
364 (define (file-system-shepherd-services file-systems)
365 "Return the list of Shepherd services for FILE-SYSTEMS."
366 (let* ((file-systems (filter file-system-mount? file-systems)))
367 (define sink
368 (shepherd-service
369 (provision '(file-systems))
370 (requirement (cons* 'root-file-system 'user-file-systems
371 (map file-system->shepherd-service-name
372 file-systems)))
373 (documentation "Target for all the initially-mounted file systems")
374 (start #~(const #t))
375 (stop #~(const #f))))
376
377 (define known-mount-points
378 (map file-system-mount-point file-systems))
379
380 (define user-unmount
381 (shepherd-service
382 (documentation "Unmount manually-mounted file systems.")
383 (provision '(user-file-systems))
384 (start #~(const #t))
385 (stop #~(lambda args
386 (define (known? mount-point)
387 (member mount-point
388 (cons* "/proc" "/sys" '#$known-mount-points)))
389
390 ;; Make sure we don't keep the user's mount points busy.
391 (chdir "/")
392
393 (for-each (lambda (mount-point)
394 (format #t "unmounting '~a'...~%" mount-point)
395 (catch 'system-error
396 (lambda ()
397 (umount mount-point))
398 (lambda args
399 (let ((errno (system-error-errno args)))
400 (format #t "failed to unmount '~a': ~a~%"
401 mount-point (strerror errno))))))
402 (filter (negate known?) (mount-points)))
403 #f))))
404
405 (cons* sink user-unmount
406 (map file-system-shepherd-service file-systems))))
407
408 (define (file-system-fstab-entries file-systems)
409 "Return the subset of @var{file-systems} that should have an entry in
410 @file{/etc/fstab}."
411 ;; /etc/fstab is about telling fsck(8), mount(8), and umount(8) about
412 ;; relevant file systems they'll have to deal with. That excludes "pseudo"
413 ;; file systems.
414 ;;
415 ;; In particular, things like GIO (part of GLib) use it to determine the set
416 ;; of mounts, which is then used by graphical file managers and desktop
417 ;; environments to display "volume" icons. Thus, we really need to exclude
418 ;; those pseudo file systems from the list.
419 (remove (lambda (file-system)
420 (or (member (file-system-type file-system)
421 %pseudo-file-system-types)
422 (memq 'bind-mount (file-system-flags file-system))))
423 file-systems))
424
425 (define file-system-service-type
426 (service-type (name 'file-systems)
427 (extensions
428 (list (service-extension shepherd-root-service-type
429 file-system-shepherd-services)
430 (service-extension fstab-service-type
431 file-system-fstab-entries)
432
433 ;; Have 'user-processes' depend on 'file-systems'.
434 (service-extension user-processes-service-type
435 (const '(file-systems)))))
436 (compose concatenate)
437 (extend append)
438 (description
439 "Provide Shepherd services to mount and unmount the given
440 file systems, as well as corresponding @file{/etc/fstab} entries.")))
441
442
443 \f
444 ;;;
445 ;;; Preserve entropy to seed /dev/urandom on boot.
446 ;;;
447
448 (define %random-seed-file
449 "/var/lib/random-seed")
450
451 (define (urandom-seed-shepherd-service _)
452 "Return a shepherd service for the /dev/urandom seed."
453 (list (shepherd-service
454 (documentation "Preserve entropy across reboots for /dev/urandom.")
455 (provision '(urandom-seed))
456
457 ;; Depend on udev so that /dev/hwrng is available.
458 (requirement '(file-systems udev))
459
460 (start #~(lambda _
461 ;; On boot, write random seed into /dev/urandom.
462 (when (file-exists? #$%random-seed-file)
463 (call-with-input-file #$%random-seed-file
464 (lambda (seed)
465 (call-with-output-file "/dev/urandom"
466 (lambda (urandom)
467 (dump-port seed urandom)
468
469 ;; Writing SEED to URANDOM isn't enough: we must
470 ;; also tell the kernel to account for these
471 ;; extra bits of entropy.
472 (let ((bits (* 8 (stat:size (stat seed)))))
473 (add-to-entropy-count urandom bits)))))))
474
475 ;; Try writing from /dev/hwrng into /dev/urandom.
476 ;; It seems that the file /dev/hwrng always exists, even
477 ;; when there is no hardware random number generator
478 ;; available. So, we handle a failed read or any other error
479 ;; reported by the operating system.
480 (let ((buf (catch 'system-error
481 (lambda ()
482 (call-with-input-file "/dev/hwrng"
483 (lambda (hwrng)
484 (get-bytevector-n hwrng 512))))
485 ;; Silence is golden...
486 (const #f))))
487 (when buf
488 (call-with-output-file "/dev/urandom"
489 (lambda (urandom)
490 (put-bytevector urandom buf)
491 (let ((bits (* 8 (bytevector-length buf))))
492 (add-to-entropy-count urandom bits))))))
493
494 ;; Immediately refresh the seed in case the system doesn't
495 ;; shut down cleanly.
496 (call-with-input-file "/dev/urandom"
497 (lambda (urandom)
498 (let ((previous-umask (umask #o077))
499 (buf (make-bytevector 512)))
500 (mkdir-p (dirname #$%random-seed-file))
501 (get-bytevector-n! urandom buf 0 512)
502 (call-with-output-file #$%random-seed-file
503 (lambda (seed)
504 (put-bytevector seed buf)))
505 (umask previous-umask))))
506 #t))
507 (stop #~(lambda _
508 ;; During shutdown, write from /dev/urandom into random seed.
509 (let ((buf (make-bytevector 512)))
510 (call-with-input-file "/dev/urandom"
511 (lambda (urandom)
512 (let ((previous-umask (umask #o077)))
513 (get-bytevector-n! urandom buf 0 512)
514 (mkdir-p (dirname #$%random-seed-file))
515 (call-with-output-file #$%random-seed-file
516 (lambda (seed)
517 (put-bytevector seed buf)))
518 (umask previous-umask))
519 #t)))))
520 (modules `((rnrs bytevectors)
521 (rnrs io ports)
522 ,@%default-modules)))))
523
524 (define urandom-seed-service-type
525 (service-type (name 'urandom-seed)
526 (extensions
527 (list (service-extension shepherd-root-service-type
528 urandom-seed-shepherd-service)
529
530 ;; Have 'user-processes' depend on 'urandom-seed'.
531 ;; This ensures that user processes and daemons don't
532 ;; start until we have seeded the PRNG.
533 (service-extension user-processes-service-type
534 (const '(urandom-seed)))))
535 (default-value #f)
536 (description
537 "Seed the @file{/dev/urandom} pseudo-random number
538 generator (RNG) with the value recorded when the system was last shut
539 down.")))
540
541 (define-deprecated (urandom-seed-service)
542 urandom-seed-service-type
543 (service urandom-seed-service-type))
544
545
546 ;;;
547 ;;; Add hardware random number generator to entropy pool.
548 ;;;
549
550 (define-record-type* <rngd-configuration>
551 rngd-configuration make-rngd-configuration
552 rngd-configuration?
553 (rng-tools rngd-configuration-rng-tools) ;package
554 (device rngd-configuration-device)) ;string
555
556 (define rngd-service-type
557 (shepherd-service-type
558 'rngd
559 (lambda (config)
560 (define rng-tools (rngd-configuration-rng-tools config))
561 (define device (rngd-configuration-device config))
562
563 (define rngd-command
564 (list (file-append rng-tools "/sbin/rngd")
565 "-f" "-r" device))
566
567 (shepherd-service
568 (documentation "Add TRNG to entropy pool.")
569 (requirement '(udev))
570 (provision '(trng))
571 (start #~(make-forkexec-constructor '#$rngd-command))
572 (stop #~(make-kill-destructor))))))
573
574 (define* (rngd-service #:key
575 (rng-tools rng-tools)
576 (device "/dev/hwrng"))
577 "Return a service that runs the @command{rngd} program from @var{rng-tools}
578 to add @var{device} to the kernel's entropy pool. The service will fail if
579 @var{device} does not exist."
580 (service rngd-service-type
581 (rngd-configuration
582 (rng-tools rng-tools)
583 (device device))))
584
585 \f
586 ;;;
587 ;;; Console & co.
588 ;;;
589
590 (define host-name-service-type
591 (shepherd-service-type
592 'host-name
593 (lambda (name)
594 (shepherd-service
595 (documentation "Initialize the machine's host name.")
596 (provision '(host-name))
597 (start #~(lambda _
598 (sethostname #$name)))
599 (one-shot? #t)))))
600
601 (define (host-name-service name)
602 "Return a service that sets the host name to @var{name}."
603 (service host-name-service-type name))
604
605 (define virtual-terminal-service-type
606 ;; Ensure that virtual terminals run in UTF-8 mode. This is the case by
607 ;; default with recent Linux kernels, but this service allows us to ensure
608 ;; this. This service must start before any 'term-' service so that newly
609 ;; created terminals inherit this property. See
610 ;; <https://bugs.gnu.org/30505> for a discussion.
611 (shepherd-service-type
612 'virtual-terminal
613 (lambda (utf8?)
614 (let ((knob "/sys/module/vt/parameters/default_utf8"))
615 (shepherd-service
616 (documentation "Set virtual terminals in UTF-8 module.")
617 (provision '(virtual-terminal))
618 (requirement '(root-file-system))
619 (start #~(lambda _
620 ;; In containers /sys is read-only so don't insist on
621 ;; writing to this file.
622 (unless (= 1 (call-with-input-file #$knob read))
623 (call-with-output-file #$knob
624 (lambda (port)
625 (display 1 port))))
626 #t))
627 (stop #~(const #f)))))
628 #t)) ;default to UTF-8
629
630 (define console-keymap-service-type
631 (shepherd-service-type
632 'console-keymap
633 (lambda (files)
634 (shepherd-service
635 (documentation (string-append "Load console keymap (loadkeys)."))
636 (provision '(console-keymap))
637 (start #~(lambda _
638 (zero? (system* #$(file-append kbd "/bin/loadkeys")
639 #$@files))))
640 (respawn? #f)))))
641
642 (define-deprecated (console-keymap-service #:rest files)
643 #f
644 "Return a service to load console keymaps from @var{files}."
645 (service console-keymap-service-type files))
646
647 (define %default-console-font
648 ;; Note: 'LatGrkCyr-8x16' has the advantage of providing three common
649 ;; scripts as well as glyphs for em dash, quotation marks, and other Unicode
650 ;; codepoints notably found in the UTF-8 manual.
651 "LatGrkCyr-8x16")
652
653 (define (console-font-shepherd-services tty+font)
654 "Return a list of Shepherd services for each pair in TTY+FONT."
655 (map (match-lambda
656 ((tty . font)
657 (let ((device (string-append "/dev/" tty)))
658 (shepherd-service
659 (documentation "Load a Unicode console font.")
660 (provision (list (symbol-append 'console-font-
661 (string->symbol tty))))
662
663 ;; Start after mingetty has been started on TTY, otherwise the settings
664 ;; are ignored.
665 (requirement (list (symbol-append 'term-
666 (string->symbol tty))))
667
668 (start #~(lambda _
669 ;; It could be that mingetty is not fully ready yet,
670 ;; which we check by calling 'ttyname'.
671 (let loop ((i 10))
672 (unless (or (zero? i)
673 (call-with-input-file #$device
674 (lambda (port)
675 (false-if-exception (ttyname port)))))
676 (usleep 500)
677 (loop (- i 1))))
678
679 ;; Assume the VT is already in UTF-8 mode, thanks to
680 ;; the 'virtual-terminal' service.
681 ;;
682 ;; 'setfont' returns EX_OSERR (71) when an
683 ;; KDFONTOP ioctl fails, for example. Like
684 ;; systemd's vconsole support, let's not treat
685 ;; this as an error.
686 (case (status:exit-val
687 (system* #$(file-append kbd "/bin/setfont")
688 "-C" #$device #$font))
689 ((0 71) #t)
690 (else #f))))
691 (stop #~(const #t))
692 (respawn? #f)))))
693 tty+font))
694
695 (define console-font-service-type
696 (service-type (name 'console-fonts)
697 (extensions
698 (list (service-extension shepherd-root-service-type
699 console-font-shepherd-services)))
700 (compose concatenate)
701 (extend append)
702 (description
703 "Install the given fonts on the specified ttys (fonts are per
704 virtual console on GNU/Linux). The value of this service is a list of
705 tty/font pairs. The font can be the name of a font provided by the @code{kbd}
706 package or any valid argument to @command{setfont}, as in this example:
707
708 @example
709 `((\"tty1\" . \"LatGrkCyr-8x16\")
710 (\"tty2\" . ,(file-append
711 font-tamzen
712 \"/share/kbd/consolefonts/TamzenForPowerline10x20.psf\"))
713 (\"tty3\" . ,(file-append
714 font-terminus
715 \"/share/consolefonts/ter-132n\"))) ; for HDPI
716 @end example\n")))
717
718 (define* (console-font-service tty #:optional (font "LatGrkCyr-8x16"))
719 "This procedure is deprecated in favor of @code{console-font-service-type}.
720
721 Return a service that sets up Unicode support in @var{tty} and loads
722 @var{font} for that tty (fonts are per virtual console in Linux.)"
723 (simple-service (symbol-append 'console-font- (string->symbol tty))
724 console-font-service-type `((,tty . ,font))))
725
726 (define %default-motd
727 (plain-file "motd" "This is the GNU operating system, welcome!\n\n"))
728
729 (define-record-type* <login-configuration>
730 login-configuration make-login-configuration
731 login-configuration?
732 (motd login-configuration-motd ;file-like
733 (default %default-motd))
734 ;; Allow empty passwords by default so that first-time users can log in when
735 ;; the 'root' account has just been created.
736 (allow-empty-passwords? login-configuration-allow-empty-passwords?
737 (default #t))) ;Boolean
738
739 (define (login-pam-service config)
740 "Return the list of PAM service needed for CONF."
741 ;; Let 'login' be known to PAM.
742 (list (unix-pam-service "login"
743 #:login-uid? #t
744 #:allow-empty-passwords?
745 (login-configuration-allow-empty-passwords? config)
746 #:motd
747 (login-configuration-motd config))))
748
749 (define login-service-type
750 (service-type (name 'login)
751 (extensions (list (service-extension pam-root-service-type
752 login-pam-service)))
753 (default-value (login-configuration))
754 (description
755 "Provide a console log-in service as specified by its
756 configuration value, a @code{login-configuration} object.")))
757
758 (define* (login-service #:optional (config (login-configuration)))
759 "Return a service configure login according to @var{config}, which specifies
760 the message of the day, among other things."
761 (service login-service-type config))
762
763 (define-record-type* <agetty-configuration>
764 agetty-configuration make-agetty-configuration
765 agetty-configuration?
766 (agetty agetty-configuration-agetty ;<package>
767 (default util-linux))
768 (tty agetty-configuration-tty) ;string | #f
769 (term agetty-term ;string | #f
770 (default #f))
771 (baud-rate agetty-baud-rate ;string | #f
772 (default #f))
773 (auto-login agetty-auto-login ;list of strings | #f
774 (default #f))
775 (login-program agetty-login-program ;gexp
776 (default (file-append shadow "/bin/login")))
777 (login-pause? agetty-login-pause? ;Boolean
778 (default #f))
779 (eight-bits? agetty-eight-bits? ;Boolean
780 (default #f))
781 (no-reset? agetty-no-reset? ;Boolean
782 (default #f))
783 (remote? agetty-remote? ;Boolean
784 (default #f))
785 (flow-control? agetty-flow-control? ;Boolean
786 (default #f))
787 (host agetty-host ;string | #f
788 (default #f))
789 (no-issue? agetty-no-issue? ;Boolean
790 (default #f))
791 (init-string agetty-init-string ;string | #f
792 (default #f))
793 (no-clear? agetty-no-clear? ;Boolean
794 (default #f))
795 (local-line agetty-local-line ;always | never | auto
796 (default #f))
797 (extract-baud? agetty-extract-baud? ;Boolean
798 (default #f))
799 (skip-login? agetty-skip-login? ;Boolean
800 (default #f))
801 (no-newline? agetty-no-newline? ;Boolean
802 (default #f))
803 (login-options agetty-login-options ;string | #f
804 (default #f))
805 (chroot agetty-chroot ;string | #f
806 (default #f))
807 (hangup? agetty-hangup? ;Boolean
808 (default #f))
809 (keep-baud? agetty-keep-baud? ;Boolean
810 (default #f))
811 (timeout agetty-timeout ;integer | #f
812 (default #f))
813 (detect-case? agetty-detect-case? ;Boolean
814 (default #f))
815 (wait-cr? agetty-wait-cr? ;Boolean
816 (default #f))
817 (no-hints? agetty-no-hints? ;Boolean
818 (default #f))
819 (no-hostname? agetty-no hostname? ;Boolean
820 (default #f))
821 (long-hostname? agetty-long-hostname? ;Boolean
822 (default #f))
823 (erase-characters agetty-erase-characters ;string | #f
824 (default #f))
825 (kill-characters agetty-kill-characters ;string | #f
826 (default #f))
827 (chdir agetty-chdir ;string | #f
828 (default #f))
829 (delay agetty-delay ;integer | #f
830 (default #f))
831 (nice agetty-nice ;integer | #f
832 (default #f))
833 ;; "Escape hatch" for passing arbitrary command-line arguments.
834 (extra-options agetty-extra-options ;list of strings
835 (default '()))
836 ;;; XXX Unimplemented for now!
837 ;;; (issue-file agetty-issue-file ;file-like
838 ;;; (default #f))
839 )
840
841 (define (default-serial-port)
842 "Return a gexp that determines a reasonable default serial port
843 to use as the tty. This is primarily useful for headless systems."
844 (with-imported-modules (source-module-closure
845 '((gnu build linux-boot))) ;for 'find-long-options'
846 #~(begin
847 ;; console=device,options
848 ;; device: can be tty0, ttyS0, lp0, ttyUSB0 (serial).
849 ;; options: BBBBPNF. P n|o|e, N number of bits,
850 ;; F flow control (r RTS)
851 (let* ((not-comma (char-set-complement (char-set #\,)))
852 (command (linux-command-line))
853 (agetty-specs (find-long-options "agetty.tty" command))
854 (console-specs (filter (lambda (spec)
855 (and (string-prefix? "tty" spec)
856 (not (or
857 (string-prefix? "tty0" spec)
858 (string-prefix? "tty1" spec)
859 (string-prefix? "tty2" spec)
860 (string-prefix? "tty3" spec)
861 (string-prefix? "tty4" spec)
862 (string-prefix? "tty5" spec)
863 (string-prefix? "tty6" spec)
864 (string-prefix? "tty7" spec)
865 (string-prefix? "tty8" spec)
866 (string-prefix? "tty9" spec)))))
867 (find-long-options "console" command)))
868 (specs (append agetty-specs console-specs)))
869 (match specs
870 (() #f)
871 ((spec _ ...)
872 ;; Extract device name from first spec.
873 (match (string-tokenize spec not-comma)
874 ((device-name _ ...)
875 device-name))))))))
876
877 (define agetty-shepherd-service
878 (match-lambda
879 (($ <agetty-configuration> agetty tty term baud-rate auto-login
880 login-program login-pause? eight-bits? no-reset? remote? flow-control?
881 host no-issue? init-string no-clear? local-line extract-baud?
882 skip-login? no-newline? login-options chroot hangup? keep-baud? timeout
883 detect-case? wait-cr? no-hints? no-hostname? long-hostname?
884 erase-characters kill-characters chdir delay nice extra-options)
885 (list
886 (shepherd-service
887 (documentation "Run agetty on a tty.")
888 (provision (list (symbol-append 'term- (string->symbol (or tty "auto")))))
889
890 ;; Since the login prompt shows the host name, wait for the 'host-name'
891 ;; service to be done. Also wait for udev essentially so that the tty
892 ;; text is not lost in the middle of kernel messages (see also
893 ;; mingetty-shepherd-service).
894 (requirement '(user-processes host-name udev))
895
896 (modules '((ice-9 match) (gnu build linux-boot)))
897 (start
898 (with-imported-modules (source-module-closure
899 '((gnu build linux-boot)))
900 #~(lambda args
901 (let ((defaulted-tty #$(or tty (default-serial-port))))
902 (apply
903 (if defaulted-tty
904 (make-forkexec-constructor
905 (list #$(file-append util-linux "/sbin/agetty")
906 #$@extra-options
907 #$@(if eight-bits?
908 #~("--8bits")
909 #~())
910 #$@(if no-reset?
911 #~("--noreset")
912 #~())
913 #$@(if remote?
914 #~("--remote")
915 #~())
916 #$@(if flow-control?
917 #~("--flow-control")
918 #~())
919 #$@(if host
920 #~("--host" #$host)
921 #~())
922 #$@(if no-issue?
923 #~("--noissue")
924 #~())
925 #$@(if init-string
926 #~("--init-string" #$init-string)
927 #~())
928 #$@(if no-clear?
929 #~("--noclear")
930 #~())
931 ;;; FIXME This doesn't work as expected. According to agetty(8), if this option
932 ;;; is not passed, then the default is 'auto'. However, in my tests, when that
933 ;;; option is selected, agetty never presents the login prompt, and the
934 ;;; term-ttyS0 service respawns every few seconds.
935 #$@(if local-line
936 #~(#$(match local-line
937 ('auto "--local-line=auto")
938 ('always "--local-line=always")
939 ('never "-local-line=never")))
940 #~())
941 #$@(if tty
942 #~()
943 #~("--keep-baud"))
944 #$@(if extract-baud?
945 #~("--extract-baud")
946 #~())
947 #$@(if skip-login?
948 #~("--skip-login")
949 #~())
950 #$@(if no-newline?
951 #~("--nonewline")
952 #~())
953 #$@(if login-options
954 #~("--login-options" #$login-options)
955 #~())
956 #$@(if chroot
957 #~("--chroot" #$chroot)
958 #~())
959 #$@(if hangup?
960 #~("--hangup")
961 #~())
962 #$@(if keep-baud?
963 #~("--keep-baud")
964 #~())
965 #$@(if timeout
966 #~("--timeout" #$(number->string timeout))
967 #~())
968 #$@(if detect-case?
969 #~("--detect-case")
970 #~())
971 #$@(if wait-cr?
972 #~("--wait-cr")
973 #~())
974 #$@(if no-hints?
975 #~("--nohints?")
976 #~())
977 #$@(if no-hostname?
978 #~("--nohostname")
979 #~())
980 #$@(if long-hostname?
981 #~("--long-hostname")
982 #~())
983 #$@(if erase-characters
984 #~("--erase-chars" #$erase-characters)
985 #~())
986 #$@(if kill-characters
987 #~("--kill-chars" #$kill-characters)
988 #~())
989 #$@(if chdir
990 #~("--chdir" #$chdir)
991 #~())
992 #$@(if delay
993 #~("--delay" #$(number->string delay))
994 #~())
995 #$@(if nice
996 #~("--nice" #$(number->string nice))
997 #~())
998 #$@(if auto-login
999 (list "--autologin" auto-login)
1000 '())
1001 #$@(if login-program
1002 #~("--login-program" #$login-program)
1003 #~())
1004 #$@(if login-pause?
1005 #~("--login-pause")
1006 #~())
1007 defaulted-tty
1008 #$@(if baud-rate
1009 #~(#$baud-rate)
1010 #~())
1011 #$@(if term
1012 #~(#$term)
1013 #~())))
1014 (const #f)) ; never start.
1015 args)))))
1016 (stop #~(make-kill-destructor)))))))
1017
1018 (define agetty-service-type
1019 (service-type (name 'agetty)
1020 (extensions (list (service-extension shepherd-root-service-type
1021 agetty-shepherd-service)))
1022 (description
1023 "Provide console login using the @command{agetty}
1024 program.")))
1025
1026 (define* (agetty-service config)
1027 "Return a service to run agetty according to @var{config}, which specifies
1028 the tty to run, among other things."
1029 (service agetty-service-type config))
1030
1031 (define-record-type* <mingetty-configuration>
1032 mingetty-configuration make-mingetty-configuration
1033 mingetty-configuration?
1034 (mingetty mingetty-configuration-mingetty ;<package>
1035 (default mingetty))
1036 (tty mingetty-configuration-tty) ;string
1037 (auto-login mingetty-auto-login ;string | #f
1038 (default #f))
1039 (login-program mingetty-login-program ;gexp
1040 (default #f))
1041 (login-pause? mingetty-login-pause? ;Boolean
1042 (default #f))
1043 (clear-on-logout? mingetty-clear-on-logout? ;Boolean
1044 (default #t)))
1045
1046 (define mingetty-shepherd-service
1047 (match-lambda
1048 (($ <mingetty-configuration> mingetty tty auto-login login-program
1049 login-pause? clear-on-logout?)
1050 (list
1051 (shepherd-service
1052 (documentation "Run mingetty on an tty.")
1053 (provision (list (symbol-append 'term- (string->symbol tty))))
1054
1055 ;; Since the login prompt shows the host name, wait for the 'host-name'
1056 ;; service to be done. Also wait for udev essentially so that the tty
1057 ;; text is not lost in the middle of kernel messages (XXX).
1058 (requirement '(user-processes host-name udev virtual-terminal))
1059
1060 (start #~(make-forkexec-constructor
1061 (list #$(file-append mingetty "/sbin/mingetty")
1062
1063 ;; Avoiding 'vhangup' allows us to avoid 'setfont'
1064 ;; errors down the path where various ioctls get
1065 ;; EIO--see 'hung_up_tty_ioctl' in driver/tty/tty_io.c
1066 ;; in Linux.
1067 "--nohangup" #$tty
1068
1069 #$@(if clear-on-logout?
1070 #~()
1071 #~("--noclear"))
1072 #$@(if auto-login
1073 #~("--autologin" #$auto-login)
1074 #~())
1075 #$@(if login-program
1076 #~("--loginprog" #$login-program)
1077 #~())
1078 #$@(if login-pause?
1079 #~("--loginpause")
1080 #~()))))
1081 (stop #~(make-kill-destructor)))))))
1082
1083 (define mingetty-service-type
1084 (service-type (name 'mingetty)
1085 (extensions (list (service-extension shepherd-root-service-type
1086 mingetty-shepherd-service)))
1087 (description
1088 "Provide console login using the @command{mingetty}
1089 program.")))
1090
1091 (define* (mingetty-service config)
1092 "Return a service to run mingetty according to @var{config}, which specifies
1093 the tty to run, among other things."
1094 (service mingetty-service-type config))
1095
1096 (define-record-type* <nscd-configuration> nscd-configuration
1097 make-nscd-configuration
1098 nscd-configuration?
1099 (log-file nscd-configuration-log-file ;string
1100 (default "/var/log/nscd.log"))
1101 (debug-level nscd-debug-level ;integer
1102 (default 0))
1103 ;; TODO: See nscd.conf in glibc for other options to add.
1104 (caches nscd-configuration-caches ;list of <nscd-cache>
1105 (default %nscd-default-caches))
1106 (name-services nscd-configuration-name-services ;list of <packages>
1107 (default '()))
1108 (glibc nscd-configuration-glibc ;<package>
1109 (default glibc)))
1110
1111 (define-record-type* <nscd-cache> nscd-cache make-nscd-cache
1112 nscd-cache?
1113 (database nscd-cache-database) ;symbol
1114 (positive-time-to-live nscd-cache-positive-time-to-live) ;integer
1115 (negative-time-to-live nscd-cache-negative-time-to-live
1116 (default 20)) ;integer
1117 (suggested-size nscd-cache-suggested-size ;integer ("default module
1118 ;of hash table")
1119 (default 211))
1120 (check-files? nscd-cache-check-files? ;Boolean
1121 (default #t))
1122 (persistent? nscd-cache-persistent? ;Boolean
1123 (default #t))
1124 (shared? nscd-cache-shared? ;Boolean
1125 (default #t))
1126 (max-database-size nscd-cache-max-database-size ;integer
1127 (default (* 32 (expt 2 20))))
1128 (auto-propagate? nscd-cache-auto-propagate? ;Boolean
1129 (default #t)))
1130
1131 (define %nscd-default-caches
1132 ;; Caches that we want to enable by default. Note that when providing an
1133 ;; empty nscd.conf, all caches are disabled.
1134 (list (nscd-cache (database 'hosts)
1135
1136 ;; Aggressively cache the host name cache to improve
1137 ;; privacy and resilience.
1138 (positive-time-to-live (* 3600 12))
1139 (negative-time-to-live 20)
1140 (persistent? #t))
1141
1142 (nscd-cache (database 'services)
1143
1144 ;; Services are unlikely to change, so we can be even more
1145 ;; aggressive.
1146 (positive-time-to-live (* 3600 24))
1147 (negative-time-to-live 3600)
1148 (check-files? #t) ;check /etc/services changes
1149 (persistent? #t))))
1150
1151 (define %nscd-default-configuration
1152 ;; Default nscd configuration.
1153 (nscd-configuration))
1154
1155 (define (nscd.conf-file config)
1156 "Return the @file{nscd.conf} configuration file for @var{config}, an
1157 @code{<nscd-configuration>} object."
1158 (define cache->config
1159 (match-lambda
1160 (($ <nscd-cache> (= symbol->string database)
1161 positive-ttl negative-ttl size check-files?
1162 persistent? shared? max-size propagate?)
1163 (string-append "\nenable-cache\t" database "\tyes\n"
1164
1165 "positive-time-to-live\t" database "\t"
1166 (number->string positive-ttl) "\n"
1167 "negative-time-to-live\t" database "\t"
1168 (number->string negative-ttl) "\n"
1169 "suggested-size\t" database "\t"
1170 (number->string size) "\n"
1171 "check-files\t" database "\t"
1172 (if check-files? "yes\n" "no\n")
1173 "persistent\t" database "\t"
1174 (if persistent? "yes\n" "no\n")
1175 "shared\t" database "\t"
1176 (if shared? "yes\n" "no\n")
1177 "max-db-size\t" database "\t"
1178 (number->string max-size) "\n"
1179 "auto-propagate\t" database "\t"
1180 (if propagate? "yes\n" "no\n")))))
1181
1182 (match config
1183 (($ <nscd-configuration> log-file debug-level caches)
1184 (plain-file "nscd.conf"
1185 (string-append "\
1186 # Configuration of libc's name service cache daemon (nscd).\n\n"
1187 (if log-file
1188 (string-append "logfile\t" log-file)
1189 "")
1190 "\n"
1191 (if debug-level
1192 (string-append "debug-level\t"
1193 (number->string debug-level))
1194 "")
1195 "\n"
1196 (string-concatenate
1197 (map cache->config caches)))))))
1198
1199 (define (nscd-action-procedure nscd config option)
1200 ;; XXX: This is duplicated from mcron; factorize.
1201 #~(lambda (_ . args)
1202 ;; Run 'nscd' in a pipe so we can explicitly redirect its output to
1203 ;; 'current-output-port', which at this stage is bound to the client
1204 ;; connection.
1205 (let ((pipe (apply open-pipe* OPEN_READ #$nscd
1206 "-f" #$config #$option args)))
1207 (let loop ()
1208 (match (read-line pipe 'concat)
1209 ((? eof-object?)
1210 (catch 'system-error
1211 (lambda ()
1212 (zero? (close-pipe pipe)))
1213 (lambda args
1214 ;; There's a race with the SIGCHLD handler, which could
1215 ;; call 'waitpid' before 'close-pipe' above does. If we
1216 ;; get ECHILD, that means we lost the race; in that case, we
1217 ;; cannot tell what the exit code was (FIXME).
1218 (or (= ECHILD (system-error-errno args))
1219 (apply throw args)))))
1220 (line
1221 (display line)
1222 (loop)))))))
1223
1224 (define (nscd-actions nscd config)
1225 "Return Shepherd actions for NSCD."
1226 ;; Make this functionality available as actions because that's a simple way
1227 ;; to run the right 'nscd' binary with the right config file.
1228 (list (shepherd-action
1229 (name 'statistics)
1230 (documentation "Display statistics about nscd usage.")
1231 (procedure (nscd-action-procedure nscd config "--statistics")))
1232 (shepherd-action
1233 (name 'invalidate)
1234 (documentation
1235 "Invalidate the given cache--e.g., 'hosts' for host name lookups.")
1236 (procedure (nscd-action-procedure nscd config "--invalidate")))))
1237
1238 (define (nscd-shepherd-service config)
1239 "Return a shepherd service for CONFIG, an <nscd-configuration> object."
1240 (let ((nscd (file-append (nscd-configuration-glibc config)
1241 "/sbin/nscd"))
1242 (nscd.conf (nscd.conf-file config))
1243 (name-services (nscd-configuration-name-services config)))
1244 (list (shepherd-service
1245 (documentation "Run libc's name service cache daemon (nscd).")
1246 (provision '(nscd))
1247 (requirement '(user-processes))
1248 (start #~(make-forkexec-constructor
1249 (list #$nscd "-f" #$nscd.conf "--foreground")
1250
1251 ;; Wait for the PID file. However, the PID file is
1252 ;; written before nscd is actually listening on its
1253 ;; socket (XXX).
1254 #:pid-file "/var/run/nscd/nscd.pid"
1255
1256 #:environment-variables
1257 (list (string-append "LD_LIBRARY_PATH="
1258 (string-join
1259 (map (lambda (dir)
1260 (string-append dir "/lib"))
1261 (list #$@name-services))
1262 ":")))))
1263 (stop #~(make-kill-destructor))
1264 (modules `((ice-9 popen) ;for the actions
1265 (ice-9 rdelim)
1266 (ice-9 match)
1267 ,@%default-modules))
1268 (actions (nscd-actions nscd nscd.conf))))))
1269
1270 (define nscd-activation
1271 ;; Actions to take before starting nscd.
1272 #~(begin
1273 (use-modules (guix build utils))
1274 (mkdir-p "/var/run/nscd")
1275 (mkdir-p "/var/db/nscd") ;for the persistent cache
1276
1277 ;; In libc 2.25 nscd uses inotify to watch /etc/resolv.conf, but only if
1278 ;; that file exists when it is started. Thus create it here. Note: on
1279 ;; some systems, such as when NetworkManager is used, /etc/resolv.conf
1280 ;; is a symlink, hence 'lstat'.
1281 (unless (false-if-exception (lstat "/etc/resolv.conf"))
1282 (call-with-output-file "/etc/resolv.conf"
1283 (lambda (port)
1284 (display "# This is a placeholder.\n" port))))))
1285
1286 (define nscd-service-type
1287 (service-type (name 'nscd)
1288 (extensions
1289 (list (service-extension activation-service-type
1290 (const nscd-activation))
1291 (service-extension shepherd-root-service-type
1292 nscd-shepherd-service)))
1293
1294 ;; This can be extended by providing additional name services
1295 ;; such as nss-mdns.
1296 (compose concatenate)
1297 (extend (lambda (config name-services)
1298 (nscd-configuration
1299 (inherit config)
1300 (name-services (append
1301 (nscd-configuration-name-services config)
1302 name-services)))))
1303 (default-value %nscd-default-configuration)
1304 (description
1305 "Runs libc's @dfn{name service cache daemon} (nscd) with the
1306 given configuration---an @code{<nscd-configuration>} object. @xref{Name
1307 Service Switch}, for an example.")))
1308
1309 (define* (nscd-service #:optional (config %nscd-default-configuration))
1310 "Return a service that runs libc's name service cache daemon (nscd) with the
1311 given @var{config}---an @code{<nscd-configuration>} object. @xref{Name
1312 Service Switch}, for an example."
1313 (service nscd-service-type config))
1314
1315
1316 (define-record-type* <syslog-configuration>
1317 syslog-configuration make-syslog-configuration
1318 syslog-configuration?
1319 (syslogd syslog-configuration-syslogd
1320 (default (file-append inetutils "/libexec/syslogd")))
1321 (config-file syslog-configuration-config-file
1322 (default %default-syslog.conf)))
1323
1324 (define syslog-service-type
1325 (shepherd-service-type
1326 'syslog
1327 (lambda (config)
1328 (shepherd-service
1329 (documentation "Run the syslog daemon (syslogd).")
1330 (provision '(syslogd))
1331 (requirement '(user-processes))
1332 (start #~(let ((spawn (make-forkexec-constructor
1333 (list #$(syslog-configuration-syslogd config)
1334 "--rcfile"
1335 #$(syslog-configuration-config-file config))
1336 #:pid-file "/var/run/syslog.pid")))
1337 (lambda ()
1338 ;; Set the umask such that file permissions are #o640.
1339 (let ((mask (umask #o137))
1340 (pid (spawn)))
1341 (umask mask)
1342 pid))))
1343 (stop #~(make-kill-destructor))))))
1344
1345 ;; Snippet adapted from the GNU inetutils manual.
1346 (define %default-syslog.conf
1347 (plain-file "syslog.conf" "
1348 # Log all error messages, authentication messages of
1349 # level notice or higher and anything of level err or
1350 # higher to the console.
1351 # Don't log private authentication messages!
1352 *.alert;auth.notice;authpriv.none /dev/console
1353
1354 # Log anything (except mail) of level info or higher.
1355 # Don't log private authentication messages!
1356 *.info;mail.none;authpriv.none /var/log/messages
1357
1358 # Like /var/log/messages, but also including \"debug\"-level logs.
1359 *.debug;mail.none;authpriv.none /var/log/debug
1360
1361 # Same, in a different place.
1362 *.info;mail.none;authpriv.none /dev/tty12
1363
1364 # The authpriv file has restricted access.
1365 authpriv.* /var/log/secure
1366
1367 # Log all the mail messages in one place.
1368 mail.* /var/log/maillog
1369 "))
1370
1371 (define* (syslog-service #:optional (config (syslog-configuration)))
1372 "Return a service that runs @command{syslogd} and takes
1373 @var{<syslog-configuration>} as a parameter.
1374
1375 @xref{syslogd invocation,,, inetutils, GNU Inetutils}, for more
1376 information on the configuration file syntax."
1377 (service syslog-service-type config))
1378
1379
1380 (define pam-limits-service-type
1381 (let ((security-limits
1382 ;; Create /etc/security containing the provided "limits.conf" file.
1383 (lambda (limits-file)
1384 `(("security"
1385 ,(computed-file
1386 "security"
1387 #~(begin
1388 (mkdir #$output)
1389 (stat #$limits-file)
1390 (symlink #$limits-file
1391 (string-append #$output "/limits.conf"))))))))
1392 (pam-extension
1393 (lambda (pam)
1394 (let ((pam-limits (pam-entry
1395 (control "required")
1396 (module "pam_limits.so")
1397 (arguments '("conf=/etc/security/limits.conf")))))
1398 (if (member (pam-service-name pam)
1399 '("login" "su" "slim" "gdm-password" "sddm"))
1400 (pam-service
1401 (inherit pam)
1402 (session (cons pam-limits
1403 (pam-service-session pam))))
1404 pam)))))
1405 (service-type
1406 (name 'limits)
1407 (extensions
1408 (list (service-extension etc-service-type security-limits)
1409 (service-extension pam-root-service-type
1410 (lambda _ (list pam-extension)))))
1411 (description
1412 "Install the specified resource usage limits by populating
1413 @file{/etc/security/limits.conf} and using the @code{pam_limits}
1414 authentication module."))))
1415
1416 (define* (pam-limits-service #:optional (limits '()))
1417 "Return a service that makes selected programs respect the list of
1418 pam-limits-entry specified in LIMITS via pam_limits.so."
1419 (service pam-limits-service-type
1420 (plain-file "limits.conf"
1421 (string-join (map pam-limits-entry->string limits)
1422 "\n"))))
1423
1424 \f
1425 ;;;
1426 ;;; Guix services.
1427 ;;;
1428
1429 (define* (guix-build-accounts count #:key
1430 (group "guixbuild")
1431 (shadow shadow))
1432 "Return a list of COUNT user accounts for Guix build users with the given
1433 GID."
1434 (unfold (cut > <> count)
1435 (lambda (n)
1436 (user-account
1437 (name (format #f "guixbuilder~2,'0d" n))
1438 (system? #t)
1439 (group group)
1440
1441 ;; guix-daemon expects GROUP to be listed as a
1442 ;; supplementary group too:
1443 ;; <http://lists.gnu.org/archive/html/bug-guix/2013-01/msg00239.html>.
1444 (supplementary-groups (list group "kvm"))
1445
1446 (comment (format #f "Guix Build User ~2d" n))
1447 (home-directory "/var/empty")
1448 (shell (file-append shadow "/sbin/nologin"))))
1449 1+
1450 1))
1451
1452 (define not-config?
1453 ;; Select (guix …) and (gnu …) modules, except (guix config).
1454 (match-lambda
1455 (('guix 'config) #f)
1456 (('guix rest ...) #t)
1457 (('gnu rest ...) #t)
1458 (rest #f)))
1459
1460 (define (substitute-key-authorization keys guix)
1461 "Return a gexp with code to register KEYS, a list of files containing 'guix
1462 archive' public keys, with GUIX."
1463 (define default-acl
1464 (with-extensions (list guile-gcrypt)
1465 (with-imported-modules `(((guix config) => ,(make-config.scm))
1466 ,@(source-module-closure '((guix pki))
1467 #:select? not-config?))
1468 (computed-file "acl"
1469 #~(begin
1470 (use-modules (guix pki)
1471 (gcrypt pk-crypto)
1472 (ice-9 rdelim))
1473
1474 (define keys
1475 (map (lambda (file)
1476 (call-with-input-file file
1477 (compose string->canonical-sexp
1478 read-string)))
1479 '(#$@keys)))
1480
1481 (call-with-output-file #$output
1482 (lambda (port)
1483 (write-acl (public-keys->acl keys)
1484 port))))))))
1485
1486 (with-imported-modules '((guix build utils))
1487 #~(begin
1488 (use-modules (guix build utils))
1489
1490 ;; If the ACL already exists, move it out of the way. Create a backup
1491 ;; if it's a regular file: it's likely that the user manually updated
1492 ;; it with 'guix archive --authorize'.
1493 (if (file-exists? "/etc/guix/acl")
1494 (if (and (symbolic-link? "/etc/guix/acl")
1495 (store-file-name? (readlink "/etc/guix/acl")))
1496 (delete-file "/etc/guix/acl")
1497 (rename-file "/etc/guix/acl" "/etc/guix/acl.bak"))
1498 (mkdir-p "/etc/guix"))
1499
1500 ;; Installed the declared ACL.
1501 (symlink #+default-acl "/etc/guix/acl"))))
1502
1503 (define %default-authorized-guix-keys
1504 ;; List of authorized substitute keys.
1505 (list (file-append guix "/share/guix/berlin.guix.gnu.org.pub")))
1506
1507 (define-record-type* <guix-configuration>
1508 guix-configuration make-guix-configuration
1509 guix-configuration?
1510 (guix guix-configuration-guix ;<package>
1511 (default guix))
1512 (build-group guix-configuration-build-group ;string
1513 (default "guixbuild"))
1514 (build-accounts guix-configuration-build-accounts ;integer
1515 (default 10))
1516 (authorize-key? guix-configuration-authorize-key? ;Boolean
1517 (default #t))
1518 (authorized-keys guix-configuration-authorized-keys ;list of gexps
1519 (default %default-authorized-guix-keys))
1520 (use-substitutes? guix-configuration-use-substitutes? ;Boolean
1521 (default #t))
1522 (substitute-urls guix-configuration-substitute-urls ;list of strings
1523 (default %default-substitute-urls))
1524 (chroot-directories guix-configuration-chroot-directories ;list of file-like/strings
1525 (default '()))
1526 (max-silent-time guix-configuration-max-silent-time ;integer
1527 (default 0))
1528 (timeout guix-configuration-timeout ;integer
1529 (default 0))
1530 (log-compression guix-configuration-log-compression
1531 (default 'bzip2))
1532 (extra-options guix-configuration-extra-options ;list of strings
1533 (default '()))
1534 (log-file guix-configuration-log-file ;string
1535 (default "/var/log/guix-daemon.log"))
1536 (http-proxy guix-http-proxy ;string | #f
1537 (default #f))
1538 (tmpdir guix-tmpdir ;string | #f
1539 (default #f)))
1540
1541 (define %default-guix-configuration
1542 (guix-configuration))
1543
1544 (define shepherd-set-http-proxy-action
1545 ;; Shepherd action to change the HTTP(S) proxy.
1546 (shepherd-action
1547 (name 'set-http-proxy)
1548 (documentation
1549 "Change the HTTP(S) proxy used by 'guix-daemon' and restart it.")
1550 (procedure #~(lambda* (_ #:optional proxy)
1551 (let ((environment (environ)))
1552 ;; A bit of a hack: communicate PROXY to the 'start'
1553 ;; method via environment variables.
1554 (if proxy
1555 (begin
1556 (format #t "changing HTTP/HTTPS \
1557 proxy of 'guix-daemon' to ~s...~%"
1558 proxy)
1559 (setenv "http_proxy" proxy))
1560 (begin
1561 (format #t "clearing HTTP/HTTPS \
1562 proxy of 'guix-daemon'...~%")
1563 (unsetenv "http_proxy")))
1564 (action 'guix-daemon 'restart)
1565 (environ environment)
1566 #t)))))
1567
1568 (define (guix-shepherd-service config)
1569 "Return a <shepherd-service> for the Guix daemon service with CONFIG."
1570 (match-record config <guix-configuration>
1571 (guix build-group build-accounts authorize-key? authorized-keys
1572 use-substitutes? substitute-urls max-silent-time timeout
1573 log-compression extra-options log-file http-proxy tmpdir
1574 chroot-directories)
1575 (list (shepherd-service
1576 (documentation "Run the Guix daemon.")
1577 (provision '(guix-daemon))
1578 (requirement '(user-processes))
1579 (actions (list shepherd-set-http-proxy-action))
1580 (modules '((srfi srfi-1)
1581 (ice-9 match)
1582 (gnu build shepherd)))
1583 (start
1584 (with-imported-modules `(((guix config) => ,(make-config.scm))
1585 ,@(source-module-closure
1586 '((gnu build shepherd))
1587 #:select? not-config?))
1588 #~(lambda args
1589 (define proxy
1590 ;; HTTP/HTTPS proxy. The 'http_proxy' variable is set by
1591 ;; the 'set-http-proxy' action.
1592 (or (getenv "http_proxy") #$http-proxy))
1593
1594 ;; Start the guix-daemon from a container, when supported,
1595 ;; to solve an installation issue. See the comment below for
1596 ;; more details.
1597 (fork+exec-command/container
1598 (cons* #$(file-append guix "/bin/guix-daemon")
1599 "--build-users-group" #$build-group
1600 "--max-silent-time"
1601 #$(number->string max-silent-time)
1602 "--timeout" #$(number->string timeout)
1603 "--log-compression"
1604 #$(symbol->string log-compression)
1605 #$@(if use-substitutes?
1606 '()
1607 '("--no-substitutes"))
1608 "--substitute-urls" #$(string-join substitute-urls)
1609 #$@extra-options
1610
1611 ;; Add CHROOT-DIRECTORIES and all their dependencies
1612 ;; (if these are store items) to the chroot.
1613 (append-map
1614 (lambda (file)
1615 (append-map (lambda (directory)
1616 (list "--chroot-directory"
1617 directory))
1618 (call-with-input-file file
1619 read)))
1620 '#$(map references-file
1621 chroot-directories)))
1622
1623 ;; When running the installer, we need guix-daemon to
1624 ;; operate from within the same MNT namespace as the
1625 ;; installation container. In that case only, enter the
1626 ;; namespace of the process PID passed as start argument.
1627 ;; Otherwise, for symmetry purposes enter the caller
1628 ;; namespaces which is a no-op.
1629 #:pid (match args
1630 ((pid) (string->number pid))
1631 (else (getpid)))
1632
1633 #:environment-variables
1634 (append (list #$@(if tmpdir
1635 (list (string-append "TMPDIR=" tmpdir))
1636 '())
1637
1638 ;; Make sure we run in a UTF-8 locale so that
1639 ;; 'guix offload' correctly restores nars
1640 ;; that contain UTF-8 file names such as
1641 ;; 'nss-certs'. See
1642 ;; <https://bugs.gnu.org/32942>.
1643 (string-append "GUIX_LOCPATH="
1644 #$glibc-utf8-locales
1645 "/lib/locale")
1646 "LC_ALL=en_US.utf8")
1647 (if proxy
1648 (list (string-append "http_proxy=" proxy)
1649 (string-append "https_proxy=" proxy))
1650 '()))
1651
1652 #:log-file #$log-file))))
1653 (stop #~(make-kill-destructor))))))
1654
1655 (define (guix-accounts config)
1656 "Return the user accounts and user groups for CONFIG."
1657 (match config
1658 (($ <guix-configuration> _ build-group build-accounts)
1659 (cons (user-group
1660 (name build-group)
1661 (system? #t)
1662
1663 ;; Use a fixed GID so that we can create the store with the right
1664 ;; owner.
1665 (id 30000))
1666 (guix-build-accounts build-accounts
1667 #:group build-group)))))
1668
1669 (define (guix-activation config)
1670 "Return the activation gexp for CONFIG."
1671 (match config
1672 (($ <guix-configuration> guix build-group build-accounts authorize-key? keys)
1673 ;; Assume that the store has BUILD-GROUP as its group. We could
1674 ;; otherwise call 'chown' here, but the problem is that on a COW overlayfs,
1675 ;; chown leads to an entire copy of the tree, which is a bad idea.
1676
1677 ;; Generate a key pair and optionally authorize substitute server keys.
1678 #~(begin
1679 (unless (file-exists? "/etc/guix/signing-key.pub")
1680 (system* #$(file-append guix "/bin/guix") "archive"
1681 "--generate-key"))
1682
1683 #$(if authorize-key?
1684 (substitute-key-authorization keys guix)
1685 #~#f)))))
1686
1687 (define* (references-file item #:optional (name "references"))
1688 "Return a file that contains the list of references of ITEM."
1689 (if (struct? item) ;lowerable object
1690 (computed-file name
1691 (with-imported-modules (source-module-closure
1692 '((guix build store-copy)))
1693 #~(begin
1694 (use-modules (guix build store-copy))
1695
1696 (call-with-output-file #$output
1697 (lambda (port)
1698 (write (map store-info-item
1699 (call-with-input-file "graph"
1700 read-reference-graph))
1701 port)))))
1702 #:options `(#:local-build? #f
1703 #:references-graphs (("graph" ,item))))
1704 (plain-file name "()")))
1705
1706 (define guix-service-type
1707 (service-type
1708 (name 'guix)
1709 (extensions
1710 (list (service-extension shepherd-root-service-type guix-shepherd-service)
1711 (service-extension account-service-type guix-accounts)
1712 (service-extension activation-service-type guix-activation)
1713 (service-extension profile-service-type
1714 (compose list guix-configuration-guix))))
1715
1716 ;; Extensions can specify extra directories to add to the build chroot.
1717 (compose concatenate)
1718 (extend (lambda (config directories)
1719 (guix-configuration
1720 (inherit config)
1721 (chroot-directories
1722 (append (guix-configuration-chroot-directories config)
1723 directories)))))
1724
1725 (default-value (guix-configuration))
1726 (description
1727 "Run the build daemon of GNU@tie{}Guix, aka. @command{guix-daemon}.")))
1728
1729 (define-deprecated (guix-service #:optional
1730 (config %default-guix-configuration))
1731 guix-service-type
1732 "Return a service that runs the Guix build daemon according to
1733 @var{config}."
1734 (service guix-service-type config))
1735
1736
1737 (define-record-type* <guix-publish-configuration>
1738 guix-publish-configuration make-guix-publish-configuration
1739 guix-publish-configuration?
1740 (guix guix-publish-configuration-guix ;package
1741 (default guix))
1742 (port guix-publish-configuration-port ;number
1743 (default 80))
1744 (host guix-publish-configuration-host ;string
1745 (default "localhost"))
1746 (compression guix-publish-configuration-compression
1747 (thunked)
1748 (default (default-compression this-record
1749 (current-source-location))))
1750 (compression-level %guix-publish-configuration-compression-level ;deprecated
1751 (default #f))
1752 (nar-path guix-publish-configuration-nar-path ;string
1753 (default "nar"))
1754 (cache guix-publish-configuration-cache ;#f | string
1755 (default #f))
1756 (cache-bypass-threshold guix-publish-configuration-cache-bypass-threshold
1757 (default (* 10 (expt 2 20)))) ;integer
1758 (workers guix-publish-configuration-workers ;#f | integer
1759 (default #f))
1760 (ttl guix-publish-configuration-ttl ;#f | integer
1761 (default #f)))
1762
1763 (define-deprecated (guix-publish-configuration-compression-level config)
1764 "Return a compression level, the old way."
1765 (match (guix-publish-configuration-compression config)
1766 (((_ level) _ ...) level)))
1767
1768 (define (default-compression config properties)
1769 "Return the default 'guix publish' compression according to CONFIG, and
1770 raise a deprecation warning if the 'compression-level' field was used."
1771 (match (%guix-publish-configuration-compression-level config)
1772 (#f
1773 '(("gzip" 3)))
1774 (level
1775 (warn-about-deprecation 'compression-level properties
1776 #:replacement 'compression)
1777 `(("gzip" ,level)))))
1778
1779 (define (guix-publish-shepherd-service config)
1780 (define (config->compression-options config)
1781 (match (guix-publish-configuration-compression config)
1782 (() ;empty list means "no compression"
1783 '("-C0"))
1784 (lst
1785 (append-map (match-lambda
1786 ((type level)
1787 `("-C" ,(string-append type ":"
1788 (number->string level)))))
1789 lst))))
1790
1791 (match-record config <guix-publish-configuration>
1792 (guix port host nar-path cache workers ttl cache-bypass-threshold)
1793 (list (shepherd-service
1794 (provision '(guix-publish))
1795 (requirement '(guix-daemon))
1796 (start #~(make-forkexec-constructor
1797 (list #$(file-append guix "/bin/guix")
1798 "publish" "-u" "guix-publish"
1799 "-p" #$(number->string port)
1800 #$@(config->compression-options config)
1801 (string-append "--nar-path=" #$nar-path)
1802 (string-append "--listen=" #$host)
1803 #$@(if workers
1804 #~((string-append "--workers="
1805 #$(number->string
1806 workers)))
1807 #~())
1808 #$@(if ttl
1809 #~((string-append "--ttl="
1810 #$(number->string ttl)
1811 "s"))
1812 #~())
1813 #$@(if cache
1814 #~((string-append "--cache=" #$cache)
1815 #$(string-append
1816 "--cache-bypass-threshold="
1817 (number->string
1818 cache-bypass-threshold)))
1819 #~()))
1820
1821 ;; Make sure we run in a UTF-8 locale so we can produce
1822 ;; nars for packages that contain UTF-8 file names such
1823 ;; as 'nss-certs'. See <https://bugs.gnu.org/26948>.
1824 #:environment-variables
1825 (list (string-append "GUIX_LOCPATH="
1826 #$glibc-utf8-locales "/lib/locale")
1827 "LC_ALL=en_US.utf8")
1828 #:log-file "/var/log/guix-publish.log"))
1829 (stop #~(make-kill-destructor))))))
1830
1831 (define %guix-publish-accounts
1832 (list (user-group (name "guix-publish") (system? #t))
1833 (user-account
1834 (name "guix-publish")
1835 (group "guix-publish")
1836 (system? #t)
1837 (comment "guix publish user")
1838 (home-directory "/var/empty")
1839 (shell (file-append shadow "/sbin/nologin")))))
1840
1841 (define %guix-publish-log-rotations
1842 (list (log-rotation
1843 (files (list "/var/log/guix-publish.log")))))
1844
1845 (define (guix-publish-activation config)
1846 (let ((cache (guix-publish-configuration-cache config)))
1847 (if cache
1848 (with-imported-modules '((guix build utils))
1849 #~(begin
1850 (use-modules (guix build utils))
1851
1852 (mkdir-p #$cache)
1853 (let* ((pw (getpw "guix-publish"))
1854 (uid (passwd:uid pw))
1855 (gid (passwd:gid pw)))
1856 (chown #$cache uid gid))))
1857 #t)))
1858
1859 (define guix-publish-service-type
1860 (service-type (name 'guix-publish)
1861 (extensions
1862 (list (service-extension shepherd-root-service-type
1863 guix-publish-shepherd-service)
1864 (service-extension account-service-type
1865 (const %guix-publish-accounts))
1866 (service-extension rottlog-service-type
1867 (const %guix-publish-log-rotations))
1868 (service-extension activation-service-type
1869 guix-publish-activation)))
1870 (default-value (guix-publish-configuration))
1871 (description
1872 "Add a Shepherd service running @command{guix publish}, a
1873 command that allows you to share pre-built binaries with others over HTTP.")))
1874
1875 (define-deprecated (guix-publish-service #:key (guix guix)
1876 (port 80) (host "localhost"))
1877 guix-publish-service-type
1878 "Return a service that runs @command{guix publish} listening on @var{host}
1879 and @var{port} (@pxref{Invoking guix publish}).
1880
1881 This assumes that @file{/etc/guix} already contains a signing key pair as
1882 created by @command{guix archive --generate-key} (@pxref{Invoking guix
1883 archive}). If that is not the case, the service will fail to start."
1884 ;; Deprecated.
1885 (service guix-publish-service-type
1886 (guix-publish-configuration (guix guix) (port port) (host host))))
1887
1888 \f
1889 ;;;
1890 ;;; Udev.
1891 ;;;
1892
1893 (define-record-type* <udev-configuration>
1894 udev-configuration make-udev-configuration
1895 udev-configuration?
1896 (udev udev-configuration-udev ;<package>
1897 (default eudev))
1898 (rules udev-configuration-rules ;list of <package>
1899 (default '())))
1900
1901 (define (udev-rules-union packages)
1902 "Return the union of the @code{lib/udev/rules.d} directories found in each
1903 item of @var{packages}."
1904 (define build
1905 (with-imported-modules '((guix build union)
1906 (guix build utils))
1907 #~(begin
1908 (use-modules (guix build union)
1909 (guix build utils)
1910 (srfi srfi-1)
1911 (srfi srfi-26))
1912
1913 (define %standard-locations
1914 '("/lib/udev/rules.d" "/libexec/udev/rules.d"))
1915
1916 (define (rules-sub-directory directory)
1917 ;; Return the sub-directory of DIRECTORY containing udev rules, or
1918 ;; #f if none was found.
1919 (find directory-exists?
1920 (map (cut string-append directory <>) %standard-locations)))
1921
1922 (mkdir-p (string-append #$output "/lib/udev"))
1923 (union-build (string-append #$output "/lib/udev/rules.d")
1924 (filter-map rules-sub-directory '#$packages)))))
1925
1926 (computed-file "udev-rules" build))
1927
1928 (define (udev-rule file-name contents)
1929 "Return a directory with a udev rule file FILE-NAME containing CONTENTS."
1930 (computed-file file-name
1931 (with-imported-modules '((guix build utils))
1932 #~(begin
1933 (use-modules (guix build utils))
1934
1935 (define rules.d
1936 (string-append #$output "/lib/udev/rules.d"))
1937
1938 (mkdir-p rules.d)
1939 (call-with-output-file
1940 (string-append rules.d "/" #$file-name)
1941 (lambda (port)
1942 (display #$contents port)))))))
1943
1944 (define (file->udev-rule file-name file)
1945 "Return a directory with a udev rule file FILE-NAME which is a copy of FILE."
1946 (computed-file file-name
1947 (with-imported-modules '((guix build utils))
1948 #~(begin
1949 (use-modules (guix build utils))
1950
1951 (define rules.d
1952 (string-append #$output "/lib/udev/rules.d"))
1953
1954 (define file-copy-dest
1955 (string-append rules.d "/" #$file-name))
1956
1957 (mkdir-p rules.d)
1958 (copy-file #$file file-copy-dest)))))
1959
1960 (define kvm-udev-rule
1961 ;; Return a directory with a udev rule that changes the group of /dev/kvm to
1962 ;; "kvm" and makes it #o660. Apparently QEMU-KVM used to ship this rule,
1963 ;; but now we have to add it by ourselves.
1964
1965 ;; Build users are part of the "kvm" group, so we can fearlessly make
1966 ;; /dev/kvm 660 (see <http://bugs.gnu.org/18994>, for background.)
1967 (udev-rule "90-kvm.rules"
1968 "KERNEL==\"kvm\", GROUP=\"kvm\", MODE=\"0660\"\n"))
1969
1970 (define udev-shepherd-service
1971 ;; Return a <shepherd-service> for UDEV with RULES.
1972 (match-lambda
1973 (($ <udev-configuration> udev rules)
1974 (let* ((rules (udev-rules-union (cons* udev kvm-udev-rule rules)))
1975 (udev.conf (computed-file "udev.conf"
1976 #~(call-with-output-file #$output
1977 (lambda (port)
1978 (format port
1979 "udev_rules=\"~a/lib/udev/rules.d\"\n"
1980 #$rules))))))
1981 (list
1982 (shepherd-service
1983 (provision '(udev))
1984
1985 ;; Udev needs /dev to be a 'devtmpfs' mount so that new device nodes can
1986 ;; be added: see
1987 ;; <http://www.linuxfromscratch.org/lfs/view/development/chapter07/udev.html>.
1988 (requirement '(root-file-system))
1989
1990 (documentation "Populate the /dev directory, dynamically.")
1991 (start
1992 (with-imported-modules (source-module-closure
1993 '((gnu build linux-boot)))
1994 #~(lambda ()
1995 (define udevd
1996 ;; 'udevd' from eudev.
1997 #$(file-append udev "/sbin/udevd"))
1998
1999 (define (wait-for-udevd)
2000 ;; Wait until someone's listening on udevd's control
2001 ;; socket.
2002 (let ((sock (socket AF_UNIX SOCK_SEQPACKET 0)))
2003 (let try ()
2004 (catch 'system-error
2005 (lambda ()
2006 (connect sock PF_UNIX "/run/udev/control")
2007 (close-port sock))
2008 (lambda args
2009 (format #t "waiting for udevd...~%")
2010 (usleep 500000)
2011 (try))))))
2012
2013 ;; Allow udev to find the modules.
2014 (setenv "LINUX_MODULE_DIRECTORY"
2015 "/run/booted-system/kernel/lib/modules")
2016
2017 (let* ((kernel-release
2018 (utsname:release (uname)))
2019 (linux-module-directory
2020 (getenv "LINUX_MODULE_DIRECTORY"))
2021 (directory
2022 (string-append linux-module-directory "/"
2023 kernel-release))
2024 (old-umask (umask #o022)))
2025 ;; If we're in a container, DIRECTORY might not exist,
2026 ;; for instance because the host runs a different
2027 ;; kernel. In that case, skip it; we'll just miss a few
2028 ;; nodes like /dev/fuse.
2029 (when (file-exists? directory)
2030 (make-static-device-nodes directory))
2031 (umask old-umask))
2032
2033 (let ((pid (fork+exec-command (list udevd)
2034 #:environment-variables
2035 (cons*
2036 ;; The first one is for udev, the second one for
2037 ;; eudev.
2038 (string-append "UDEV_CONFIG_FILE=" #$udev.conf)
2039 (string-append "EUDEV_RULES_DIRECTORY="
2040 #$(file-append
2041 rules "/lib/udev/rules.d"))
2042 (string-append "LINUX_MODULE_DIRECTORY="
2043 (getenv "LINUX_MODULE_DIRECTORY"))
2044 (default-environment-variables)))))
2045 ;; Wait until udevd is up and running. This appears to
2046 ;; be needed so that the events triggered below are
2047 ;; actually handled.
2048 (wait-for-udevd)
2049
2050 ;; Trigger device node creation.
2051 (system* #$(file-append udev "/bin/udevadm")
2052 "trigger" "--action=add")
2053
2054 ;; Wait for things to settle down.
2055 (system* #$(file-append udev "/bin/udevadm")
2056 "settle")
2057 pid))))
2058 (stop #~(make-kill-destructor))
2059
2060 ;; When halting the system, 'udev' is actually killed by
2061 ;; 'user-processes', i.e., before its own 'stop' method was called.
2062 ;; Thus, make sure it is not respawned.
2063 (respawn? #f)
2064 ;; We need additional modules.
2065 (modules `((gnu build linux-boot) ;'make-static-device-nodes'
2066 ,@%default-modules))
2067
2068 (actions (list (shepherd-action
2069 (name 'rules)
2070 (documentation "Display the directory containing
2071 the udev rules in use.")
2072 (procedure #~(lambda (_)
2073 (display #$rules)
2074 (newline))))))))))))
2075
2076 (define udev-service-type
2077 (service-type (name 'udev)
2078 (extensions
2079 (list (service-extension shepherd-root-service-type
2080 udev-shepherd-service)))
2081
2082 (compose concatenate) ;concatenate the list of rules
2083 (extend (lambda (config rules)
2084 (match config
2085 (($ <udev-configuration> udev initial-rules)
2086 (udev-configuration
2087 (udev udev)
2088 (rules (append initial-rules rules)))))))
2089 (default-value (udev-configuration))
2090 (description
2091 "Run @command{udev}, which populates the @file{/dev}
2092 directory dynamically. Get extra rules from the packages listed in the
2093 @code{rules} field of its value, @code{udev-configuration} object.")))
2094
2095 (define* (udev-service #:key (udev eudev) (rules '()))
2096 "Run @var{udev}, which populates the @file{/dev} directory dynamically. Get
2097 extra rules from the packages listed in @var{rules}."
2098 (service udev-service-type
2099 (udev-configuration (udev udev) (rules rules))))
2100
2101 (define* (udev-rules-service name rules #:key (groups '()))
2102 "Return a service that extends udev-service-type with RULES and
2103 account-service-type with GROUPS as system groups. This works by creating a
2104 singleton service type NAME-udev-rules, of which the returned service is an
2105 instance."
2106 (let* ((name (symbol-append name '-udev-rules))
2107 (account-extension
2108 (const (map (lambda (group)
2109 (user-group (name group) (system? #t)))
2110 groups)))
2111 (udev-extension (const (list rules)))
2112 (type (service-type
2113 (name name)
2114 (extensions (list
2115 (service-extension
2116 account-service-type account-extension)
2117 (service-extension
2118 udev-service-type udev-extension))))))
2119 (service type #f)))
2120
2121 (define swap-service-type
2122 (shepherd-service-type
2123 'swap
2124 (lambda (device)
2125 (define requirement
2126 (if (and (string? device)
2127 (string-prefix? "/dev/mapper/" device))
2128 (list (symbol-append 'device-mapping-
2129 (string->symbol (basename device))))
2130 '()))
2131
2132 (define (device-lookup device)
2133 ;; The generic 'find-partition' procedures could return a partition
2134 ;; that's not swap space, but that's unlikely.
2135 (cond ((uuid? device)
2136 #~(find-partition-by-uuid #$(uuid-bytevector device)))
2137 ((file-system-label? device)
2138 #~(find-partition-by-label
2139 #$(file-system-label->string device)))
2140 (else
2141 device)))
2142
2143 (define service-name
2144 (symbol-append 'swap-
2145 (string->symbol
2146 (cond ((uuid? device)
2147 (string-take (uuid->string device) 6))
2148 ((file-system-label? device)
2149 (file-system-label->string device))
2150 (else
2151 device)))))
2152
2153 (with-imported-modules (source-module-closure '((gnu build file-systems)))
2154 (shepherd-service
2155 (provision (list service-name))
2156 (requirement `(udev ,@requirement))
2157 (documentation "Enable the given swap device.")
2158 (modules `((gnu build file-systems)
2159 ,@%default-modules))
2160 (start #~(lambda ()
2161 (let ((device #$(device-lookup device)))
2162 (and device
2163 (begin
2164 (restart-on-EINTR (swapon device))
2165 #t)))))
2166 (stop #~(lambda _
2167 (let ((device #$(device-lookup device)))
2168 (when device
2169 (restart-on-EINTR (swapoff device)))
2170 #f)))
2171 (respawn? #f))))))
2172
2173 (define (swap-service device)
2174 "Return a service that uses @var{device} as a swap device."
2175 (service swap-service-type device))
2176
2177 (define %default-gpm-options
2178 ;; Default options for GPM.
2179 '("-m" "/dev/input/mice" "-t" "ps2"))
2180
2181 (define-record-type* <gpm-configuration>
2182 gpm-configuration make-gpm-configuration gpm-configuration?
2183 (gpm gpm-configuration-gpm ;package
2184 (default gpm))
2185 (options gpm-configuration-options ;list of strings
2186 (default %default-gpm-options)))
2187
2188 (define gpm-shepherd-service
2189 (match-lambda
2190 (($ <gpm-configuration> gpm options)
2191 (list (shepherd-service
2192 (requirement '(udev))
2193 (provision '(gpm))
2194 (start #~(lambda ()
2195 ;; 'gpm' runs in the background and sets a PID file.
2196 ;; Note that it requires running as "root".
2197 (false-if-exception (delete-file "/var/run/gpm.pid"))
2198 (fork+exec-command (list #$(file-append gpm "/sbin/gpm")
2199 #$@options))
2200
2201 ;; Wait for the PID file to appear; declare failure if
2202 ;; it doesn't show up.
2203 (let loop ((i 3))
2204 (or (file-exists? "/var/run/gpm.pid")
2205 (if (zero? i)
2206 #f
2207 (begin
2208 (sleep 1)
2209 (loop (1- i))))))))
2210
2211 (stop #~(lambda (_)
2212 ;; Return #f if successfully stopped.
2213 (not (zero? (system* #$(file-append gpm "/sbin/gpm")
2214 "-k"))))))))))
2215
2216 (define gpm-service-type
2217 (service-type (name 'gpm)
2218 (extensions
2219 (list (service-extension shepherd-root-service-type
2220 gpm-shepherd-service)))
2221 (default-value (gpm-configuration))
2222 (description
2223 "Run GPM, the general-purpose mouse daemon, with the given
2224 command-line options. GPM allows users to use the mouse in the console,
2225 notably to select, copy, and paste text. The default options use the
2226 @code{ps2} protocol, which works for both USB and PS/2 mice.")))
2227
2228 (define-deprecated (gpm-service #:key (gpm gpm)
2229 (options %default-gpm-options))
2230 gpm-service-type
2231 "Run @var{gpm}, the general-purpose mouse daemon, with the given
2232 command-line @var{options}. GPM allows users to use the mouse in the console,
2233 notably to select, copy, and paste text. The default value of @var{options}
2234 uses the @code{ps2} protocol, which works for both USB and PS/2 mice.
2235
2236 This service is not part of @var{%base-services}."
2237 ;; To test in QEMU, use "-usbdevice mouse" and then, in the monitor, use
2238 ;; "info mice" and "mouse_set X" to use the right mouse.
2239 (service gpm-service-type
2240 (gpm-configuration (gpm gpm) (options options))))
2241
2242 (define-record-type* <kmscon-configuration>
2243 kmscon-configuration make-kmscon-configuration
2244 kmscon-configuration?
2245 (kmscon kmscon-configuration-kmscon
2246 (default kmscon))
2247 (virtual-terminal kmscon-configuration-virtual-terminal)
2248 (login-program kmscon-configuration-login-program
2249 (default (file-append shadow "/bin/login")))
2250 (login-arguments kmscon-configuration-login-arguments
2251 (default '("-p")))
2252 (auto-login kmscon-configuration-auto-login
2253 (default #f))
2254 (hardware-acceleration? kmscon-configuration-hardware-acceleration?
2255 (default #f))) ; #t causes failure
2256
2257 (define kmscon-service-type
2258 (shepherd-service-type
2259 'kmscon
2260 (lambda (config)
2261 (let ((kmscon (kmscon-configuration-kmscon config))
2262 (virtual-terminal (kmscon-configuration-virtual-terminal config))
2263 (login-program (kmscon-configuration-login-program config))
2264 (login-arguments (kmscon-configuration-login-arguments config))
2265 (auto-login (kmscon-configuration-auto-login config))
2266 (hardware-acceleration? (kmscon-configuration-hardware-acceleration? config)))
2267
2268 (define kmscon-command
2269 #~(list
2270 #$(file-append kmscon "/bin/kmscon") "--login"
2271 "--vt" #$virtual-terminal
2272 "--no-switchvt" ;Prevent a switch to the virtual terminal.
2273 #$@(if hardware-acceleration? '("--hwaccel") '())
2274 "--login" "--"
2275 #$login-program #$@login-arguments
2276 #$@(if auto-login
2277 #~(#$auto-login)
2278 #~())))
2279
2280 (shepherd-service
2281 (documentation "kmscon virtual terminal")
2282 (requirement '(user-processes udev dbus-system))
2283 (provision (list (symbol-append 'term- (string->symbol virtual-terminal))))
2284 (start #~(make-forkexec-constructor #$kmscon-command))
2285 (stop #~(make-kill-destructor)))))))
2286
2287 (define-record-type* <static-networking>
2288 static-networking make-static-networking
2289 static-networking?
2290 (interface static-networking-interface)
2291 (ip static-networking-ip)
2292 (netmask static-networking-netmask
2293 (default #f))
2294 (gateway static-networking-gateway ;FIXME: doesn't belong here
2295 (default #f))
2296 (provision static-networking-provision
2297 (default #f))
2298 (requirement static-networking-requirement
2299 (default '()))
2300 (name-servers static-networking-name-servers ;FIXME: doesn't belong here
2301 (default '())))
2302
2303 (define static-networking-shepherd-service
2304 (match-lambda
2305 (($ <static-networking> interface ip netmask gateway provision
2306 requirement name-servers)
2307 (let ((loopback? (and provision (memq 'loopback provision))))
2308 (shepherd-service
2309
2310 (documentation
2311 "Bring up the networking interface using a static IP address.")
2312 (requirement requirement)
2313 (provision (or provision
2314 (list (symbol-append 'networking-
2315 (string->symbol interface)))))
2316
2317 (start #~(lambda _
2318 ;; Return #t if successfully started.
2319 (let* ((addr (inet-pton AF_INET #$ip))
2320 (sockaddr (make-socket-address AF_INET addr 0))
2321 (mask (and #$netmask
2322 (inet-pton AF_INET #$netmask)))
2323 (maskaddr (and mask
2324 (make-socket-address AF_INET
2325 mask 0)))
2326 (gateway (and #$gateway
2327 (inet-pton AF_INET #$gateway)))
2328 (gatewayaddr (and gateway
2329 (make-socket-address AF_INET
2330 gateway 0))))
2331 (configure-network-interface #$interface sockaddr
2332 (logior IFF_UP
2333 #$(if loopback?
2334 #~IFF_LOOPBACK
2335 0))
2336 #:netmask maskaddr)
2337 (when gateway
2338 (let ((sock (socket AF_INET SOCK_DGRAM 0)))
2339 (add-network-route/gateway sock gatewayaddr)
2340 (close-port sock))))))
2341 (stop #~(lambda _
2342 ;; Return #f is successfully stopped.
2343 (let ((sock (socket AF_INET SOCK_STREAM 0)))
2344 (when #$gateway
2345 (delete-network-route sock
2346 (make-socket-address
2347 AF_INET INADDR_ANY 0)))
2348 (set-network-interface-flags sock #$interface 0)
2349 (close-port sock)
2350 #f)))
2351 (respawn? #f))))))
2352
2353 (define (static-networking-etc-files interfaces)
2354 "Return a /etc/resolv.conf entry for INTERFACES or the empty list."
2355 (match (delete-duplicates
2356 (append-map static-networking-name-servers
2357 interfaces))
2358 (()
2359 '())
2360 ((name-servers ...)
2361 (let ((content (string-join
2362 (map (cut string-append "nameserver " <>)
2363 name-servers)
2364 "\n" 'suffix)))
2365 `(("resolv.conf"
2366 ,(plain-file "resolv.conf"
2367 (string-append "\
2368 # Generated by 'static-networking-service'.\n"
2369 content))))))))
2370
2371 (define (static-networking-shepherd-services interfaces)
2372 "Return the list of Shepherd services to bring up INTERFACES, a list of
2373 <static-networking> objects."
2374 (define (loopback? service)
2375 (memq 'loopback (shepherd-service-provision service)))
2376
2377 (let ((services (map static-networking-shepherd-service interfaces)))
2378 (match (remove loopback? services)
2379 (()
2380 ;; There's no interface other than 'loopback', so we assume that the
2381 ;; 'networking' service will be provided by dhclient or similar.
2382 services)
2383 ((non-loopback ...)
2384 ;; Assume we're providing all the interfaces, and thus, provide a
2385 ;; 'networking' service.
2386 (cons (shepherd-service
2387 (provision '(networking))
2388 (requirement (append-map shepherd-service-provision
2389 services))
2390 (start #~(const #t))
2391 (stop #~(const #f))
2392 (documentation "Bring up all the networking interfaces."))
2393 services)))))
2394
2395 (define static-networking-service-type
2396 ;; The service type for statically-defined network interfaces.
2397 (service-type (name 'static-networking)
2398 (extensions
2399 (list
2400 (service-extension shepherd-root-service-type
2401 static-networking-shepherd-services)
2402 (service-extension etc-service-type
2403 static-networking-etc-files)))
2404 (compose concatenate)
2405 (extend append)
2406 (description
2407 "Turn up the specified network interfaces upon startup,
2408 with the given IP address, gateway, netmask, and so on. The value for
2409 services of this type is a list of @code{static-networking} objects, one per
2410 network interface.")))
2411
2412 (define* (static-networking-service interface ip
2413 #:key
2414 netmask gateway provision
2415 ;; Most interfaces require udev to be usable.
2416 (requirement '(udev))
2417 (name-servers '()))
2418 "Return a service that starts @var{interface} with address @var{ip}. If
2419 @var{netmask} is true, use it as the network mask. If @var{gateway} is true,
2420 it must be a string specifying the default network gateway.
2421
2422 This procedure can be called several times, one for each network
2423 interface of interest. Behind the scenes what it does is extend
2424 @code{static-networking-service-type} with additional network interfaces
2425 to handle."
2426 (simple-service 'static-network-interface
2427 static-networking-service-type
2428 (list (static-networking (interface interface) (ip ip)
2429 (netmask netmask) (gateway gateway)
2430 (provision provision)
2431 (requirement requirement)
2432 (name-servers name-servers)))))
2433
2434 \f
2435 (define %base-services
2436 ;; Convenience variable holding the basic services.
2437 (list (service login-service-type)
2438
2439 (service virtual-terminal-service-type)
2440 (service console-font-service-type
2441 (map (lambda (tty)
2442 (cons tty %default-console-font))
2443 '("tty1" "tty2" "tty3" "tty4" "tty5" "tty6")))
2444
2445 (service agetty-service-type (agetty-configuration
2446 (extra-options '("-L")) ; no carrier detect
2447 (term "vt100")
2448 (tty #f))) ; automatic
2449
2450 (service mingetty-service-type (mingetty-configuration
2451 (tty "tty1")))
2452 (service mingetty-service-type (mingetty-configuration
2453 (tty "tty2")))
2454 (service mingetty-service-type (mingetty-configuration
2455 (tty "tty3")))
2456 (service mingetty-service-type (mingetty-configuration
2457 (tty "tty4")))
2458 (service mingetty-service-type (mingetty-configuration
2459 (tty "tty5")))
2460 (service mingetty-service-type (mingetty-configuration
2461 (tty "tty6")))
2462
2463 (service static-networking-service-type
2464 (list (static-networking (interface "lo")
2465 (ip "127.0.0.1")
2466 (requirement '())
2467 (provision '(loopback)))))
2468 (syslog-service)
2469 (service urandom-seed-service-type)
2470 (service guix-service-type)
2471 (service nscd-service-type)
2472
2473 (service rottlog-service-type)
2474
2475 ;; The LVM2 rules are needed as soon as LVM2 or the device-mapper is
2476 ;; used, so enable them by default. The FUSE and ALSA rules are
2477 ;; less critical, but handy.
2478 (service udev-service-type
2479 (udev-configuration
2480 (rules (list lvm2 fuse alsa-utils crda))))
2481
2482 (service special-files-service-type
2483 `(("/bin/sh" ,(file-append bash "/bin/sh"))
2484 ("/usr/bin/env" ,(file-append coreutils "/bin/env"))))))
2485
2486 ;;; base.scm ends here