system: Add (gnu system mapped-devices).
[jackhill/guix/guix.git] / gnu / services / base.scm
CommitLineData
db4fdc04 1;;; GNU Guix --- Functional package management for GNU
9a8b9eb8 2;;; Copyright © 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
34044d55 3;;; Copyright © 2015, 2016 Alex Kost <alezost@gmail.com>
4307c476 4;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
e10964ef 5;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
db4fdc04
LC
6;;;
7;;; This file is part of GNU Guix.
8;;;
9;;; GNU Guix is free software; you can redistribute it and/or modify it
10;;; under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 3 of the License, or (at
12;;; your option) any later version.
13;;;
14;;; GNU Guix is distributed in the hope that it will be useful, but
15;;; WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
21
22(define-module (gnu services base)
e87f0591 23 #:use-module (guix store)
db4fdc04 24 #:use-module (gnu services)
0190c1c0 25 #:use-module (gnu services shepherd)
4a3b3b07 26 #:use-module (gnu services networking)
6e828634 27 #:use-module (gnu system pam)
db4fdc04 28 #:use-module (gnu system shadow) ; 'user-account', etc.
0adfe95a 29 #:use-module (gnu system file-systems) ; 'file-system', etc.
060d62a7 30 #:use-module (gnu system mapped-devices)
db4fdc04 31 #:use-module (gnu packages admin)
151a2c07 32 #:use-module ((gnu packages linux)
255f7308 33 #:select (eudev kbd e2fsprogs lvm2 fuse alsa-utils crda gpm))
db4fdc04 34 #:use-module ((gnu packages base)
bdb36958 35 #:select (canonical-package glibc))
db4fdc04 36 #:use-module (gnu packages package-management)
2d1d2dd8
LC
37 #:use-module (gnu packages lsh)
38 #:use-module (gnu packages lsof)
e2f4b305 39 #:use-module ((gnu build file-systems)
2c071ce9 40 #:select (mount-flags->bit-mask))
b5f4e686 41 #:use-module (guix gexp)
6454b333 42 #:use-module (guix records)
db4fdc04
LC
43 #:use-module (srfi srfi-1)
44 #:use-module (srfi srfi-26)
6454b333 45 #:use-module (ice-9 match)
db4fdc04 46 #:use-module (ice-9 format)
e43e84ba
LC
47 #:export (fstab-service-type
48 root-file-system-service
023f391c 49 file-system-service
d6e2a622 50 user-unmount-service
5dae0186 51 device-mapping-service
2a13d05e 52 swap-service
a00dd9fb 53 user-processes-service
e10964ef
SB
54 session-environment-service
55 session-environment-service-type
a00dd9fb 56 host-name-service
5eca9459 57 console-keymap-service
62ca0fdf 58 console-font-service
c797fabe
RW
59
60 udev-configuration
61 udev-configuration?
62 udev-configuration-rules
0adfe95a 63 udev-service-type
151a2c07 64 udev-service
80e6f37e 65 udev-rule
66e4f01c
LC
66
67 mingetty-configuration
68 mingetty-configuration?
db4fdc04 69 mingetty-service
cd6f6c22 70 mingetty-service-type
6454b333
LC
71
72 %nscd-default-caches
73 %nscd-default-configuration
74
75 nscd-configuration
76 nscd-configuration?
77
78 nscd-cache
79 nscd-cache?
80
0adfe95a 81 nscd-service-type
db4fdc04
LC
82 nscd-service
83 syslog-service
44abcb28 84 %default-syslog.conf
0adfe95a
LC
85
86 guix-configuration
87 guix-configuration?
8b198abe 88 guix-service
cd6f6c22 89 guix-service-type
1c52181f
LC
90 guix-publish-configuration
91 guix-publish-configuration?
92 guix-publish-service
93 guix-publish-service-type
8664cc88
LC
94 gpm-service-type
95 gpm-service
0adfe95a 96
8b198abe 97 %base-services))
db4fdc04
LC
98
99;;; Commentary:
100;;;
101;;; Base system services---i.e., services that 99% of the users will want to
102;;; use.
103;;;
104;;; Code:
105
0adfe95a
LC
106\f
107;;;
108;;; File systems.
109;;;
a00dd9fb 110
e43e84ba
LC
111(define (file-system->fstab-entry file-system)
112 "Return a @file{/etc/fstab} entry for @var{file-system}."
113 (string-append (case (file-system-title file-system)
114 ((label)
115 (string-append "LABEL=" (file-system-device file-system)))
116 ((uuid)
117 (string-append
118 "UUID="
119 (uuid->string (file-system-device file-system))))
120 (else
121 (file-system-device file-system)))
122 "\t"
123 (file-system-mount-point file-system) "\t"
124 (file-system-type file-system) "\t"
125 (or (file-system-options file-system) "defaults") "\t"
126
127 ;; XXX: Omit the 'fs_freq' and 'fs_passno' fields because we
128 ;; don't have anything sensible to put in there.
129 ))
130
131(define (file-systems->fstab file-systems)
132 "Return a @file{/etc} entry for an @file{fstab} describing
133@var{file-systems}."
134 `(("fstab" ,(plain-file "fstab"
135 (string-append
136 "\
137# This file was generated from your GuixSD configuration. Any changes
138# will be lost upon reboot or reconfiguration.\n\n"
139 (string-join (map file-system->fstab-entry
140 file-systems)
141 "\n")
142 "\n")))))
143
144(define fstab-service-type
145 ;; The /etc/fstab service.
146 (service-type (name 'fstab)
147 (extensions
148 (list (service-extension etc-service-type
149 file-systems->fstab)))
150 (compose identity)
151 (extend append)))
152
d4053c71
AK
153(define %root-file-system-shepherd-service
154 (shepherd-service
be1c2c54
LC
155 (documentation "Take care of the root file system.")
156 (provision '(root-file-system))
157 (start #~(const #t))
158 (stop #~(lambda _
159 ;; Return #f if successfully stopped.
160 (sync)
161
162 (call-with-blocked-asyncs
163 (lambda ()
164 (let ((null (%make-void-port "w")))
34044d55 165 ;; Close 'shepherd.log'.
be1c2c54 166 (display "closing log\n")
34044d55 167 ((@ (shepherd comm) stop-logging))
be1c2c54
LC
168
169 ;; Redirect the default output ports..
170 (set-current-output-port null)
171 (set-current-error-port null)
172
173 ;; Close /dev/console.
174 (for-each close-fdes '(0 1 2))
175
176 ;; At this point, there are no open files left, so the
177 ;; root file system can be re-mounted read-only.
178 (mount #f "/" #f
179 (logior MS_REMOUNT MS_RDONLY)
180 #:update-mtab? #f)
181
182 #f)))))
183 (respawn? #f)))
a00dd9fb 184
0adfe95a 185(define root-file-system-service-type
d4053c71
AK
186 (shepherd-service-type 'root-file-system
187 (const %root-file-system-shepherd-service)))
0adfe95a
LC
188
189(define (root-file-system-service)
190 "Return a service whose sole purpose is to re-mount read-only the root file
191system upon shutdown (aka. cleanly \"umounting\" root.)
192
193This service must be the root of the service dependency graph so that its
d4053c71 194'stop' action is invoked when shepherd is the only process left."
0adfe95a
LC
195 (service root-file-system-service-type #f))
196
d4053c71 197(define (file-system->shepherd-service-name file-system)
0adfe95a
LC
198 "Return the symbol that denotes the service mounting and unmounting
199FILE-SYSTEM."
200 (symbol-append 'file-system-
201 (string->symbol (file-system-mount-point file-system))))
202
d4053c71
AK
203(define (mapped-device->shepherd-service-name md)
204 "Return the symbol that denotes the shepherd service of MD, a <mapped-device>."
e502bf89
LC
205 (symbol-append 'device-mapping-
206 (string->symbol (mapped-device-target md))))
207
d4053c71 208(define dependency->shepherd-service-name
e502bf89
LC
209 (match-lambda
210 ((? mapped-device? md)
d4053c71 211 (mapped-device->shepherd-service-name md))
e502bf89 212 ((? file-system? fs)
d4053c71 213 (file-system->shepherd-service-name fs))))
e502bf89 214
d4053c71
AK
215(define (file-system-shepherd-service file-system)
216 "Return a list containing the shepherd service for @var{file-system}."
e43e84ba
LC
217 (let ((target (file-system-mount-point file-system))
218 (device (file-system-device file-system))
219 (type (file-system-type file-system))
220 (title (file-system-title file-system))
221 (check? (file-system-check? file-system))
222 (create? (file-system-create-mount-point? file-system))
223 (dependencies (file-system-dependencies file-system)))
be21979d
LC
224 (if (file-system-mount? file-system)
225 (list
d4053c71
AK
226 (shepherd-service
227 (provision (list (file-system->shepherd-service-name file-system)))
be21979d 228 (requirement `(root-file-system
d4053c71 229 ,@(map dependency->shepherd-service-name dependencies)))
be21979d
LC
230 (documentation "Check, mount, and unmount the given file system.")
231 (start #~(lambda args
232 ;; FIXME: Use or factorize with 'mount-file-system'.
233 (let ((device (canonicalize-device-spec #$device '#$title))
234 (flags #$(mount-flags->bit-mask
235 (file-system-flags file-system))))
236 #$(if create?
237 #~(mkdir-p #$target)
238 #~#t)
239 #$(if check?
240 #~(begin
241 ;; Make sure fsck.ext2 & co. can be found.
242 (setenv "PATH"
243 (string-append
244 #$e2fsprogs "/sbin:"
245 "/run/current-system/profile/sbin:"
246 (getenv "PATH")))
247 (check-file-system device #$type))
248 #~#t)
249
250 (mount device #$target #$type flags
251 #$(file-system-options file-system))
252
253 ;; For read-only bind mounts, an extra remount is
254 ;; needed, as per <http://lwn.net/Articles/281157/>,
255 ;; which still applies to Linux 4.0.
256 (when (and (= MS_BIND (logand flags MS_BIND))
257 (= MS_RDONLY (logand flags MS_RDONLY)))
258 (mount device #$target #$type
259 (logior MS_BIND MS_REMOUNT MS_RDONLY))))
260 #t))
261 (stop #~(lambda args
262 ;; Normally there are no processes left at this point, so
263 ;; TARGET can be safely unmounted.
264
265 ;; Make sure PID 1 doesn't keep TARGET busy.
266 (chdir "/")
267
268 (umount #$target)
269 #f))
270
271 ;; We need an additional module.
272 (modules `(((gnu build file-systems)
273 #:select (check-file-system canonicalize-device-spec))
274 ,@%default-modules))
275 (imported-modules `((gnu build file-systems)
6eb43907 276 (guix build bournish)
be21979d
LC
277 ,@%default-imported-modules))))
278 '())))
e43e84ba 279
0adfe95a
LC
280(define file-system-service-type
281 ;; TODO(?): Make this an extensible service that takes <file-system> objects
d4053c71 282 ;; and returns a list of <shepherd-service>.
e43e84ba
LC
283 (service-type (name 'file-system)
284 (extensions
d4053c71
AK
285 (list (service-extension shepherd-root-service-type
286 file-system-shepherd-service)
e43e84ba
LC
287 (service-extension fstab-service-type
288 identity)))))
0adfe95a
LC
289
290(define* (file-system-service file-system)
291 "Return a service that mounts @var{file-system}, a @code{<file-system>}
292object."
293 (service file-system-service-type file-system))
294
295(define user-unmount-service-type
d4053c71 296 (shepherd-service-type
5f44ee4f 297 'user-file-systems
0adfe95a 298 (lambda (known-mount-points)
d4053c71 299 (shepherd-service
0adfe95a 300 (documentation "Unmount manually-mounted file systems.")
5f44ee4f 301 (provision '(user-file-systems))
0adfe95a
LC
302 (start #~(const #t))
303 (stop #~(lambda args
304 (define (known? mount-point)
305 (member mount-point
306 (cons* "/proc" "/sys" '#$known-mount-points)))
307
308 ;; Make sure we don't keep the user's mount points busy.
309 (chdir "/")
310
311 (for-each (lambda (mount-point)
312 (format #t "unmounting '~a'...~%" mount-point)
313 (catch 'system-error
314 (lambda ()
315 (umount mount-point))
316 (lambda args
317 (let ((errno (system-error-errno args)))
318 (format #t "failed to unmount '~a': ~a~%"
319 mount-point (strerror errno))))))
320 (filter (negate known?) (mount-points)))
321 #f))))))
023f391c 322
d6e2a622
LC
323(define (user-unmount-service known-mount-points)
324 "Return a service whose sole purpose is to unmount file systems not listed
325in KNOWN-MOUNT-POINTS when it is stopped."
0adfe95a 326 (service user-unmount-service-type known-mount-points))
d6e2a622 327
7d57cfd3
LC
328(define %do-not-kill-file
329 ;; Name of the file listing PIDs of processes that must survive when halting
330 ;; the system. Typical example is user-space file systems.
b8c02c18 331 "/etc/shepherd/do-not-kill")
7d57cfd3 332
0adfe95a 333(define user-processes-service-type
d4053c71 334 (shepherd-service-type
00184239 335 'user-processes
0adfe95a
LC
336 (match-lambda
337 ((requirements grace-delay)
d4053c71 338 (shepherd-service
0adfe95a
LC
339 (documentation "When stopped, terminate all user processes.")
340 (provision '(user-processes))
5f44ee4f 341 (requirement (cons* 'root-file-system 'user-file-systems
d4053c71 342 (map file-system->shepherd-service-name
5f44ee4f 343 requirements)))
0adfe95a
LC
344 (start #~(const #t))
345 (stop #~(lambda _
346 (define (kill-except omit signal)
347 ;; Kill all the processes with SIGNAL except those listed
348 ;; in OMIT and the current process.
349 (let ((omit (cons (getpid) omit)))
350 (for-each (lambda (pid)
351 (unless (memv pid omit)
352 (false-if-exception
353 (kill pid signal))))
354 (processes))))
355
356 (define omitted-pids
357 ;; List of PIDs that must not be killed.
358 (if (file-exists? #$%do-not-kill-file)
359 (map string->number
360 (call-with-input-file #$%do-not-kill-file
361 (compose string-tokenize
362 (@ (ice-9 rdelim) read-string))))
363 '()))
364
365 (define (now)
366 (car (gettimeofday)))
367
368 (define (sleep* n)
369 ;; Really sleep N seconds.
370 ;; Work around <http://bugs.gnu.org/19581>.
371 (define start (now))
372 (let loop ((elapsed 0))
373 (when (> n elapsed)
374 (sleep (- n elapsed))
375 (loop (- (now) start)))))
376
377 (define lset= (@ (srfi srfi-1) lset=))
378
379 (display "sending all processes the TERM signal\n")
380
381 (if (null? omitted-pids)
382 (begin
383 ;; Easy: terminate all of them.
384 (kill -1 SIGTERM)
385 (sleep* #$grace-delay)
386 (kill -1 SIGKILL))
387 (begin
388 ;; Kill them all except OMITTED-PIDS. XXX: We would
389 ;; like to (kill -1 SIGSTOP) to get a fixed list of
390 ;; processes, like 'killall5' does, but that seems
391 ;; unreliable.
392 (kill-except omitted-pids SIGTERM)
393 (sleep* #$grace-delay)
394 (kill-except omitted-pids SIGKILL)
395 (delete-file #$%do-not-kill-file)))
396
397 (let wait ()
398 (let ((pids (processes)))
399 (unless (lset= = pids (cons 1 omitted-pids))
400 (format #t "waiting for process termination\
401 (processes left: ~s)~%"
402 pids)
403 (sleep* 2)
404 (wait))))
405
406 (display "all processes have been terminated\n")
407 #f))
408 (respawn? #f))))))
409
410(define* (user-processes-service file-systems #:key (grace-delay 4))
a00dd9fb
LC
411 "Return the service that is responsible for terminating all the processes so
412that the root file system can be re-mounted read-only, just before
413rebooting/halting. Processes still running GRACE-DELAY seconds after SIGTERM
414has been sent are terminated with SIGKILL.
415
d4053c71 416The returned service will depend on 'root-file-system' and on all the shepherd
0adfe95a 417services corresponding to FILE-SYSTEMS.
023f391c 418
a00dd9fb
LC
419All the services that spawn processes must depend on this one so that they are
420stopped before 'kill' is called."
0adfe95a 421 (service user-processes-service-type
be21979d 422 (list (filter file-system-mount? file-systems) grace-delay)))
d656c14e 423
0adfe95a 424\f
e10964ef
SB
425;;;
426;;; System-wide environment variables.
427;;;
428
429(define (environment-variables->environment-file vars)
430 "Return a file for pam_env(8) that contains environment variables VARS."
431 (apply mixed-text-file "environment"
432 (append-map (match-lambda
433 ((key . value)
434 (list key "=" value "\n")))
435 vars)))
436
437(define session-environment-service-type
438 (service-type
439 (name 'session-environment)
440 (extensions
441 (list (service-extension
442 etc-service-type
443 (lambda (vars)
444 (list `("environment"
445 ,(environment-variables->environment-file vars)))))))
446 (compose concatenate)
447 (extend append)))
448
449(define (session-environment-service vars)
450 "Return a service that builds the @file{/etc/environment}, which can be read
451by PAM-aware applications to set environment variables for sessions.
452
453VARS should be an association list in which both the keys and the values are
454strings or string-valued gexps."
455 (service session-environment-service-type vars))
456
457\f
0adfe95a
LC
458;;;
459;;; Console & co.
460;;;
461
462(define host-name-service-type
d4053c71 463 (shepherd-service-type
00184239 464 'host-name
0adfe95a 465 (lambda (name)
d4053c71 466 (shepherd-service
0adfe95a
LC
467 (documentation "Initialize the machine's host name.")
468 (provision '(host-name))
469 (start #~(lambda _
470 (sethostname #$name)))
471 (respawn? #f)))))
a00dd9fb 472
db4fdc04 473(define (host-name-service name)
51da7ca0 474 "Return a service that sets the host name to @var{name}."
0adfe95a 475 (service host-name-service-type name))
db4fdc04 476
62ca0fdf
LC
477(define (unicode-start tty)
478 "Return a gexp to start Unicode support on @var{tty}."
479
480 ;; We have to run 'unicode_start' in a pipe so that when it invokes the
481 ;; 'tty' command, that command returns TTY.
482 #~(begin
483 (let ((pid (primitive-fork)))
484 (case pid
485 ((0)
486 (close-fdes 0)
487 (dup2 (open-fdes #$tty O_RDONLY) 0)
488 (close-fdes 1)
489 (dup2 (open-fdes #$tty O_WRONLY) 1)
490 (execl (string-append #$kbd "/bin/unicode_start")
491 "unicode_start"))
492 (else
493 (zero? (cdr (waitpid pid))))))))
494
0adfe95a 495(define console-keymap-service-type
d4053c71 496 (shepherd-service-type
00184239 497 'console-keymap
b3d05f48 498 (lambda (files)
d4053c71 499 (shepherd-service
0adfe95a
LC
500 (documentation (string-append "Load console keymap (loadkeys)."))
501 (provision '(console-keymap))
502 (start #~(lambda _
503 (zero? (system* (string-append #$kbd "/bin/loadkeys")
b3d05f48 504 #$@files))))
0adfe95a
LC
505 (respawn? #f)))))
506
b3d05f48
AK
507(define (console-keymap-service . files)
508 "Return a service to load console keymaps from @var{files}."
509 (service console-keymap-service-type files))
0adfe95a
LC
510
511(define console-font-service-type
d4053c71 512 (shepherd-service-type
00184239 513 'console-font
0adfe95a
LC
514 (match-lambda
515 ((tty font)
516 (let ((device (string-append "/dev/" tty)))
d4053c71 517 (shepherd-service
0adfe95a
LC
518 (documentation "Load a Unicode console font.")
519 (provision (list (symbol-append 'console-font-
520 (string->symbol tty))))
521
522 ;; Start after mingetty has been started on TTY, otherwise the settings
523 ;; are ignored.
524 (requirement (list (symbol-append 'term-
525 (string->symbol tty))))
526
527 (start #~(lambda _
528 (and #$(unicode-start device)
529 (zero?
530 (system* (string-append #$kbd "/bin/setfont")
531 "-C" #$device #$font)))))
532 (stop #~(const #t))
533 (respawn? #f)))))))
5eca9459 534
62ca0fdf
LC
535(define* (console-font-service tty #:optional (font "LatGrkCyr-8x16"))
536 "Return a service that sets up Unicode support in @var{tty} and loads
537@var{font} for that tty (fonts are per virtual console in Linux.)"
538 ;; Note: 'LatGrkCyr-8x16' has the advantage of providing three common
539 ;; scripts as well as glyphs for em dash, quotation marks, and other Unicode
540 ;; codepoints notably found in the UTF-8 manual.
0adfe95a 541 (service console-font-service-type (list tty font)))
62ca0fdf 542
66e4f01c
LC
543(define-record-type* <mingetty-configuration>
544 mingetty-configuration make-mingetty-configuration
545 mingetty-configuration?
546 (mingetty mingetty-configuration-mingetty ;<package>
547 (default mingetty))
548 (tty mingetty-configuration-tty) ;string
549 (motd mingetty-configuration-motd ;file-like
550 (default (plain-file "motd" "Welcome.\n")))
551 (auto-login mingetty-auto-login ;string | #f
552 (default #f))
553 (login-program mingetty-login-program ;gexp
554 (default #f))
555 (login-pause? mingetty-login-pause? ;Boolean
556 (default #f))
557
558 ;; Allow empty passwords by default so that first-time users can log in when
559 ;; the 'root' account has just been created.
560 (allow-empty-passwords? mingetty-configuration-allow-empty-passwords?
561 (default #t))) ;Boolean
562
0adfe95a
LC
563(define (mingetty-pam-service conf)
564 "Return the list of PAM service needed for CONF."
565 ;; Let 'login' be known to PAM. All the mingetty services will have that
566 ;; PAM service, but that's fine because they're all identical and duplicates
567 ;; are removed.
568 (list (unix-pam-service "login"
569 #:allow-empty-passwords?
570 (mingetty-configuration-allow-empty-passwords? conf)
571 #:motd
572 (mingetty-configuration-motd conf))))
573
d4053c71 574(define mingetty-shepherd-service
0adfe95a 575 (match-lambda
66e4f01c
LC
576 (($ <mingetty-configuration> mingetty tty motd auto-login login-program
577 login-pause? allow-empty-passwords?)
0adfe95a 578 (list
d4053c71 579 (shepherd-service
0adfe95a
LC
580 (documentation "Run mingetty on an tty.")
581 (provision (list (symbol-append 'term- (string->symbol tty))))
582
583 ;; Since the login prompt shows the host name, wait for the 'host-name'
584 ;; service to be done. Also wait for udev essentially so that the tty
585 ;; text is not lost in the middle of kernel messages (XXX).
586 (requirement '(user-processes host-name udev))
587
588 (start #~(make-forkexec-constructor
589 (list (string-append #$mingetty "/sbin/mingetty")
590 "--noclear" #$tty
591 #$@(if auto-login
592 #~("--autologin" #$auto-login)
593 #~())
594 #$@(if login-program
595 #~("--loginprog" #$login-program)
596 #~())
597 #$@(if login-pause?
598 #~("--loginpause")
599 #~()))))
600 (stop #~(make-kill-destructor)))))))
601
602(define mingetty-service-type
603 (service-type (name 'mingetty)
d4053c71
AK
604 (extensions (list (service-extension shepherd-root-service-type
605 mingetty-shepherd-service)
0adfe95a
LC
606 (service-extension pam-root-service-type
607 mingetty-pam-service)))))
608
609(define* (mingetty-service config)
610 "Return a service to run mingetty according to @var{config}, which specifies
611the tty to run, among other things."
612 (service mingetty-service-type config))
db4fdc04 613
6454b333
LC
614(define-record-type* <nscd-configuration> nscd-configuration
615 make-nscd-configuration
616 nscd-configuration?
617 (log-file nscd-configuration-log-file ;string
618 (default "/var/log/nscd.log"))
619 (debug-level nscd-debug-level ;integer
620 (default 0))
621 ;; TODO: See nscd.conf in glibc for other options to add.
622 (caches nscd-configuration-caches ;list of <nscd-cache>
b893f1ae
LC
623 (default %nscd-default-caches))
624 (name-services nscd-configuration-name-services ;list of <packages>
625 (default '()))
626 (glibc nscd-configuration-glibc ;<package>
627 (default (canonical-package glibc))))
6454b333
LC
628
629(define-record-type* <nscd-cache> nscd-cache make-nscd-cache
630 nscd-cache?
631 (database nscd-cache-database) ;symbol
632 (positive-time-to-live nscd-cache-positive-time-to-live) ;integer
633 (negative-time-to-live nscd-cache-negative-time-to-live
634 (default 20)) ;integer
635 (suggested-size nscd-cache-suggested-size ;integer ("default module
636 ;of hash table")
637 (default 211))
638 (check-files? nscd-cache-check-files? ;Boolean
639 (default #t))
640 (persistent? nscd-cache-persistent? ;Boolean
641 (default #t))
642 (shared? nscd-cache-shared? ;Boolean
643 (default #t))
644 (max-database-size nscd-cache-max-database-size ;integer
645 (default (* 32 (expt 2 20))))
646 (auto-propagate? nscd-cache-auto-propagate? ;Boolean
647 (default #t)))
648
649(define %nscd-default-caches
650 ;; Caches that we want to enable by default. Note that when providing an
651 ;; empty nscd.conf, all caches are disabled.
652 (list (nscd-cache (database 'hosts)
653
654 ;; Aggressively cache the host name cache to improve
655 ;; privacy and resilience.
656 (positive-time-to-live (* 3600 12))
657 (negative-time-to-live 20)
658 (persistent? #t))
659
660 (nscd-cache (database 'services)
661
662 ;; Services are unlikely to change, so we can be even more
663 ;; aggressive.
664 (positive-time-to-live (* 3600 24))
665 (negative-time-to-live 3600)
666 (check-files? #t) ;check /etc/services changes
667 (persistent? #t))))
668
669(define %nscd-default-configuration
670 ;; Default nscd configuration.
671 (nscd-configuration))
672
673(define (nscd.conf-file config)
674 "Return the @file{nscd.conf} configuration file for @var{config}, an
675@code{<nscd-configuration>} object."
676 (define cache->config
677 (match-lambda
be1c2c54
LC
678 (($ <nscd-cache> (= symbol->string database)
679 positive-ttl negative-ttl size check-files?
680 persistent? shared? max-size propagate?)
681 (string-append "\nenable-cache\t" database "\tyes\n"
682
683 "positive-time-to-live\t" database "\t"
684 (number->string positive-ttl) "\n"
685 "negative-time-to-live\t" database "\t"
686 (number->string negative-ttl) "\n"
687 "suggested-size\t" database "\t"
688 (number->string size) "\n"
689 "check-files\t" database "\t"
690 (if check-files? "yes\n" "no\n")
691 "persistent\t" database "\t"
692 (if persistent? "yes\n" "no\n")
693 "shared\t" database "\t"
694 (if shared? "yes\n" "no\n")
695 "max-db-size\t" database "\t"
696 (number->string max-size) "\n"
697 "auto-propagate\t" database "\t"
698 (if propagate? "yes\n" "no\n")))))
6454b333
LC
699
700 (match config
701 (($ <nscd-configuration> log-file debug-level caches)
be1c2c54
LC
702 (plain-file "nscd.conf"
703 (string-append "\
6454b333 704# Configuration of libc's name service cache daemon (nscd).\n\n"
be1c2c54
LC
705 (if log-file
706 (string-append "logfile\t" log-file)
707 "")
708 "\n"
709 (if debug-level
710 (string-append "debug-level\t"
711 (number->string debug-level))
712 "")
713 "\n"
714 (string-concatenate
715 (map cache->config caches)))))))
6454b333 716
d4053c71
AK
717(define (nscd-shepherd-service config)
718 "Return a shepherd service for CONFIG, an <nscd-configuration> object."
0adfe95a
LC
719 (let ((nscd.conf (nscd.conf-file config))
720 (name-services (nscd-configuration-name-services config)))
d4053c71 721 (list (shepherd-service
0adfe95a
LC
722 (documentation "Run libc's name service cache daemon (nscd).")
723 (provision '(nscd))
724 (requirement '(user-processes))
725 (start #~(make-forkexec-constructor
726 (list (string-append #$(nscd-configuration-glibc config)
727 "/sbin/nscd")
728 "-f" #$nscd.conf "--foreground")
729
730 #:environment-variables
731 (list (string-append "LD_LIBRARY_PATH="
732 (string-join
733 (map (lambda (dir)
734 (string-append dir "/lib"))
735 (list #$@name-services))
736 ":")))))
cc7234ae 737 (stop #~(make-kill-destructor))))))
0adfe95a
LC
738
739(define nscd-activation
740 ;; Actions to take before starting nscd.
741 #~(begin
742 (use-modules (guix build utils))
743 (mkdir-p "/var/run/nscd")
744 (mkdir-p "/var/db/nscd"))) ;for the persistent cache
745
746(define nscd-service-type
747 (service-type (name 'nscd)
748 (extensions
749 (list (service-extension activation-service-type
750 (const nscd-activation))
d4053c71
AK
751 (service-extension shepherd-root-service-type
752 nscd-shepherd-service)))
0adfe95a
LC
753
754 ;; This can be extended by providing additional name services
755 ;; such as nss-mdns.
756 (compose concatenate)
757 (extend (lambda (config name-services)
758 (nscd-configuration
759 (inherit config)
760 (name-services (append
761 (nscd-configuration-name-services config)
762 name-services)))))))
763
b893f1ae 764(define* (nscd-service #:optional (config %nscd-default-configuration))
6454b333 765 "Return a service that runs libc's name service cache daemon (nscd) with the
b893f1ae
LC
766given @var{config}---an @code{<nscd-configuration>} object. @xref{Name
767Service Switch}, for an example."
0adfe95a
LC
768 (service nscd-service-type config))
769
770(define syslog-service-type
d4053c71 771 (shepherd-service-type
00184239 772 'syslog
0adfe95a 773 (lambda (config-file)
d4053c71 774 (shepherd-service
0adfe95a
LC
775 (documentation "Run the syslog daemon (syslogd).")
776 (provision '(syslogd))
777 (requirement '(user-processes))
778 (start #~(make-forkexec-constructor
779 (list (string-append #$inetutils "/libexec/syslogd")
780 "--no-detach" "--rcfile" #$config-file)))
781 (stop #~(make-kill-destructor))))))
be1c2c54
LC
782
783;; Snippet adapted from the GNU inetutils manual.
784(define %default-syslog.conf
785 (plain-file "syslog.conf" "
1f3fc60d 786 # Log all error messages, authentication messages of
db4fdc04
LC
787 # level notice or higher and anything of level err or
788 # higher to the console.
789 # Don't log private authentication messages!
6a191274 790 *.alert;auth.notice;authpriv.none /dev/console
db4fdc04
LC
791
792 # Log anything (except mail) of level info or higher.
793 # Don't log private authentication messages!
794 *.info;mail.none;authpriv.none /var/log/messages
795
796 # Same, in a different place.
797 *.info;mail.none;authpriv.none /dev/tty12
798
799 # The authpriv file has restricted access.
800 authpriv.* /var/log/secure
801
802 # Log all the mail messages in one place.
803 mail.* /var/log/maillog
be1c2c54 804"))
0adfe95a 805
be1c2c54 806(define* (syslog-service #:key (config-file %default-syslog.conf))
44abcb28
LC
807 "Return a service that runs @command{syslogd}. If configuration file
808name @var{config-file} is not specified, use some reasonable default
809settings.
810
811@xref{syslogd invocation,,, inetutils, GNU Inetutils}, for more
812information on the configuration file syntax."
0adfe95a 813 (service syslog-service-type config-file))
db4fdc04 814
1c52181f
LC
815\f
816;;;
817;;; Guix services.
818;;;
819
db4fdc04 820(define* (guix-build-accounts count #:key
ab6a279a 821 (group "guixbuild")
db4fdc04 822 (first-uid 30001)
db4fdc04
LC
823 (shadow shadow))
824 "Return a list of COUNT user accounts for Guix build users, with UIDs
825starting at FIRST-UID, and under GID."
5250a4f2
LC
826 (unfold (cut > <> count)
827 (lambda (n)
828 (user-account
829 (name (format #f "guixbuilder~2,'0d" n))
830 (system? #t)
831 (uid (+ first-uid n -1))
832 (group group)
833
834 ;; guix-daemon expects GROUP to be listed as a
835 ;; supplementary group too:
836 ;; <http://lists.gnu.org/archive/html/bug-guix/2013-01/msg00239.html>.
837 (supplementary-groups (list group "kvm"))
838
839 (comment (format #f "Guix Build User ~2d" n))
840 (home-directory "/var/empty")
841 (shell #~(string-append #$shadow "/sbin/nologin"))))
842 1+
843 1))
db4fdc04 844
2c5c696c
LC
845(define (hydra-key-authorization guix)
846 "Return a gexp with code to register the hydra.gnu.org public key with
847GUIX."
848 #~(unless (file-exists? "/etc/guix/acl")
849 (let ((pid (primitive-fork)))
850 (case pid
851 ((0)
852 (let* ((key (string-append #$guix
853 "/share/guix/hydra.gnu.org.pub"))
854 (port (open-file key "r0b")))
855 (format #t "registering public key '~a'...~%" key)
856 (close-port (current-input-port))
2c5c696c
LC
857 (dup port 0)
858 (execl (string-append #$guix "/bin/guix")
859 "guix" "archive" "--authorize")
860 (exit 1)))
861 (else
862 (let ((status (cdr (waitpid pid))))
863 (unless (zero? status)
864 (format (current-error-port) "warning: \
865failed to register hydra.gnu.org public key: ~a~%" status))))))))
866
0adfe95a
LC
867(define-record-type* <guix-configuration>
868 guix-configuration make-guix-configuration
869 guix-configuration?
870 (guix guix-configuration-guix ;<package>
871 (default guix))
872 (build-group guix-configuration-build-group ;string
873 (default "guixbuild"))
874 (build-accounts guix-configuration-build-accounts ;integer
875 (default 10))
876 (authorize-key? guix-configuration-authorize-key? ;Boolean
877 (default #t))
878 (use-substitutes? guix-configuration-use-substitutes? ;Boolean
879 (default #t))
b0b9f6e0
LC
880 (substitute-urls guix-configuration-substitute-urls ;list of strings
881 (default %default-substitute-urls))
0adfe95a
LC
882 (extra-options guix-configuration-extra-options ;list of strings
883 (default '()))
884 (lsof guix-configuration-lsof ;<package>
885 (default lsof))
886 (lsh guix-configuration-lsh ;<package>
887 (default lsh)))
888
889(define %default-guix-configuration
890 (guix-configuration))
891
d4053c71
AK
892(define (guix-shepherd-service config)
893 "Return a <shepherd-service> for the Guix daemon service with CONFIG."
0adfe95a
LC
894 (match config
895 (($ <guix-configuration> guix build-group build-accounts authorize-key?
b0b9f6e0
LC
896 use-substitutes? substitute-urls extra-options
897 lsof lsh)
d4053c71 898 (list (shepherd-service
0adfe95a
LC
899 (documentation "Run the Guix daemon.")
900 (provision '(guix-daemon))
901 (requirement '(user-processes))
902 (start
903 #~(make-forkexec-constructor
904 (list (string-append #$guix "/bin/guix-daemon")
905 "--build-users-group" #$build-group
906 #$@(if use-substitutes?
907 '()
908 '("--no-substitutes"))
b0b9f6e0 909 "--substitute-urls" #$(string-join substitute-urls)
0adfe95a
LC
910 #$@extra-options)
911
912 ;; Add 'lsof' (for the GC) and 'lsh' (for offloading) to the
913 ;; daemon's $PATH.
914 #:environment-variables
915 (list (string-append "PATH=" #$lsof "/bin:" #$lsh "/bin"))))
916 (stop #~(make-kill-destructor)))))))
917
918(define (guix-accounts config)
919 "Return the user accounts and user groups for CONFIG."
920 (match config
921 (($ <guix-configuration> _ build-group build-accounts)
922 (cons (user-group
923 (name build-group)
924 (system? #t)
925
926 ;; Use a fixed GID so that we can create the store with the right
927 ;; owner.
928 (id 30000))
929 (guix-build-accounts build-accounts
930 #:group build-group)))))
931
932(define (guix-activation config)
933 "Return the activation gexp for CONFIG."
934 (match config
935 (($ <guix-configuration> guix build-group build-accounts authorize-key?)
936 ;; Assume that the store has BUILD-GROUP as its group. We could
937 ;; otherwise call 'chown' here, but the problem is that on a COW unionfs,
938 ;; chown leads to an entire copy of the tree, which is a bad idea.
939
940 ;; Optionally authorize hydra.gnu.org's key.
941 (and authorize-key?
942 (hydra-key-authorization guix)))))
943
944(define guix-service-type
945 (service-type
946 (name 'guix)
947 (extensions
d4053c71 948 (list (service-extension shepherd-root-service-type guix-shepherd-service)
0adfe95a 949 (service-extension account-service-type guix-accounts)
9a8b9eb8
LC
950 (service-extension activation-service-type guix-activation)
951 (service-extension profile-service-type
952 (compose list guix-configuration-guix))))))
0adfe95a
LC
953
954(define* (guix-service #:optional (config %default-guix-configuration))
955 "Return a service that runs the Guix build daemon according to
956@var{config}."
957 (service guix-service-type config))
958
1c52181f
LC
959
960(define-record-type* <guix-publish-configuration>
961 guix-publish-configuration make-guix-publish-configuration
962 guix-publish-configuration?
963 (guix guix-publish-configuration-guix ;package
964 (default guix))
965 (port guix-publish-configuration-port ;number
966 (default 80))
967 (host guix-publish-configuration-host ;string
968 (default "localhost")))
969
d4053c71 970(define guix-publish-shepherd-service
1c52181f
LC
971 (match-lambda
972 (($ <guix-publish-configuration> guix port host)
d4053c71 973 (list (shepherd-service
1c52181f
LC
974 (provision '(guix-publish))
975 (requirement '(guix-daemon))
976 (start #~(make-forkexec-constructor
977 (list (string-append #$guix "/bin/guix")
978 "publish" "-u" "guix-publish"
979 "-p" #$(number->string port)
980 (string-append "--listen=" #$host))))
981 (stop #~(make-kill-destructor)))))))
982
983(define %guix-publish-accounts
984 (list (user-group (name "guix-publish") (system? #t))
985 (user-account
986 (name "guix-publish")
987 (group "guix-publish")
988 (system? #t)
989 (comment "guix publish user")
990 (home-directory "/var/empty")
991 (shell #~(string-append #$shadow "/sbin/nologin")))))
992
993(define guix-publish-service-type
994 (service-type (name 'guix-publish)
995 (extensions
d4053c71
AK
996 (list (service-extension shepherd-root-service-type
997 guix-publish-shepherd-service)
1c52181f
LC
998 (service-extension account-service-type
999 (const %guix-publish-accounts))))))
1000
1001(define* (guix-publish-service #:key (guix guix) (port 80) (host "localhost"))
1002 "Return a service that runs @command{guix publish} listening on @var{host}
1003and @var{port} (@pxref{Invoking guix publish}).
1004
1005This assumes that @file{/etc/guix} already contains a signing key pair as
1006created by @command{guix archive --generate-key} (@pxref{Invoking guix
1007archive}). If that is not the case, the service will fail to start."
1008 (service guix-publish-service-type
1009 (guix-publish-configuration (guix guix) (port port) (host host))))
1010
0adfe95a
LC
1011\f
1012;;;
1013;;; Udev.
1014;;;
1015
1016(define-record-type* <udev-configuration>
1017 udev-configuration make-udev-configuration
1018 udev-configuration?
1019 (udev udev-configuration-udev ;<package>
1020 (default udev))
1021 (rules udev-configuration-rules ;list of <package>
1022 (default '())))
db4fdc04 1023
ecd06ca9
LC
1024(define (udev-rules-union packages)
1025 "Return the union of the @code{lib/udev/rules.d} directories found in each
1026item of @var{packages}."
1027 (define build
1028 #~(begin
1029 (use-modules (guix build union)
1030 (guix build utils)
1031 (srfi srfi-1)
1032 (srfi srfi-26))
1033
1034 (define %standard-locations
1035 '("/lib/udev/rules.d" "/libexec/udev/rules.d"))
1036
1037 (define (rules-sub-directory directory)
1038 ;; Return the sub-directory of DIRECTORY containing udev rules, or
1039 ;; #f if none was found.
1040 (find directory-exists?
1041 (map (cut string-append directory <>) %standard-locations)))
1042
1043 (mkdir-p (string-append #$output "/lib/udev"))
1044 (union-build (string-append #$output "/lib/udev/rules.d")
1045 (filter-map rules-sub-directory '#$packages))))
1046
be1c2c54
LC
1047 (computed-file "udev-rules" build
1048 #:modules '((guix build union)
1049 (guix build utils))))
ecd06ca9 1050
80e6f37e
RW
1051(define (udev-rule file-name contents)
1052 "Return a directory with a udev rule file FILE-NAME containing CONTENTS."
1053 (computed-file file-name
be1c2c54
LC
1054 #~(begin
1055 (use-modules (guix build utils))
1056
1057 (define rules.d
1058 (string-append #$output "/lib/udev/rules.d"))
1059
1060 (mkdir-p rules.d)
1061 (call-with-output-file
80e6f37e 1062 (string-append rules.d "/" #$file-name)
be1c2c54 1063 (lambda (port)
80e6f37e 1064 (display #$contents port))))
be1c2c54 1065 #:modules '((guix build utils))))
7f28bf9a 1066
80e6f37e
RW
1067(define kvm-udev-rule
1068 ;; Return a directory with a udev rule that changes the group of /dev/kvm to
1069 ;; "kvm" and makes it #o660. Apparently QEMU-KVM used to ship this rule,
1070 ;; but now we have to add it by ourselves.
1071
1072 ;; Build users are part of the "kvm" group, so we can fearlessly make
1073 ;; /dev/kvm 660 (see <http://bugs.gnu.org/18994>, for background.)
1074 (udev-rule "90-kvm.rules"
1075 "KERNEL==\"kvm\", GROUP=\"kvm\", MODE=\"0660\"\n"))
1076
d4053c71
AK
1077(define udev-shepherd-service
1078 ;; Return a <shepherd-service> for UDEV with RULES.
0adfe95a
LC
1079 (match-lambda
1080 (($ <udev-configuration> udev rules)
80e6f37e 1081 (let* ((rules (udev-rules-union (cons* udev kvm-udev-rule rules)))
0adfe95a
LC
1082 (udev.conf (computed-file "udev.conf"
1083 #~(call-with-output-file #$output
1084 (lambda (port)
1085 (format port
1086 "udev_rules=\"~a/lib/udev/rules.d\"\n"
1087 #$rules))))))
1088 (list
d4053c71 1089 (shepherd-service
0adfe95a
LC
1090 (provision '(udev))
1091
1092 ;; Udev needs /dev to be a 'devtmpfs' mount so that new device nodes can
1093 ;; be added: see
1094 ;; <http://www.linuxfromscratch.org/lfs/view/development/chapter07/udev.html>.
1095 (requirement '(root-file-system))
1096
1097 (documentation "Populate the /dev directory, dynamically.")
1098 (start #~(lambda ()
1099 (define find
1100 (@ (srfi srfi-1) find))
1101
1102 (define udevd
1103 ;; Choose the right 'udevd'.
1104 (find file-exists?
1105 (map (lambda (suffix)
1106 (string-append #$udev suffix))
1107 '("/libexec/udev/udevd" ;udev
1108 "/sbin/udevd")))) ;eudev
1109
1110 (define (wait-for-udevd)
1111 ;; Wait until someone's listening on udevd's control
1112 ;; socket.
1113 (let ((sock (socket AF_UNIX SOCK_SEQPACKET 0)))
1114 (let try ()
1115 (catch 'system-error
1116 (lambda ()
1117 (connect sock PF_UNIX "/run/udev/control")
1118 (close-port sock))
1119 (lambda args
1120 (format #t "waiting for udevd...~%")
1121 (usleep 500000)
1122 (try))))))
1123
1124 ;; Allow udev to find the modules.
1125 (setenv "LINUX_MODULE_DIRECTORY"
1126 "/run/booted-system/kernel/lib/modules")
1127
1128 ;; The first one is for udev, the second one for eudev.
1129 (setenv "UDEV_CONFIG_FILE" #$udev.conf)
1130 (setenv "EUDEV_RULES_DIRECTORY"
1131 (string-append #$rules "/lib/udev/rules.d"))
1132
1133 (let ((pid (primitive-fork)))
1134 (case pid
1135 ((0)
1136 (exec-command (list udevd)))
1137 (else
1138 ;; Wait until udevd is up and running. This
1139 ;; appears to be needed so that the events
1140 ;; triggered below are actually handled.
1141 (wait-for-udevd)
1142
1143 ;; Trigger device node creation.
1144 (system* (string-append #$udev "/bin/udevadm")
1145 "trigger" "--action=add")
1146
1147 ;; Wait for things to settle down.
1148 (system* (string-append #$udev "/bin/udevadm")
1149 "settle")
1150 pid)))))
1151 (stop #~(make-kill-destructor))
1152
1153 ;; When halting the system, 'udev' is actually killed by
1154 ;; 'user-processes', i.e., before its own 'stop' method was called.
1155 ;; Thus, make sure it is not respawned.
1156 (respawn? #f)))))))
1157
1158(define udev-service-type
1159 (service-type (name 'udev)
1160 (extensions
d4053c71
AK
1161 (list (service-extension shepherd-root-service-type
1162 udev-shepherd-service)))
0adfe95a
LC
1163
1164 (compose concatenate) ;concatenate the list of rules
1165 (extend (lambda (config rules)
1166 (match config
1167 (($ <udev-configuration> udev initial-rules)
1168 (udev-configuration
1169 (udev udev)
1170 (rules (append initial-rules rules)))))))))
1171
255f7308 1172(define* (udev-service #:key (udev eudev) (rules '()))
ecd06ca9
LC
1173 "Run @var{udev}, which populates the @file{/dev} directory dynamically. Get
1174extra rules from the packages listed in @var{rules}."
0adfe95a
LC
1175 (service udev-service-type
1176 (udev-configuration (udev udev) (rules rules))))
1177
1178(define device-mapping-service-type
d4053c71 1179 (shepherd-service-type
00184239 1180 'device-mapping
0adfe95a
LC
1181 (match-lambda
1182 ((target open close)
d4053c71 1183 (shepherd-service
0adfe95a
LC
1184 (provision (list (symbol-append 'device-mapping- (string->symbol target))))
1185 (requirement '(udev))
1186 (documentation "Map a device node using Linux's device mapper.")
1187 (start #~(lambda () #$open))
1188 (stop #~(lambda _ (not #$close)))
1189 (respawn? #f))))))
151a2c07 1190
722554a3 1191(define (device-mapping-service target open close)
5dae0186 1192 "Return a service that maps device @var{target}, a string such as
722554a3
LC
1193@code{\"home\"} (meaning @code{/dev/mapper/home}). Evaluate @var{open}, a
1194gexp, to open it, and evaluate @var{close} to close it."
0adfe95a
LC
1195 (service device-mapping-service-type
1196 (list target open close)))
1197
1198(define swap-service-type
d4053c71 1199 (shepherd-service-type
00184239 1200 'swap
0adfe95a
LC
1201 (lambda (device)
1202 (define requirement
1203 (if (string-prefix? "/dev/mapper/" device)
1204 (list (symbol-append 'device-mapping-
1205 (string->symbol (basename device))))
1206 '()))
1207
d4053c71 1208 (shepherd-service
0adfe95a
LC
1209 (provision (list (symbol-append 'swap- (string->symbol device))))
1210 (requirement `(udev ,@requirement))
1211 (documentation "Enable the given swap device.")
1212 (start #~(lambda ()
1213 (restart-on-EINTR (swapon #$device))
1214 #t))
1215 (stop #~(lambda _
1216 (restart-on-EINTR (swapoff #$device))
1217 #f))
1218 (respawn? #f)))))
5dae0186 1219
2a13d05e
LC
1220(define (swap-service device)
1221 "Return a service that uses @var{device} as a swap device."
0adfe95a 1222 (service swap-service-type device))
2a13d05e 1223
8664cc88
LC
1224
1225(define-record-type* <gpm-configuration>
1226 gpm-configuration make-gpm-configuration gpm-configuration?
1227 (gpm gpm-configuration-gpm) ;package
1228 (options gpm-configuration-options)) ;list of strings
1229
d4053c71 1230(define gpm-shepherd-service
8664cc88 1231 (match-lambda
a907d997 1232 (($ <gpm-configuration> gpm options)
d4053c71 1233 (list (shepherd-service
8664cc88
LC
1234 (requirement '(udev))
1235 (provision '(gpm))
1236 (start #~(lambda ()
1237 ;; 'gpm' runs in the background and sets a PID file.
1238 ;; Note that it requires running as "root".
1239 (false-if-exception (delete-file "/var/run/gpm.pid"))
1240 (fork+exec-command (list (string-append #$gpm "/sbin/gpm")
1241 #$@options))
1242
1243 ;; Wait for the PID file to appear; declare failure if
1244 ;; it doesn't show up.
1245 (let loop ((i 3))
1246 (or (file-exists? "/var/run/gpm.pid")
1247 (if (zero? i)
1248 #f
1249 (begin
1250 (sleep 1)
1251 (loop (1- i))))))))
1252
1253 (stop #~(lambda (_)
1254 ;; Return #f if successfully stopped.
1255 (not (zero? (system* (string-append #$gpm "/sbin/gpm")
1256 "-k"))))))))))
1257
1258(define gpm-service-type
1259 (service-type (name 'gpm)
1260 (extensions
d4053c71
AK
1261 (list (service-extension shepherd-root-service-type
1262 gpm-shepherd-service)))))
8664cc88
LC
1263
1264(define* (gpm-service #:key (gpm gpm)
1265 (options '("-m" "/dev/input/mice" "-t" "ps2")))
1266 "Run @var{gpm}, the general-purpose mouse daemon, with the given
1267command-line @var{options}. GPM allows users to use the mouse in the console,
1268notably to select, copy, and paste text. The default value of @var{options}
1269uses the @code{ps2} protocol, which works for both USB and PS/2 mice.
1270
1271This service is not part of @var{%base-services}."
1272 ;; To test in QEMU, use "-usbdevice mouse" and then, in the monitor, use
1273 ;; "info mice" and "mouse_set X" to use the right mouse.
1274 (service gpm-service-type
1275 (gpm-configuration (gpm gpm) (options options))))
1276
1277\f
8b198abe
LC
1278(define %base-services
1279 ;; Convenience variable holding the basic services.
ce8a6dfc 1280 (let ((motd (plain-file "motd" "
8b198abe 1281This is the GNU operating system, welcome!\n\n")))
62ca0fdf
LC
1282 (list (console-font-service "tty1")
1283 (console-font-service "tty2")
1284 (console-font-service "tty3")
1285 (console-font-service "tty4")
1286 (console-font-service "tty5")
1287 (console-font-service "tty6")
1288
66e4f01c
LC
1289 (mingetty-service (mingetty-configuration
1290 (tty "tty1") (motd motd)))
1291 (mingetty-service (mingetty-configuration
1292 (tty "tty2") (motd motd)))
1293 (mingetty-service (mingetty-configuration
1294 (tty "tty3") (motd motd)))
1295 (mingetty-service (mingetty-configuration
1296 (tty "tty4") (motd motd)))
1297 (mingetty-service (mingetty-configuration
1298 (tty "tty5") (motd motd)))
1299 (mingetty-service (mingetty-configuration
1300 (tty "tty6") (motd motd)))
1301
4a3b3b07
LC
1302 (static-networking-service "lo" "127.0.0.1"
1303 #:provision '(loopback))
8b198abe
LC
1304 (syslog-service)
1305 (guix-service)
151a2c07 1306 (nscd-service)
ecd06ca9 1307
52bd5734
LC
1308 ;; The LVM2 rules are needed as soon as LVM2 or the device-mapper is
1309 ;; used, so enable them by default. The FUSE and ALSA rules are
1310 ;; less critical, but handy.
68ac258b 1311 (udev-service #:rules (list lvm2 fuse alsa-utils crda)))))
8b198abe 1312
db4fdc04 1313;;; base.scm ends here