gnu: eudev: Honor $EUDEV_RULES_DIRECTORY.
[jackhill/guix/guix.git] / gnu / services / base.scm
CommitLineData
db4fdc04
LC
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org>
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (gnu services base)
185f6691
LC
20 #:use-module ((guix store)
21 #:select (%store-prefix))
db4fdc04 22 #:use-module (gnu services)
4a3b3b07 23 #:use-module (gnu services networking)
db4fdc04
LC
24 #:use-module (gnu system shadow) ; 'user-account', etc.
25 #:use-module (gnu system linux) ; 'pam-service', etc.
26 #:use-module (gnu packages admin)
151a2c07 27 #:use-module ((gnu packages linux)
ecd06ca9 28 #:select (udev kbd e2fsprogs lvm2))
db4fdc04 29 #:use-module ((gnu packages base)
bdb36958 30 #:select (canonical-package glibc))
db4fdc04 31 #:use-module (gnu packages package-management)
e2f4b305 32 #:use-module ((gnu build file-systems)
2c071ce9 33 #:select (mount-flags->bit-mask))
b5f4e686 34 #:use-module (guix gexp)
db4fdc04
LC
35 #:use-module (guix monads)
36 #:use-module (srfi srfi-1)
37 #:use-module (srfi srfi-26)
38 #:use-module (ice-9 format)
a00dd9fb 39 #:export (root-file-system-service
023f391c 40 file-system-service
5dae0186 41 device-mapping-service
a00dd9fb
LC
42 user-processes-service
43 host-name-service
62ca0fdf 44 console-font-service
151a2c07 45 udev-service
db4fdc04
LC
46 mingetty-service
47 nscd-service
48 syslog-service
8b198abe
LC
49 guix-service
50 %base-services))
db4fdc04
LC
51
52;;; Commentary:
53;;;
54;;; Base system services---i.e., services that 99% of the users will want to
55;;; use.
56;;;
57;;; Code:
58
a00dd9fb
LC
59(define (root-file-system-service)
60 "Return a service whose sole purpose is to re-mount read-only the root file
61system upon shutdown (aka. cleanly \"umounting\" root.)
62
63This service must be the root of the service dependency graph so that its
64'stop' action is invoked when dmd is the only process left."
a00dd9fb
LC
65 (with-monad %store-monad
66 (return
67 (service
68 (documentation "Take care of the root file system.")
69 (provision '(root-file-system))
70 (start #~(const #t))
71 (stop #~(lambda _
72 ;; Return #f if successfully stopped.
23ed63a1 73 (sync)
a00dd9fb
LC
74
75 (call-with-blocked-asyncs
76 (lambda ()
77 (let ((null (%make-void-port "w")))
78 ;; Close 'dmd.log'.
79 (display "closing log\n")
80 ;; XXX: Ideally we'd use 'stop-logging', but that one
81 ;; doesn't actually close the port as of dmd 0.1.
82 (close-port (@@ (dmd comm) log-output-port))
83 (set! (@@ (dmd comm) log-output-port) null)
84
85 ;; Redirect the default output ports..
86 (set-current-output-port null)
87 (set-current-error-port null)
88
89 ;; Close /dev/console.
90 (for-each close-fdes '(0 1 2))
91
23ed63a1 92 ;; At this point, there are no open files left, so the
a00dd9fb 93 ;; root file system can be re-mounted read-only.
23ed63a1
LC
94 (mount #f "/" #f
95 (logior MS_REMOUNT MS_RDONLY)
96 #:update-mtab? #f)
97
98 #f)))))
a00dd9fb
LC
99 (respawn? #f)))))
100
023f391c 101(define* (file-system-service device target type
2c071ce9 102 #:key (flags '()) (check? #t)
5dae0186
LC
103 create-mount-point? options (title 'any)
104 (requirements '()))
023f391c 105 "Return a service that mounts DEVICE on TARGET as a file system TYPE with
d4c87617
LC
106OPTIONS. TITLE is a symbol specifying what kind of name DEVICE is: 'label for
107a partition label, 'device for a device file name, or 'any. When CHECK? is
4e469051 108true, check the file system before mounting it. When CREATE-MOUNT-POINT? is
2c071ce9 109true, create TARGET if it does not exist yet. FLAGS is a list of symbols,
5dae0186
LC
110such as 'read-only' etc. Optionally, REQUIREMENTS may be a list of service
111names such as device-mapping services."
023f391c
LC
112 (with-monad %store-monad
113 (return
114 (service
115 (provision (list (symbol-append 'file-system- (string->symbol target))))
5dae0186 116 (requirement `(root-file-system ,@requirements))
023f391c
LC
117 (documentation "Check, mount, and unmount the given file system.")
118 (start #~(lambda args
d4c87617 119 (let ((device (canonicalize-device-spec #$device '#$title)))
4e469051
LC
120 #$(if create-mount-point?
121 #~(mkdir-p #$target)
122 #~#t)
d4c87617 123 #$(if check?
1b09031f
LC
124 #~(begin
125 ;; Make sure fsck.ext2 & co. can be found.
126 (setenv "PATH"
127 (string-append
128 #$e2fsprogs "/sbin:"
129 "/run/current-system/profile/sbin:"
130 (getenv "PATH")))
131 (check-file-system device #$type))
d4c87617 132 #~#t)
2c071ce9
LC
133 (mount device #$target #$type
134 #$(mount-flags->bit-mask flags)
135 #$options))
023f391c
LC
136 #t))
137 (stop #~(lambda args
138 ;; Normally there are no processes left at this point, so
139 ;; TARGET can be safely unmounted.
140 (umount #$target)
141 #f))))))
142
7d57cfd3
LC
143(define %do-not-kill-file
144 ;; Name of the file listing PIDs of processes that must survive when halting
145 ;; the system. Typical example is user-space file systems.
146 "/etc/dmd/do-not-kill")
147
023f391c 148(define* (user-processes-service requirements #:key (grace-delay 2))
a00dd9fb
LC
149 "Return the service that is responsible for terminating all the processes so
150that the root file system can be re-mounted read-only, just before
151rebooting/halting. Processes still running GRACE-DELAY seconds after SIGTERM
152has been sent are terminated with SIGKILL.
153
023f391c
LC
154The returned service will depend on 'root-file-system' and on all the services
155listed in REQUIREMENTS.
156
a00dd9fb
LC
157All the services that spawn processes must depend on this one so that they are
158stopped before 'kill' is called."
159 (with-monad %store-monad
160 (return (service
161 (documentation "When stopped, terminate all user processes.")
162 (provision '(user-processes))
023f391c 163 (requirement (cons 'root-file-system requirements))
a00dd9fb
LC
164 (start #~(const #t))
165 (stop #~(lambda _
7d57cfd3
LC
166 (define (kill-except omit signal)
167 ;; Kill all the processes with SIGNAL except those
168 ;; listed in OMIT and the current process.
169 (let ((omit (cons (getpid) omit)))
170 (for-each (lambda (pid)
171 (unless (memv pid omit)
172 (false-if-exception
173 (kill pid signal))))
174 (processes))))
175
176 (define omitted-pids
177 ;; List of PIDs that must not be killed.
178 (if (file-exists? #$%do-not-kill-file)
179 (map string->number
180 (call-with-input-file #$%do-not-kill-file
181 (compose string-tokenize
182 (@ (ice-9 rdelim) read-string))))
183 '()))
184
a00dd9fb
LC
185 ;; When this happens, all the processes have been
186 ;; killed, including 'deco', so DMD-OUTPUT-PORT and
187 ;; thus CURRENT-OUTPUT-PORT are dangling.
188 (call-with-output-file "/dev/console"
189 (lambda (port)
190 (display "sending all processes the TERM signal\n"
191 port)))
192
7d57cfd3
LC
193 (if (null? omitted-pids)
194 (begin
195 ;; Easy: terminate all of them.
196 (kill -1 SIGTERM)
197 (sleep #$grace-delay)
198 (kill -1 SIGKILL))
199 (begin
200 ;; Kill them all except OMITTED-PIDS. XXX: We
201 ;; would like to (kill -1 SIGSTOP) to get a fixed
202 ;; list of processes, like 'killall5' does, but
203 ;; that seems unreliable.
204 (kill-except omitted-pids SIGTERM)
205 (sleep #$grace-delay)
206 (kill-except omitted-pids SIGKILL)
207 (delete-file #$%do-not-kill-file)))
a00dd9fb
LC
208
209 (display "all processes have been terminated\n")
210 #f))
211 (respawn? #f)))))
212
db4fdc04 213(define (host-name-service name)
51da7ca0 214 "Return a service that sets the host name to @var{name}."
db4fdc04
LC
215 (with-monad %store-monad
216 (return (service
217 (documentation "Initialize the machine's host name.")
218 (provision '(host-name))
b5f4e686
LC
219 (start #~(lambda _
220 (sethostname #$name)))
db4fdc04
LC
221 (respawn? #f)))))
222
62ca0fdf
LC
223(define (unicode-start tty)
224 "Return a gexp to start Unicode support on @var{tty}."
225
226 ;; We have to run 'unicode_start' in a pipe so that when it invokes the
227 ;; 'tty' command, that command returns TTY.
228 #~(begin
229 (let ((pid (primitive-fork)))
230 (case pid
231 ((0)
232 (close-fdes 0)
233 (dup2 (open-fdes #$tty O_RDONLY) 0)
234 (close-fdes 1)
235 (dup2 (open-fdes #$tty O_WRONLY) 1)
236 (execl (string-append #$kbd "/bin/unicode_start")
237 "unicode_start"))
238 (else
239 (zero? (cdr (waitpid pid))))))))
240
241(define* (console-font-service tty #:optional (font "LatGrkCyr-8x16"))
242 "Return a service that sets up Unicode support in @var{tty} and loads
243@var{font} for that tty (fonts are per virtual console in Linux.)"
244 ;; Note: 'LatGrkCyr-8x16' has the advantage of providing three common
245 ;; scripts as well as glyphs for em dash, quotation marks, and other Unicode
246 ;; codepoints notably found in the UTF-8 manual.
247 (let ((device (string-append "/dev/" tty)))
248 (with-monad %store-monad
249 (return (service
250 (documentation "Load a Unicode console font.")
251 (provision (list (symbol-append 'console-font-
252 (string->symbol tty))))
253
254 ;; Start after mingetty has been started on TTY, otherwise the
255 ;; settings are ignored.
256 (requirement (list (symbol-append 'term-
257 (string->symbol tty))))
258
259 (start #~(lambda _
260 (and #$(unicode-start device)
261 (zero?
262 (system* (string-append #$kbd "/bin/setfont")
263 "-C" #$device #$font)))))
264 (stop #~(const #t))
265 (respawn? #f))))))
266
db4fdc04
LC
267(define* (mingetty-service tty
268 #:key
269 (motd (text-file "motd" "Welcome.\n"))
52322163
LC
270 auto-login
271 login-program
272 login-pause?
51da7ca0
LC
273
274 ;; Allow empty passwords by default so that
275 ;; first-time users can log in when the 'root'
276 ;; account has just been created.
db4fdc04 277 (allow-empty-passwords? #t))
52322163
LC
278 "Return a service to run mingetty on @var{tty}.
279
280When @var{allow-empty-passwords?} is true, allow empty log-in password. When
281@var{auto-login} is true, it must be a user name under which to log-in
282automatically. @var{login-pause?} can be set to @code{#t} in conjunction with
283@var{auto-login}, in which case the user will have to press a key before the
284login shell is launched.
285
286When true, @var{login-program} is a gexp or a monadic gexp denoting the name
287of the log-in program (the default is the @code{login} program from the Shadow
288tool suite.)
289
290@var{motd} is a monadic value containing a text file to use as
51da7ca0 291the ``message of the day''."
52322163
LC
292 (mlet %store-monad ((motd motd)
293 (login-program (cond ((gexp? login-program)
294 (return login-program))
295 ((not login-program)
296 (return #f))
297 (else
298 login-program))))
db4fdc04
LC
299 (return
300 (service
301 (documentation (string-append "Run mingetty on " tty "."))
302 (provision (list (symbol-append 'term- (string->symbol tty))))
303
304 ;; Since the login prompt shows the host name, wait for the 'host-name'
305 ;; service to be done.
a00dd9fb 306 (requirement '(user-processes host-name))
db4fdc04 307
b5f4e686 308 (start #~(make-forkexec-constructor
1c6b445b
LC
309 (list (string-append #$mingetty "/sbin/mingetty")
310 "--noclear" #$tty
311 #$@(if auto-login
312 #~("--autologin" #$auto-login)
313 #~())
314 #$@(if login-program
315 #~("--loginprog" #$login-program)
316 #~())
317 #$@(if login-pause?
318 #~("--loginpause")
319 #~()))))
b5f4e686 320 (stop #~(make-kill-destructor))
db4fdc04
LC
321
322 (pam-services
323 ;; Let 'login' be known to PAM. All the mingetty services will have
324 ;; that PAM service, but that's fine because they're all identical and
325 ;; duplicates are removed.
326 (list (unix-pam-service "login"
327 #:allow-empty-passwords? allow-empty-passwords?
328 #:motd motd)))))))
329
bdb36958 330(define* (nscd-service #:key (glibc (canonical-package glibc)))
db4fdc04 331 "Return a service that runs libc's name service cache daemon (nscd)."
b5f4e686 332 (with-monad %store-monad
db4fdc04
LC
333 (return (service
334 (documentation "Run libc's name service cache daemon (nscd).")
335 (provision '(nscd))
a00dd9fb 336 (requirement '(user-processes))
4b2615e1
LC
337
338 (activate #~(begin
339 (use-modules (guix build utils))
340 (mkdir-p "/var/run/nscd")))
341
1c6b445b
LC
342 (start #~(make-forkexec-constructor
343 (list (string-append #$glibc "/sbin/nscd")
344 "-f" "/dev/null" "--foreground")))
b5f4e686 345 (stop #~(make-kill-destructor))
db4fdc04 346
b5f4e686 347 (respawn? #f)))))
db4fdc04
LC
348
349(define (syslog-service)
51da7ca0 350 "Return a service that runs @code{syslogd} with reasonable default settings."
db4fdc04
LC
351
352 ;; Snippet adapted from the GNU inetutils manual.
353 (define contents "
1f3fc60d 354 # Log all error messages, authentication messages of
db4fdc04
LC
355 # level notice or higher and anything of level err or
356 # higher to the console.
357 # Don't log private authentication messages!
6a191274 358 *.alert;auth.notice;authpriv.none /dev/console
db4fdc04
LC
359
360 # Log anything (except mail) of level info or higher.
361 # Don't log private authentication messages!
362 *.info;mail.none;authpriv.none /var/log/messages
363
364 # Same, in a different place.
365 *.info;mail.none;authpriv.none /dev/tty12
366
367 # The authpriv file has restricted access.
368 authpriv.* /var/log/secure
369
370 # Log all the mail messages in one place.
371 mail.* /var/log/maillog
372")
373
374 (mlet %store-monad
b5f4e686 375 ((syslog.conf (text-file "syslog.conf" contents)))
db4fdc04
LC
376 (return
377 (service
378 (documentation "Run the syslog daemon (syslogd).")
379 (provision '(syslogd))
a00dd9fb 380 (requirement '(user-processes))
b5f4e686 381 (start
1c6b445b
LC
382 #~(make-forkexec-constructor
383 (list (string-append #$inetutils "/libexec/syslogd")
384 "--no-detach" "--rcfile" #$syslog.conf)))
b5f4e686 385 (stop #~(make-kill-destructor))))))
db4fdc04
LC
386
387(define* (guix-build-accounts count #:key
ab6a279a 388 (group "guixbuild")
db4fdc04 389 (first-uid 30001)
db4fdc04
LC
390 (shadow shadow))
391 "Return a list of COUNT user accounts for Guix build users, with UIDs
392starting at FIRST-UID, and under GID."
393 (with-monad %store-monad
394 (return (unfold (cut > <> count)
395 (lambda (n)
396 (user-account
397 (name (format #f "guixbuilder~2,'0d" n))
459dd9ea 398 (system? #t)
db4fdc04 399 (uid (+ first-uid n -1))
ab6a279a 400 (group group)
3d116a70
LC
401
402 ;; guix-daemon expects GROUP to be listed as a
403 ;; supplementary group too:
404 ;; <http://lists.gnu.org/archive/html/bug-guix/2013-01/msg00239.html>.
405 (supplementary-groups (list group))
406
db4fdc04
LC
407 (comment (format #f "Guix Build User ~2d" n))
408 (home-directory "/var/empty")
b5f4e686 409 (shell #~(string-append #$shadow "/sbin/nologin"))))
db4fdc04
LC
410 1+
411 1))))
412
2c5c696c
LC
413(define (hydra-key-authorization guix)
414 "Return a gexp with code to register the hydra.gnu.org public key with
415GUIX."
416 #~(unless (file-exists? "/etc/guix/acl")
417 (let ((pid (primitive-fork)))
418 (case pid
419 ((0)
420 (let* ((key (string-append #$guix
421 "/share/guix/hydra.gnu.org.pub"))
422 (port (open-file key "r0b")))
423 (format #t "registering public key '~a'...~%" key)
424 (close-port (current-input-port))
2c5c696c
LC
425 (dup port 0)
426 (execl (string-append #$guix "/bin/guix")
427 "guix" "archive" "--authorize")
428 (exit 1)))
429 (else
430 (let ((status (cdr (waitpid pid))))
431 (unless (zero? status)
432 (format (current-error-port) "warning: \
433failed to register hydra.gnu.org public key: ~a~%" status))))))))
434
db4fdc04 435(define* (guix-service #:key (guix guix) (builder-group "guixbuild")
c11a6eb1
LC
436 (build-accounts 10) authorize-hydra-key?
437 (use-substitutes? #t)
438 (extra-options '()))
51da7ca0
LC
439 "Return a service that runs the build daemon from @var{guix}, and has
440@var{build-accounts} user accounts available under @var{builder-group}.
2c5c696c 441
51da7ca0
LC
442When @var{authorize-hydra-key?} is true, the @code{hydra.gnu.org} public key
443provided by @var{guix} is authorized upon activation, meaning that substitutes
c11a6eb1
LC
444from @code{hydra.gnu.org} are used by default.
445
446If @var{use-substitutes?} is false, the daemon is run with
447@option{--no-substitutes} (@pxref{Invoking guix-daemon,
448@option{--no-substitutes}}).
449
450Finally, @var{extra-options} is a list of additional command-line options
451passed to @command{guix-daemon}."
185f6691 452 (define activate
e97c5be9
LC
453 ;; Assume that the store has BUILDER-GROUP as its group. We could
454 ;; otherwise call 'chown' here, but the problem is that on a COW unionfs,
455 ;; chown leads to an entire copy of the tree, which is a bad idea.
185f6691 456
e97c5be9
LC
457 ;; Optionally authorize hydra.gnu.org's key.
458 (and authorize-hydra-key?
459 (hydra-key-authorization guix)))
185f6691 460
b5f4e686 461 (mlet %store-monad ((accounts (guix-build-accounts build-accounts
ab6a279a 462 #:group builder-group)))
db4fdc04
LC
463 (return (service
464 (provision '(guix-daemon))
a00dd9fb 465 (requirement '(user-processes))
b5f4e686 466 (start
1c6b445b
LC
467 #~(make-forkexec-constructor
468 (list (string-append #$guix "/bin/guix-daemon")
c11a6eb1
LC
469 "--build-users-group" #$builder-group
470 #$@(if use-substitutes?
471 '()
472 '("--no-substitutes"))
473 #$@extra-options)))
b5f4e686 474 (stop #~(make-kill-destructor))
db4fdc04
LC
475 (user-accounts accounts)
476 (user-groups (list (user-group
477 (name builder-group)
41717509 478 (system? #t)
e97c5be9
LC
479
480 ;; Use a fixed GID so that we can create the
481 ;; store with the right owner.
482 (id 30000))))
185f6691 483 (activate activate)))))
db4fdc04 484
ecd06ca9
LC
485(define (udev-rules-union packages)
486 "Return the union of the @code{lib/udev/rules.d} directories found in each
487item of @var{packages}."
488 (define build
489 #~(begin
490 (use-modules (guix build union)
491 (guix build utils)
492 (srfi srfi-1)
493 (srfi srfi-26))
494
495 (define %standard-locations
496 '("/lib/udev/rules.d" "/libexec/udev/rules.d"))
497
498 (define (rules-sub-directory directory)
499 ;; Return the sub-directory of DIRECTORY containing udev rules, or
500 ;; #f if none was found.
501 (find directory-exists?
502 (map (cut string-append directory <>) %standard-locations)))
503
504 (mkdir-p (string-append #$output "/lib/udev"))
505 (union-build (string-append #$output "/lib/udev/rules.d")
506 (filter-map rules-sub-directory '#$packages))))
507
508 (gexp->derivation "udev-rules" build
509 #:modules '((guix build union)
510 (guix build utils))
511 #:local-build? #t))
512
513(define* (udev-service #:key (udev udev) (rules '()))
514 "Run @var{udev}, which populates the @file{/dev} directory dynamically. Get
515extra rules from the packages listed in @var{rules}."
516 (mlet* %store-monad ((rules (udev-rules-union (cons udev rules)))
517 (udev.conf (text-file* "udev.conf"
518 "udev_rules=\"" rules
519 "/lib/udev/rules.d\"\n")))
151a2c07
LC
520 (return (service
521 (provision '(udev))
a69576ea
LC
522
523 ;; Udev needs /dev to be a 'devtmpfs' mount so that new device
524 ;; nodes can be added: see
525 ;; <http://www.linuxfromscratch.org/lfs/view/development/chapter07/udev.html>.
7f239fd3 526 (requirement '(root-file-system))
a69576ea
LC
527
528 (documentation "Populate the /dev directory, dynamically.")
151a2c07 529 (start #~(lambda ()
1c6b445b
LC
530 (define udevd
531 (string-append #$udev "/libexec/udev/udevd"))
532
ed09bb11
LC
533 (define (wait-for-udevd)
534 ;; Wait until someone's listening on udevd's control
535 ;; socket.
536 (let ((sock (socket AF_UNIX SOCK_SEQPACKET 0)))
537 (let try ()
538 (catch 'system-error
539 (lambda ()
540 (connect sock PF_UNIX "/run/udev/control")
541 (close-port sock))
542 (lambda args
543 (format #t "waiting for udevd...~%")
544 (usleep 500000)
545 (try))))))
546
081c5b2d
LC
547 ;; Allow udev to find the modules.
548 (setenv "LINUX_MODULE_DIRECTORY"
549 "/run/booted-system/kernel/lib/modules")
550
ecd06ca9
LC
551 (setenv "UDEV_CONFIG_FILE" #$udev.conf)
552
151a2c07
LC
553 (let ((pid (primitive-fork)))
554 (case pid
555 ((0)
1c6b445b 556 (exec-command (list udevd)))
151a2c07 557 (else
ed09bb11
LC
558 ;; Wait until udevd is up and running. This
559 ;; appears to be needed so that the events
560 ;; triggered below are actually handled.
561 (wait-for-udevd)
562
563 ;; Trigger device node creation.
564 (system* (string-append #$udev "/bin/udevadm")
565 "trigger" "--action=add")
566
081c5b2d
LC
567 ;; Wait for things to settle down.
568 (system* (string-append #$udev "/bin/udevadm")
569 "settle")
151a2c07
LC
570 pid)))))
571 (stop #~(make-kill-destructor))))))
572
5dae0186
LC
573(define (device-mapping-service target command)
574 "Return a service that maps device @var{target}, a string such as
575@code{\"home\"} (meaning @code{/dev/mapper/home}), by executing @var{command},
576a gexp."
577 (with-monad %store-monad
578 (return (service
579 (provision (list (symbol-append 'device-mapping-
580 (string->symbol target))))
581 (requirement '(udev))
582 (documentation "Map a device node using Linux's device mapper.")
583 (start #~(lambda ()
584 #$command))
585 (stop #~(const #f))
586 (respawn? #f)))))
587
8b198abe
LC
588(define %base-services
589 ;; Convenience variable holding the basic services.
590 (let ((motd (text-file "motd" "
591This is the GNU operating system, welcome!\n\n")))
62ca0fdf
LC
592 (list (console-font-service "tty1")
593 (console-font-service "tty2")
594 (console-font-service "tty3")
595 (console-font-service "tty4")
596 (console-font-service "tty5")
597 (console-font-service "tty6")
598
599 (mingetty-service "tty1" #:motd motd)
8b198abe
LC
600 (mingetty-service "tty2" #:motd motd)
601 (mingetty-service "tty3" #:motd motd)
602 (mingetty-service "tty4" #:motd motd)
603 (mingetty-service "tty5" #:motd motd)
604 (mingetty-service "tty6" #:motd motd)
4a3b3b07
LC
605 (static-networking-service "lo" "127.0.0.1"
606 #:provision '(loopback))
8b198abe
LC
607 (syslog-service)
608 (guix-service)
151a2c07 609 (nscd-service)
ecd06ca9
LC
610
611 ;; By default, enable the udev rules of LVM2. They are needed as
612 ;; soon as LVM2 or the device-mapper is used.
613 (udev-service #:rules (list lvm2)))))
8b198abe 614
db4fdc04 615;;; base.scm ends here