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