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