summaryrefslogtreecommitdiff
path: root/gnu/services/desktop.scm
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/services/desktop.scm')
-rw-r--r--gnu/services/desktop.scm238
1 files changed, 228 insertions, 10 deletions
diff --git a/gnu/services/desktop.scm b/gnu/services/desktop.scm
index 4e4b49df3e..b91bdd8ad3 100644
--- a/gnu/services/desktop.scm
+++ b/gnu/services/desktop.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014, 2015 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2015 Andy Wingo <wingo@igalia.com>
+;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -24,12 +25,18 @@
#:use-module (gnu services xorg)
#:use-module (gnu services networking)
#:use-module (gnu system shadow)
+ #:use-module (gnu system linux) ; unix-pam-service
#:use-module (gnu packages glib)
#:use-module (gnu packages admin)
+ #:use-module (gnu packages freedesktop)
#:use-module (gnu packages gnome)
#:use-module (gnu packages avahi)
#:use-module (gnu packages wicd)
+ #:use-module (gnu packages polkit)
+ #:use-module ((gnu packages linux)
+ #:select (lvm2 fuse alsa-utils crda))
#:use-module (guix monads)
+ #:use-module (guix records)
#:use-module (guix store)
#:use-module (guix gexp)
#:use-module (ice-9 match)
@@ -39,6 +46,9 @@
geoclue-application
%standard-geoclue-applications
geoclue-service
+ polkit-service
+ elogind-configuration
+ elogind-service
%desktop-services))
;;; Commentary:
@@ -374,6 +384,199 @@ site} for more information."
;;;
+;;; Polkit privilege management service.
+;;;
+
+(define* (polkit-service #:key (polkit polkit))
+ "Return a service that runs the @command{polkit} privilege management
+service. By querying the @command{polkit} service, a privileged system
+component can know when it should grant additional capabilities to ordinary
+users. For example, an ordinary user can be granted the capability to suspend
+the system if the user is logged in locally."
+ (with-monad %store-monad
+ (return
+ (service
+ (documentation "Run the polkit privilege management service.")
+ (provision '(polkit-daemon))
+ (requirement '(dbus-system))
+
+ (start #~(make-forkexec-constructor
+ (list (string-append #$polkit "/lib/polkit-1/polkitd"))))
+ (stop #~(make-kill-destructor))
+
+ (user-groups (list (user-group
+ (name "polkitd")
+ (system? #t))))
+ (user-accounts (list (user-account
+ (name "polkitd")
+ (group "polkitd")
+ (system? #t)
+ (comment "Polkit daemon user")
+ (home-directory "/var/empty")
+ (shell
+ "/run/current-system/profile/sbin/nologin"))))
+
+ (pam-services (list (unix-pam-service "polkit-1")))))))
+
+
+;;;
+;;; Elogind login and seat management service.
+;;;
+
+(define-record-type* <elogind-configuration> elogind-configuration
+ make-elogind-configuration
+ elogind-configuration
+ (kill-user-processes? elogind-kill-user-processes?
+ (default #f))
+ (kill-only-users elogind-kill-only-users
+ (default '()))
+ (kill-exclude-users elogind-kill-exclude-users
+ (default '("root")))
+ (inhibit-delay-max-seconds elogind-inhibit-delay-max-seconds
+ (default 5))
+ (handle-power-key elogind-handle-power-key
+ (default 'poweroff))
+ (handle-suspend-key elogind-handle-suspend-key
+ (default 'suspend))
+ (handle-hibernate-key elogind-handle-hibernate-key
+ ;; (default 'hibernate)
+ ;; XXX Ignore it for now, since we don't
+ ;; yet handle resume-from-hibernation in
+ ;; our initrd.
+ (default 'ignore))
+ (handle-lid-switch elogind-handle-lid-switch
+ (default 'suspend))
+ (handle-lid-switch-docked elogind-handle-lid-switch-docked
+ (default 'ignore))
+ (power-key-ignore-inhibited? elogind-power-key-ignore-inhibited?
+ (default #f))
+ (suspend-key-ignore-inhibited? elogind-suspend-key-ignore-inhibited?
+ (default #f))
+ (hibernate-key-ignore-inhibited? elogind-hibernate-key-ignore-inhibited?
+ (default #f))
+ (lid-switch-ignore-inhibited? elogind-lid-switch-ignore-inhibited?
+ (default #t))
+ (holdoff-timeout-seconds elogind-holdoff-timeout-seconds
+ (default 30))
+ (idle-action elogind-idle-action
+ (default 'ignore))
+ (idle-action-seconds elogind-idle-action-seconds
+ (default (* 30 60)))
+ (runtime-directory-size-percent elogind-runtime-directory-size-percent
+ (default 10))
+ (runtime-directory-size elogind-runtime-directory-size
+ (default #f))
+ (remove-ipc? elogind-remove-ipc?
+ (default #t))
+
+ (suspend-state elogind-suspend-state
+ (default '("mem" "standby" "freeze")))
+ (suspend-mode elogind-suspend-mode
+ (default '()))
+ (hibernate-state elogind-hibernate-state
+ (default '("disk")))
+ (hibernate-mode elogind-hibernate-mode
+ (default '("platform" "shutdown")))
+ (hybrid-sleep-state elogind-hybrid-sleep-state
+ (default '("disk")))
+ (hybrid-sleep-mode elogind-hybrid-sleep-mode
+ (default
+ '("suspend" "platform" "shutdown"))))
+
+(define (elogind-configuration-file config)
+ (define (yesno x)
+ (match x
+ (#t "yes")
+ (#f "no")
+ (_ (error "expected #t or #f, instead got:" x))))
+ (define char-set:user-name
+ (string->char-set "abcdefghijklmnopqrstuvwxyz0123456789_-"))
+ (define (valid-list? l pred)
+ (and-map (lambda (x) (string-every pred x)) l))
+ (define (user-name-list users)
+ (unless (valid-list? users char-set:user-name)
+ (error "invalid user list" users))
+ (string-join users " "))
+ (define (enum val allowed)
+ (unless (memq val allowed)
+ (error "invalid value" val allowed))
+ (symbol->string val))
+ (define (non-negative-integer x)
+ (unless (exact-integer? x) (error "not an integer" x))
+ (when (negative? x) (error "negative number not allowed" x))
+ (number->string x))
+ (define handle-actions
+ '(ignore poweroff reboot halt kexec suspend hibernate hybrid-sleep lock))
+ (define (handle-action x)
+ (enum x handle-actions))
+ (define (sleep-list tokens)
+ (unless (valid-list? tokens char-set:user-name)
+ (error "invalid sleep list" tokens))
+ (string-join tokens " "))
+ (define-syntax ini-file-clause
+ (syntax-rules ()
+ ((_ config (prop (parser getter)))
+ (string-append prop "=" (parser (getter config)) "\n"))
+ ((_ config str)
+ (string-append str "\n"))))
+ (define-syntax-rule (ini-file config file clause ...)
+ (text-file file (string-append (ini-file-clause config clause) ...)))
+ (ini-file
+ config "logind.conf"
+ "[Login]"
+ ("KillUserProcesses" (yesno elogind-kill-user-processes?))
+ ("KillOnlyUsers" (user-name-list elogind-kill-only-users))
+ ("KillExcludeUsers" (user-name-list elogind-kill-exclude-users))
+ ("InhibitDelayMaxSecs" (non-negative-integer elogind-inhibit-delay-max-seconds))
+ ("HandlePowerKey" (handle-action elogind-handle-power-key))
+ ("HandleSuspendKey" (handle-action elogind-handle-suspend-key))
+ ("HandleHibernateKey" (handle-action elogind-handle-hibernate-key))
+ ("HandleLidSwitch" (handle-action elogind-handle-lid-switch))
+ ("HandleLidSwitchDocked" (handle-action elogind-handle-lid-switch-docked))
+ ("PowerKeyIgnoreInhibited" (yesno elogind-power-key-ignore-inhibited?))
+ ("SuspendKeyIgnoreInhibited" (yesno elogind-suspend-key-ignore-inhibited?))
+ ("HibernateKeyIgnoreInhibited" (yesno elogind-hibernate-key-ignore-inhibited?))
+ ("LidSwitchIgnoreInhibited" (yesno elogind-lid-switch-ignore-inhibited?))
+ ("HoldoffTimeoutSecs" (non-negative-integer elogind-holdoff-timeout-seconds))
+ ("IdleAction" (handle-action elogind-idle-action))
+ ("IdleActionSeconds" (non-negative-integer elogind-idle-action-seconds))
+ ("RuntimeDirectorySize"
+ (identity
+ (lambda (config)
+ (match (elogind-runtime-directory-size-percent config)
+ (#f (non-negative-integer (elogind-runtime-directory-size config)))
+ (percent (string-append (non-negative-integer percent) "%"))))))
+ ("RemoveIpc" (yesno elogind-remove-ipc?))
+ "[Sleep]"
+ ("SuspendState" (sleep-list elogind-suspend-state))
+ ("SuspendMode" (sleep-list elogind-suspend-mode))
+ ("HibernateState" (sleep-list elogind-hibernate-state))
+ ("HibernateMode" (sleep-list elogind-hibernate-mode))
+ ("HybridSleepState" (sleep-list elogind-hybrid-sleep-state))
+ ("HybridSleepMode" (sleep-list elogind-hybrid-sleep-mode))))
+
+(define* (elogind-service #:key (elogind elogind)
+ (config (elogind-configuration)))
+ "Return a service that runs the @command{elogind} login and seat management
+service. The @command{elogind} service integrates with PAM to allow other
+system components to know the set of logged-in users as well as their session
+types (graphical, console, remote, etc.). It can also clean up after users
+when they log out."
+ (mlet %store-monad ((config-file (elogind-configuration-file config)))
+ (return
+ (service
+ (documentation "Run the elogind login and seat management service.")
+ (provision '(elogind))
+ (requirement '(dbus-system))
+
+ (start #~(make-forkexec-constructor
+ (list (string-append #$elogind "/libexec/elogind/elogind"))
+ #:environment-variables
+ (list (string-append "ELOGIND_CONF_FILE=" #$config-file))))
+ (stop #~(make-kill-destructor))))))
+
+
+;;;
;;; The default set of desktop services.
;;;
(define %desktop-services
@@ -383,23 +586,38 @@ site} for more information."
(avahi-service)
(wicd-service)
(upower-service)
- ;; FIXME: The colord and geoclue services could all be bus-activated
- ;; by default, so they don't run at program startup. However, user
- ;; creation and /var/lib.colord creation happen at service activation
- ;; time, so we currently add them to the set of default services.
+ ;; FIXME: The colord, geoclue, and polkit services could all be
+ ;; bus-activated by default, so they don't run at program startup.
+ ;; However, user creation and /var/lib/colord creation happen at
+ ;; service activation time, so we currently add them to the set of
+ ;; default services.
(colord-service)
(geoclue-service)
- (dbus-service (list avahi wicd upower colord geoclue))
+ (polkit-service)
+ (elogind-service)
+ (dbus-service (list avahi wicd upower colord geoclue polkit elogind))
(ntp-service)
(map (lambda (mservice)
- ;; Provide an nscd ready to use nss-mdns.
(mlet %store-monad ((service mservice))
- (if (memq 'nscd (service-provision service))
- (nscd-service (nscd-configuration)
- #:name-services (list nss-mdns))
- mservice)))
+ (cond
+ ;; Provide an nscd ready to use nss-mdns.
+ ((memq 'nscd (service-provision service))
+ (nscd-service (nscd-configuration)
+ #:name-services (list nss-mdns)))
+
+ ;; Add more rules to udev-service.
+ ;;
+ ;; XXX Keep this in sync with the 'udev-service' call in
+ ;; %base-services. Here we intend only to add 'upower',
+ ;; 'colord', and 'elogind'.
+ ((memq 'udev (service-provision service))
+ (udev-service #:rules
+ (list lvm2 fuse alsa-utils crda
+ upower colord elogind)))
+
+ (else mservice))))
%base-services)))
;;; desktop.scm ends here