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