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