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