aboutsummaryrefslogtreecommitdiff
path: root/gnu/services/base.scm
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/services/base.scm')
-rw-r--r--gnu/services/base.scm222
1 files changed, 204 insertions, 18 deletions
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 336cc4dec9..a86e8e04c7 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -2,6 +2,7 @@
;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2015 Alex Kost <alezost@gmail.com>
;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -23,12 +24,12 @@
#:use-module (gnu services)
#:use-module (gnu services dmd)
#:use-module (gnu services networking)
+ #:use-module (gnu system pam)
#:use-module (gnu system shadow) ; 'user-account', etc.
- #:use-module (gnu system linux) ; 'pam-service', etc.
#:use-module (gnu system file-systems) ; 'file-system', etc.
#:use-module (gnu packages admin)
#:use-module ((gnu packages linux)
- #:select (eudev kbd e2fsprogs lvm2 fuse alsa-utils crda))
+ #:select (eudev kbd e2fsprogs lvm2 fuse alsa-utils crda gpm))
#:use-module ((gnu packages base)
#:select (canonical-package glibc))
#:use-module (gnu packages package-management)
@@ -48,15 +49,23 @@
device-mapping-service
swap-service
user-processes-service
+ session-environment-service
+ session-environment-service-type
host-name-service
console-keymap-service
console-font-service
+
+ udev-configuration
+ udev-configuration?
+ udev-configuration-rules
udev-service-type
udev-service
+ udev-rule
mingetty-configuration
mingetty-configuration?
mingetty-service
+ mingetty-service-type
%nscd-default-caches
%nscd-default-configuration
@@ -74,6 +83,13 @@
guix-configuration
guix-configuration?
guix-service
+ guix-service-type
+ guix-publish-configuration
+ guix-publish-configuration?
+ guix-publish-service
+ guix-publish-service-type
+ gpm-service-type
+ gpm-service
%base-services))
@@ -142,6 +158,18 @@ FILE-SYSTEM."
(symbol-append 'file-system-
(string->symbol (file-system-mount-point file-system))))
+(define (mapped-device->dmd-service-name md)
+ "Return the symbol that denotes the dmd service of MD, a <mapped-device>."
+ (symbol-append 'device-mapping-
+ (string->symbol (mapped-device-target md))))
+
+(define dependency->dmd-service-name
+ (match-lambda
+ ((? mapped-device? md)
+ (mapped-device->dmd-service-name md))
+ ((? file-system? fs)
+ (file-system->dmd-service-name fs))))
+
(define file-system-service-type
;; TODO(?): Make this an extensible service that takes <file-system> objects
;; and returns a list of <dmd-service>.
@@ -158,7 +186,7 @@ FILE-SYSTEM."
(dmd-service
(provision (list (file-system->dmd-service-name file-system)))
(requirement `(root-file-system
- ,@(map file-system->dmd-service-name dependencies)))
+ ,@(map dependency->dmd-service-name dependencies)))
(documentation "Check, mount, and unmount the given file system.")
(start #~(lambda args
;; FIXME: Use or factorize with 'mount-file-system'.
@@ -198,7 +226,14 @@ FILE-SYSTEM."
(chdir "/")
(umount #$target)
- #f)))))))
+ #f))
+
+ ;; We need an additional module.
+ (modules `(((gnu build file-systems)
+ #:select (check-file-system canonicalize-device-spec))
+ ,@%default-modules))
+ (imported-modules `((gnu build file-systems)
+ ,@%default-imported-modules)))))))
(define* (file-system-service file-system)
"Return a service that mounts @var{file-system}, a @code{<file-system>}
@@ -336,6 +371,39 @@ stopped before 'kill' is called."
;;;
+;;; System-wide environment variables.
+;;;
+
+(define (environment-variables->environment-file vars)
+ "Return a file for pam_env(8) that contains environment variables VARS."
+ (apply mixed-text-file "environment"
+ (append-map (match-lambda
+ ((key . value)
+ (list key "=" value "\n")))
+ vars)))
+
+(define session-environment-service-type
+ (service-type
+ (name 'session-environment)
+ (extensions
+ (list (service-extension
+ etc-service-type
+ (lambda (vars)
+ (list `("environment"
+ ,(environment-variables->environment-file vars)))))))
+ (compose concatenate)
+ (extend append)))
+
+(define (session-environment-service vars)
+ "Return a service that builds the @file{/etc/environment}, which can be read
+by PAM-aware applications to set environment variables for sessions.
+
+VARS should be an association list in which both the keys and the values are
+strings or string-valued gexps."
+ (service session-environment-service-type vars))
+
+
+;;;
;;; Console & co.
;;;
@@ -691,6 +759,11 @@ If configuration file name @var{config-file} is not specified, use some
reasonable default settings."
(service syslog-service-type config-file))
+
+;;;
+;;; Guix services.
+;;;
+
(define* (guix-build-accounts count #:key
(group "guixbuild")
(first-uid 30001)
@@ -751,6 +824,8 @@ failed to register hydra.gnu.org public key: ~a~%" status))))))))
(default #t))
(use-substitutes? guix-configuration-use-substitutes? ;Boolean
(default #t))
+ (substitute-urls guix-configuration-substitute-urls ;list of strings
+ (default %default-substitute-urls))
(extra-options guix-configuration-extra-options ;list of strings
(default '()))
(lsof guix-configuration-lsof ;<package>
@@ -765,7 +840,8 @@ failed to register hydra.gnu.org public key: ~a~%" status))))))))
"Return a <dmd-service> for the Guix daemon service with CONFIG."
(match config
(($ <guix-configuration> guix build-group build-accounts authorize-key?
- use-substitutes? extra-options lsof lsh)
+ use-substitutes? substitute-urls extra-options
+ lsof lsh)
(list (dmd-service
(documentation "Run the Guix daemon.")
(provision '(guix-daemon))
@@ -777,6 +853,7 @@ failed to register hydra.gnu.org public key: ~a~%" status))))))))
#$@(if use-substitutes?
'()
'("--no-substitutes"))
+ "--substitute-urls" #$(string-join substitute-urls)
#$@extra-options)
;; Add 'lsof' (for the GC) and 'lsh' (for offloading) to the
@@ -824,6 +901,58 @@ failed to register hydra.gnu.org public key: ~a~%" status))))))))
@var{config}."
(service guix-service-type config))
+
+(define-record-type* <guix-publish-configuration>
+ guix-publish-configuration make-guix-publish-configuration
+ guix-publish-configuration?
+ (guix guix-publish-configuration-guix ;package
+ (default guix))
+ (port guix-publish-configuration-port ;number
+ (default 80))
+ (host guix-publish-configuration-host ;string
+ (default "localhost")))
+
+(define guix-publish-dmd-service
+ (match-lambda
+ (($ <guix-publish-configuration> guix port host)
+ (list (dmd-service
+ (provision '(guix-publish))
+ (requirement '(guix-daemon))
+ (start #~(make-forkexec-constructor
+ (list (string-append #$guix "/bin/guix")
+ "publish" "-u" "guix-publish"
+ "-p" #$(number->string port)
+ (string-append "--listen=" #$host))))
+ (stop #~(make-kill-destructor)))))))
+
+(define %guix-publish-accounts
+ (list (user-group (name "guix-publish") (system? #t))
+ (user-account
+ (name "guix-publish")
+ (group "guix-publish")
+ (system? #t)
+ (comment "guix publish user")
+ (home-directory "/var/empty")
+ (shell #~(string-append #$shadow "/sbin/nologin")))))
+
+(define guix-publish-service-type
+ (service-type (name 'guix-publish)
+ (extensions
+ (list (service-extension dmd-root-service-type
+ guix-publish-dmd-service)
+ (service-extension account-service-type
+ (const %guix-publish-accounts))))))
+
+(define* (guix-publish-service #:key (guix guix) (port 80) (host "localhost"))
+ "Return a service that runs @command{guix publish} listening on @var{host}
+and @var{port} (@pxref{Invoking guix publish}).
+
+This assumes that @file{/etc/guix} already contains a signing key pair as
+created by @command{guix archive --generate-key} (@pxref{Invoking guix
+archive}). If that is not the case, the service will fail to start."
+ (service guix-publish-service-type
+ (guix-publish-configuration (guix guix) (port port) (host host))))
+
;;;
;;; Udev.
@@ -864,12 +993,9 @@ item of @var{packages}."
#:modules '((guix build union)
(guix build utils))))
-(define* (kvm-udev-rule)
- "Return a directory with a udev rule that changes the group of
-@file{/dev/kvm} to \"kvm\" and makes it #o660."
- ;; Apparently QEMU-KVM used to ship this rule, but now we have to add it by
- ;; ourselves.
- (computed-file "kvm-udev-rules"
+(define (udev-rule file-name contents)
+ "Return a directory with a udev rule file FILE-NAME containing CONTENTS."
+ (computed-file file-name
#~(begin
(use-modules (guix build utils))
@@ -878,20 +1004,26 @@ item of @var{packages}."
(mkdir-p rules.d)
(call-with-output-file
- (string-append rules.d "/90-kvm.rules")
+ (string-append rules.d "/" #$file-name)
(lambda (port)
- ;; Build users are part of the "kvm" group, so we
- ;; can fearlessly make /dev/kvm 660 (see
- ;; <http://bugs.gnu.org/18994>, for background.)
- (display "\
-KERNEL==\"kvm\", GROUP=\"kvm\", MODE=\"0660\"\n" port))))
+ (display #$contents port))))
#:modules '((guix build utils))))
+(define kvm-udev-rule
+ ;; Return a directory with a udev rule that changes the group of /dev/kvm to
+ ;; "kvm" and makes it #o660. Apparently QEMU-KVM used to ship this rule,
+ ;; but now we have to add it by ourselves.
+
+ ;; Build users are part of the "kvm" group, so we can fearlessly make
+ ;; /dev/kvm 660 (see <http://bugs.gnu.org/18994>, for background.)
+ (udev-rule "90-kvm.rules"
+ "KERNEL==\"kvm\", GROUP=\"kvm\", MODE=\"0660\"\n"))
+
(define udev-dmd-service
;; Return a <dmd-service> for UDEV with RULES.
(match-lambda
(($ <udev-configuration> udev rules)
- (let* ((rules (udev-rules-union (cons* udev (kvm-udev-rule) rules)))
+ (let* ((rules (udev-rules-union (cons* udev kvm-udev-rule rules)))
(udev.conf (computed-file "udev.conf"
#~(call-with-output-file #$output
(lambda (port)
@@ -1034,6 +1166,60 @@ gexp, to open it, and evaluate @var{close} to close it."
"Return a service that uses @var{device} as a swap device."
(service swap-service-type device))
+
+(define-record-type* <gpm-configuration>
+ gpm-configuration make-gpm-configuration gpm-configuration?
+ (gpm gpm-configuration-gpm) ;package
+ (options gpm-configuration-options)) ;list of strings
+
+(define gpm-dmd-service
+ (match-lambda
+ (($ <gpm-configuration> gpm options)
+ (list (dmd-service
+ (requirement '(udev))
+ (provision '(gpm))
+ (start #~(lambda ()
+ ;; 'gpm' runs in the background and sets a PID file.
+ ;; Note that it requires running as "root".
+ (false-if-exception (delete-file "/var/run/gpm.pid"))
+ (fork+exec-command (list (string-append #$gpm "/sbin/gpm")
+ #$@options))
+
+ ;; Wait for the PID file to appear; declare failure if
+ ;; it doesn't show up.
+ (let loop ((i 3))
+ (or (file-exists? "/var/run/gpm.pid")
+ (if (zero? i)
+ #f
+ (begin
+ (sleep 1)
+ (loop (1- i))))))))
+
+ (stop #~(lambda (_)
+ ;; Return #f if successfully stopped.
+ (not (zero? (system* (string-append #$gpm "/sbin/gpm")
+ "-k"))))))))))
+
+(define gpm-service-type
+ (service-type (name 'gpm)
+ (extensions
+ (list (service-extension dmd-root-service-type
+ gpm-dmd-service)))))
+
+(define* (gpm-service #:key (gpm gpm)
+ (options '("-m" "/dev/input/mice" "-t" "ps2")))
+ "Run @var{gpm}, the general-purpose mouse daemon, with the given
+command-line @var{options}. GPM allows users to use the mouse in the console,
+notably to select, copy, and paste text. The default value of @var{options}
+uses the @code{ps2} protocol, which works for both USB and PS/2 mice.
+
+This service is not part of @var{%base-services}."
+ ;; To test in QEMU, use "-usbdevice mouse" and then, in the monitor, use
+ ;; "info mice" and "mouse_set X" to use the right mouse.
+ (service gpm-service-type
+ (gpm-configuration (gpm gpm) (options options))))
+
+
(define %base-services
;; Convenience variable holding the basic services.
(let ((motd (plain-file "motd" "