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