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