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