desktop.scm 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
  3. ;;; Copyright © 2015 Andy Wingo <wingo@igalia.com>
  4. ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
  5. ;;; Copyright © 2016 Sou Bunnbu <iyzsong@gmail.com>
  6. ;;; Copyright © 2017 Maxim Cournoyer <maxim.cournoyer@gmail.com>
  7. ;;;
  8. ;;; This file is part of GNU Guix.
  9. ;;;
  10. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  11. ;;; under the terms of the GNU General Public License as published by
  12. ;;; the Free Software Foundation; either version 3 of the License, or (at
  13. ;;; your option) any later version.
  14. ;;;
  15. ;;; GNU Guix is distributed in the hope that it will be useful, but
  16. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. ;;; GNU General Public License for more details.
  19. ;;;
  20. ;;; You should have received a copy of the GNU General Public License
  21. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  22. (define-module (gnu services desktop)
  23. #:use-module (gnu services)
  24. #:use-module (gnu services shepherd)
  25. #:use-module (gnu services base)
  26. #:use-module (gnu services dbus)
  27. #:use-module (gnu services avahi)
  28. #:use-module (gnu services xorg)
  29. #:use-module (gnu services networking)
  30. #:use-module ((gnu system file-systems)
  31. #:select (%elogind-file-systems))
  32. #:use-module (gnu system shadow)
  33. #:use-module (gnu system pam)
  34. #:use-module (gnu packages glib)
  35. #:use-module (gnu packages admin)
  36. #:use-module (gnu packages freedesktop)
  37. #:use-module (gnu packages gnome)
  38. #:use-module (gnu packages xfce)
  39. #:use-module (gnu packages avahi)
  40. #:use-module (gnu packages xdisorg)
  41. #:use-module (gnu packages suckless)
  42. #:use-module (gnu packages linux)
  43. #:use-module (gnu packages libusb)
  44. #:use-module (guix records)
  45. #:use-module (guix packages)
  46. #:use-module (guix store)
  47. #:use-module (guix gexp)
  48. #:use-module (srfi srfi-1)
  49. #:use-module (ice-9 match)
  50. #:export (upower-configuration
  51. upower-configuration?
  52. upower-service
  53. upower-service-type
  54. udisks-configuration
  55. udisks-configuration?
  56. udisks-service
  57. udisks-service-type
  58. colord-service
  59. geoclue-application
  60. geoclue-configuration
  61. geoclue-configuration?
  62. %standard-geoclue-applications
  63. geoclue-service
  64. geoclue-service-type
  65. bluetooth-service
  66. elogind-configuration
  67. elogind-configuration?
  68. elogind-service
  69. elogind-service-type
  70. accountsservice-service-type
  71. accountsservice-service
  72. gnome-desktop-configuration
  73. gnome-desktop-configuration?
  74. gnome-desktop-service
  75. gnome-desktop-service-type
  76. xfce-desktop-configuration
  77. xfce-desktop-configuration?
  78. xfce-desktop-service
  79. xfce-desktop-service-type
  80. %desktop-services))
  81. ;;; Commentary:
  82. ;;;
  83. ;;; This module contains service definitions for a "desktop" environment.
  84. ;;;
  85. ;;; Code:
  86. ;;;
  87. ;;; Helpers.
  88. ;;;
  89. (define (bool value)
  90. (if value "true\n" "false\n"))
  91. (define (package-direct-input-selector input)
  92. (lambda (package)
  93. (match (assoc-ref (package-direct-inputs package) input)
  94. ((package . _) package))))
  95. (define (wrapped-dbus-service service program variable value)
  96. "Return a wrapper for @var{service}, a package containing a D-Bus service,
  97. where @var{program} is wrapped such that environment variable @var{variable}
  98. is set to @var{value} when the bus daemon launches it."
  99. (define wrapper
  100. (program-file (string-append (package-name service) "-program-wrapper")
  101. #~(begin
  102. (setenv #$variable #$value)
  103. (apply execl (string-append #$service "/" #$program)
  104. (string-append #$service "/" #$program)
  105. (cdr (command-line))))))
  106. (define build
  107. (with-imported-modules '((guix build utils))
  108. #~(begin
  109. (use-modules (guix build utils))
  110. (define service-directory
  111. "/share/dbus-1/system-services")
  112. (mkdir-p (dirname (string-append #$output
  113. service-directory)))
  114. (copy-recursively (string-append #$service
  115. service-directory)
  116. (string-append #$output
  117. service-directory))
  118. (symlink (string-append #$service "/etc") ;for etc/dbus-1
  119. (string-append #$output "/etc"))
  120. (for-each (lambda (file)
  121. (substitute* file
  122. (("Exec[[:blank:]]*=[[:blank:]]*([[:graph:]]+)(.*)$"
  123. _ original-program arguments)
  124. (string-append "Exec=" #$wrapper arguments
  125. "\n"))))
  126. (find-files #$output "\\.service$")))))
  127. (computed-file (string-append (package-name service) "-wrapper")
  128. build))
  129. ;;;
  130. ;;; Upower D-Bus service.
  131. ;;;
  132. ;; TODO: Export.
  133. (define-record-type* <upower-configuration>
  134. upower-configuration make-upower-configuration
  135. upower-configuration?
  136. (upower upower-configuration-upower
  137. (default upower))
  138. (watts-up-pro? upower-configuration-watts-up-pro?)
  139. (poll-batteries? upower-configuration-poll-batteries?)
  140. (ignore-lid? upower-configuration-ignore-lid?)
  141. (use-percentage-for-policy? upower-configuration-use-percentage-for-policy?)
  142. (percentage-low upower-configuration-percentage-low)
  143. (percentage-critical upower-configuration-percentage-critical)
  144. (percentage-action upower-configuration-percentage-action)
  145. (time-low upower-configuration-time-low)
  146. (time-critical upower-configuration-time-critical)
  147. (time-action upower-configuration-time-action)
  148. (critical-power-action upower-configuration-critical-power-action))
  149. (define* upower-configuration-file
  150. ;; Return an upower-daemon configuration file.
  151. (match-lambda
  152. (($ <upower-configuration> upower
  153. watts-up-pro? poll-batteries? ignore-lid? use-percentage-for-policy?
  154. percentage-low percentage-critical percentage-action time-low
  155. time-critical time-action critical-power-action)
  156. (plain-file "UPower.conf"
  157. (string-append
  158. "[UPower]\n"
  159. "EnableWattsUpPro=" (bool watts-up-pro?)
  160. "NoPollBatteries=" (bool (not poll-batteries?))
  161. "IgnoreLid=" (bool ignore-lid?)
  162. "UsePercentageForPolicy=" (bool use-percentage-for-policy?)
  163. "PercentageLow=" (number->string percentage-low) "\n"
  164. "PercentageCritical=" (number->string percentage-critical) "\n"
  165. "PercentageAction=" (number->string percentage-action) "\n"
  166. "TimeLow=" (number->string time-low) "\n"
  167. "TimeCritical=" (number->string time-critical) "\n"
  168. "TimeAction=" (number->string time-action) "\n"
  169. "CriticalPowerAction=" (match critical-power-action
  170. ('hybrid-sleep "HybridSleep")
  171. ('hibernate "Hibernate")
  172. ('power-off "PowerOff"))
  173. "\n")))))
  174. (define %upower-activation
  175. #~(begin
  176. (use-modules (guix build utils))
  177. (mkdir-p "/var/lib/upower")))
  178. (define (upower-dbus-service config)
  179. (list (wrapped-dbus-service (upower-configuration-upower config)
  180. "libexec/upowerd"
  181. "UPOWER_CONF_FILE_NAME"
  182. (upower-configuration-file config))))
  183. (define (upower-shepherd-service config)
  184. "Return a shepherd service for UPower with CONFIG."
  185. (let ((upower (upower-configuration-upower config))
  186. (config (upower-configuration-file config)))
  187. (list (shepherd-service
  188. (documentation "Run the UPower power and battery monitor.")
  189. (provision '(upower-daemon))
  190. (requirement '(dbus-system udev))
  191. (start #~(make-forkexec-constructor
  192. (list (string-append #$upower "/libexec/upowerd"))
  193. #:environment-variables
  194. (list (string-append "UPOWER_CONF_FILE_NAME="
  195. #$config))))
  196. (stop #~(make-kill-destructor))))))
  197. (define upower-service-type
  198. (let ((upower-package (compose list upower-configuration-upower)))
  199. (service-type (name 'upower)
  200. (extensions
  201. (list (service-extension dbus-root-service-type
  202. upower-dbus-service)
  203. (service-extension shepherd-root-service-type
  204. upower-shepherd-service)
  205. (service-extension activation-service-type
  206. (const %upower-activation))
  207. (service-extension udev-service-type
  208. upower-package)
  209. ;; Make the 'upower' command visible.
  210. (service-extension profile-service-type
  211. upower-package))))))
  212. (define* (upower-service #:key (upower upower)
  213. (watts-up-pro? #f)
  214. (poll-batteries? #t)
  215. (ignore-lid? #f)
  216. (use-percentage-for-policy? #f)
  217. (percentage-low 10)
  218. (percentage-critical 3)
  219. (percentage-action 2)
  220. (time-low 1200)
  221. (time-critical 300)
  222. (time-action 120)
  223. (critical-power-action 'hybrid-sleep))
  224. "Return a service that runs @uref{http://upower.freedesktop.org/,
  225. @command{upowerd}}, a system-wide monitor for power consumption and battery
  226. levels, with the given configuration settings. It implements the
  227. @code{org.freedesktop.UPower} D-Bus interface, and is notably used by GNOME."
  228. (let ((config (upower-configuration
  229. (watts-up-pro? watts-up-pro?)
  230. (poll-batteries? poll-batteries?)
  231. (ignore-lid? ignore-lid?)
  232. (use-percentage-for-policy? use-percentage-for-policy?)
  233. (percentage-low percentage-low)
  234. (percentage-critical percentage-critical)
  235. (percentage-action percentage-action)
  236. (time-low time-low)
  237. (time-critical time-critical)
  238. (time-action time-action)
  239. (critical-power-action critical-power-action))))
  240. (service upower-service-type config)))
  241. ;;;
  242. ;;; GeoClue D-Bus service.
  243. ;;;
  244. ;; TODO: Export.
  245. (define-record-type* <geoclue-configuration>
  246. geoclue-configuration make-geoclue-configuration
  247. geoclue-configuration?
  248. (geoclue geoclue-configuration-geoclue
  249. (default geoclue))
  250. (whitelist geoclue-configuration-whitelist)
  251. (wifi-geolocation-url geoclue-configuration-wifi-geolocation-url)
  252. (submit-data? geoclue-configuration-submit-data?)
  253. (wifi-submission-url geoclue-configuration-wifi-submission-url)
  254. (submission-nick geoclue-configuration-submission-nick)
  255. (applications geoclue-configuration-applications))
  256. (define* (geoclue-application name #:key (allowed? #t) system? (users '()))
  257. "Configure default GeoClue access permissions for an application. NAME is
  258. the Desktop ID of the application, without the .desktop part. If ALLOWED? is
  259. true, the application will have access to location information by default.
  260. The boolean SYSTEM? value indicates that an application is a system component
  261. or not. Finally USERS is a list of UIDs of all users for which this
  262. application is allowed location info access. An empty users list means all
  263. users are allowed."
  264. (string-append
  265. "[" name "]\n"
  266. "allowed=" (bool allowed?)
  267. "system=" (bool system?)
  268. "users=" (string-join users ";") "\n"))
  269. (define %standard-geoclue-applications
  270. (list (geoclue-application "gnome-datetime-panel" #:system? #t)
  271. (geoclue-application "epiphany" #:system? #f)
  272. (geoclue-application "firefox" #:system? #f)))
  273. (define* (geoclue-configuration-file config)
  274. "Return a geoclue configuration file."
  275. (plain-file "geoclue.conf"
  276. (string-append
  277. "[agent]\n"
  278. "whitelist="
  279. (string-join (geoclue-configuration-whitelist config)
  280. ";") "\n"
  281. "[wifi]\n"
  282. "url=" (geoclue-configuration-wifi-geolocation-url config) "\n"
  283. "submit-data=" (bool (geoclue-configuration-submit-data? config))
  284. "submission-url="
  285. (geoclue-configuration-wifi-submission-url config) "\n"
  286. "submission-nick="
  287. (geoclue-configuration-submission-nick config)
  288. "\n"
  289. (string-join (geoclue-configuration-applications config)
  290. "\n"))))
  291. (define (geoclue-dbus-service config)
  292. (list (wrapped-dbus-service (geoclue-configuration-geoclue config)
  293. "libexec/geoclue"
  294. "GEOCLUE_CONFIG_FILE"
  295. (geoclue-configuration-file config))))
  296. (define %geoclue-accounts
  297. (list (user-group (name "geoclue") (system? #t))
  298. (user-account
  299. (name "geoclue")
  300. (group "geoclue")
  301. (system? #t)
  302. (comment "GeoClue daemon user")
  303. (home-directory "/var/empty")
  304. (shell "/run/current-system/profile/sbin/nologin"))))
  305. (define geoclue-service-type
  306. (service-type (name 'geoclue)
  307. (extensions
  308. (list (service-extension dbus-root-service-type
  309. geoclue-dbus-service)
  310. (service-extension account-service-type
  311. (const %geoclue-accounts))))))
  312. (define* (geoclue-service #:key (geoclue geoclue)
  313. (whitelist '())
  314. (wifi-geolocation-url
  315. ;; Mozilla geolocation service:
  316. "https://location.services.mozilla.com/v1/geolocate?key=geoclue")
  317. (submit-data? #f)
  318. (wifi-submission-url
  319. "https://location.services.mozilla.com/v1/submit?key=geoclue")
  320. (submission-nick "geoclue")
  321. (applications %standard-geoclue-applications))
  322. "Return a service that runs the @command{geoclue} location service. This
  323. service provides a D-Bus interface to allow applications to request access to
  324. a user's physical location, and optionally to add information to online
  325. location databases. By default, only the GNOME date-time panel and the Icecat
  326. and Epiphany web browsers are able to ask for the user's location, and in the
  327. case of Icecat and Epiphany, both will ask the user for permission first. See
  328. @uref{https://wiki.freedesktop.org/www/Software/GeoClue/, the geoclue web
  329. site} for more information."
  330. (service geoclue-service-type
  331. (geoclue-configuration
  332. (geoclue geoclue)
  333. (whitelist whitelist)
  334. (wifi-geolocation-url wifi-geolocation-url)
  335. (submit-data? submit-data?)
  336. (wifi-submission-url wifi-submission-url)
  337. (submission-nick submission-nick)
  338. (applications applications))))
  339. ;;;
  340. ;;; Bluetooth.
  341. ;;;
  342. (define-record-type* <bluetooth-configuration>
  343. bluetooth-configuration make-bluetooth-configuration
  344. bluetooth-configuration?
  345. (bluez bluetooth-configuration-bluez (default bluez))
  346. (auto-enable? bluetooth-configuration-auto-enable? (default #f)))
  347. (define (bluetooth-configuration-file config)
  348. "Return a configuration file for the systemd bluetooth service, as a string."
  349. (string-append
  350. "[Policy]\n"
  351. "AutoEnable=" (bool (bluetooth-configuration-auto-enable?
  352. config))))
  353. (define (bluetooth-directory config)
  354. (computed-file "etc-bluetooth"
  355. #~(begin
  356. (mkdir #$output)
  357. (chdir #$output)
  358. (call-with-output-file "main.conf"
  359. (lambda (port)
  360. (display #$(bluetooth-configuration-file config)
  361. port))))))
  362. (define (bluetooth-shepherd-service config)
  363. "Return a shepherd service for @command{bluetoothd}."
  364. (shepherd-service
  365. (provision '(bluetooth))
  366. (requirement '(dbus-system udev))
  367. (documentation "Run the bluetoothd daemon.")
  368. (start #~(make-forkexec-constructor
  369. (string-append #$(bluetooth-configuration-bluez config)
  370. "/libexec/bluetooth/bluetoothd")))
  371. (stop #~(make-kill-destructor))))
  372. (define bluetooth-service-type
  373. (service-type
  374. (name 'bluetooth)
  375. (extensions
  376. (list (service-extension dbus-root-service-type
  377. (compose list bluetooth-configuration-bluez))
  378. (service-extension udev-service-type
  379. (compose list bluetooth-configuration-bluez))
  380. (service-extension etc-service-type
  381. (lambda (config)
  382. `(("bluetooth"
  383. ,(bluetooth-directory config)))))
  384. (service-extension shepherd-root-service-type
  385. (compose list bluetooth-shepherd-service))))))
  386. (define* (bluetooth-service #:key (bluez bluez) (auto-enable? #f))
  387. "Return a service that runs the @command{bluetoothd} daemon, which manages
  388. all the Bluetooth devices and provides a number of D-Bus interfaces. When
  389. AUTO-ENABLE? is true, the bluetooth controller is powered automatically at
  390. boot.
  391. Users need to be in the @code{lp} group to access the D-Bus service.
  392. "
  393. (service bluetooth-service-type
  394. (bluetooth-configuration
  395. (bluez bluez)
  396. (auto-enable? auto-enable?))))
  397. ;;;
  398. ;;; Colord D-Bus service.
  399. ;;;
  400. (define %colord-activation
  401. #~(begin
  402. (use-modules (guix build utils))
  403. (mkdir-p "/var/lib/colord")
  404. (let ((user (getpwnam "colord")))
  405. (chown "/var/lib/colord"
  406. (passwd:uid user) (passwd:gid user)))))
  407. (define %colord-accounts
  408. (list (user-group (name "colord") (system? #t))
  409. (user-account
  410. (name "colord")
  411. (group "colord")
  412. (system? #t)
  413. (comment "colord daemon user")
  414. (home-directory "/var/empty")
  415. (shell (file-append shadow "/sbin/nologin")))))
  416. (define colord-service-type
  417. (service-type (name 'colord)
  418. (extensions
  419. (list (service-extension account-service-type
  420. (const %colord-accounts))
  421. (service-extension activation-service-type
  422. (const %colord-activation))
  423. ;; Colord is a D-Bus service that dbus-daemon can
  424. ;; activate.
  425. (service-extension dbus-root-service-type list)
  426. ;; Colord provides "color device" rules for udev.
  427. (service-extension udev-service-type list)
  428. ;; It provides polkit "actions".
  429. (service-extension polkit-service-type list)))))
  430. (define* (colord-service #:key (colord colord))
  431. "Return a service that runs @command{colord}, a system service with a D-Bus
  432. interface to manage the color profiles of input and output devices such as
  433. screens and scanners. It is notably used by the GNOME Color Manager graphical
  434. tool. See @uref{http://www.freedesktop.org/software/colord/, the colord web
  435. site} for more information."
  436. (service colord-service-type colord))
  437. ;;;
  438. ;;; UDisks.
  439. ;;;
  440. (define-record-type* <udisks-configuration>
  441. udisks-configuration make-udisks-configuration
  442. udisks-configuration?
  443. (udisks udisks-configuration-udisks
  444. (default udisks)))
  445. (define udisks-service-type
  446. (let ((udisks-package (lambda (config)
  447. (list (udisks-configuration-udisks config)))))
  448. (service-type (name 'udisks)
  449. (extensions
  450. (list (service-extension polkit-service-type
  451. udisks-package)
  452. (service-extension dbus-root-service-type
  453. udisks-package)
  454. (service-extension udev-service-type
  455. udisks-package)
  456. ;; Profile 'udisksctl' & co. in the system profile.
  457. (service-extension profile-service-type
  458. udisks-package))))))
  459. (define* (udisks-service #:key (udisks udisks))
  460. "Return a service for @uref{http://udisks.freedesktop.org/docs/latest/,
  461. UDisks}, a @dfn{disk management} daemon that provides user interfaces with
  462. notifications and ways to mount/unmount disks. Programs that talk to UDisks
  463. include the @command{udisksctl} command, part of UDisks, and GNOME Disks."
  464. (service udisks-service-type
  465. (udisks-configuration (udisks udisks))))
  466. ;;;
  467. ;;; Elogind login and seat management service.
  468. ;;;
  469. (define-record-type* <elogind-configuration> elogind-configuration
  470. make-elogind-configuration
  471. elogind-configuration
  472. (elogind elogind-package
  473. (default elogind))
  474. (kill-user-processes? elogind-kill-user-processes?
  475. (default #f))
  476. (kill-only-users elogind-kill-only-users
  477. (default '()))
  478. (kill-exclude-users elogind-kill-exclude-users
  479. (default '("root")))
  480. (inhibit-delay-max-seconds elogind-inhibit-delay-max-seconds
  481. (default 5))
  482. (handle-power-key elogind-handle-power-key
  483. (default 'poweroff))
  484. (handle-suspend-key elogind-handle-suspend-key
  485. (default 'suspend))
  486. (handle-hibernate-key elogind-handle-hibernate-key
  487. ;; (default 'hibernate)
  488. ;; XXX Ignore it for now, since we don't
  489. ;; yet handle resume-from-hibernation in
  490. ;; our initrd.
  491. (default 'ignore))
  492. (handle-lid-switch elogind-handle-lid-switch
  493. (default 'suspend))
  494. (handle-lid-switch-docked elogind-handle-lid-switch-docked
  495. (default 'ignore))
  496. (power-key-ignore-inhibited? elogind-power-key-ignore-inhibited?
  497. (default #f))
  498. (suspend-key-ignore-inhibited? elogind-suspend-key-ignore-inhibited?
  499. (default #f))
  500. (hibernate-key-ignore-inhibited? elogind-hibernate-key-ignore-inhibited?
  501. (default #f))
  502. (lid-switch-ignore-inhibited? elogind-lid-switch-ignore-inhibited?
  503. (default #t))
  504. (holdoff-timeout-seconds elogind-holdoff-timeout-seconds
  505. (default 30))
  506. (idle-action elogind-idle-action
  507. (default 'ignore))
  508. (idle-action-seconds elogind-idle-action-seconds
  509. (default (* 30 60)))
  510. (runtime-directory-size-percent elogind-runtime-directory-size-percent
  511. (default 10))
  512. (runtime-directory-size elogind-runtime-directory-size
  513. (default #f))
  514. (remove-ipc? elogind-remove-ipc?
  515. (default #t))
  516. (suspend-state elogind-suspend-state
  517. (default '("mem" "standby" "freeze")))
  518. (suspend-mode elogind-suspend-mode
  519. (default '()))
  520. (hibernate-state elogind-hibernate-state
  521. (default '("disk")))
  522. (hibernate-mode elogind-hibernate-mode
  523. (default '("platform" "shutdown")))
  524. (hybrid-sleep-state elogind-hybrid-sleep-state
  525. (default '("disk")))
  526. (hybrid-sleep-mode elogind-hybrid-sleep-mode
  527. (default
  528. '("suspend" "platform" "shutdown"))))
  529. (define (elogind-configuration-file config)
  530. (define (yesno x)
  531. (match x
  532. (#t "yes")
  533. (#f "no")
  534. (_ (error "expected #t or #f, instead got:" x))))
  535. (define char-set:user-name
  536. (string->char-set "abcdefghijklmnopqrstuvwxyz0123456789_-"))
  537. (define (valid-list? l pred)
  538. (and-map (lambda (x) (string-every pred x)) l))
  539. (define (user-name-list users)
  540. (unless (valid-list? users char-set:user-name)
  541. (error "invalid user list" users))
  542. (string-join users " "))
  543. (define (enum val allowed)
  544. (unless (memq val allowed)
  545. (error "invalid value" val allowed))
  546. (symbol->string val))
  547. (define (non-negative-integer x)
  548. (unless (exact-integer? x) (error "not an integer" x))
  549. (when (negative? x) (error "negative number not allowed" x))
  550. (number->string x))
  551. (define handle-actions
  552. '(ignore poweroff reboot halt kexec suspend hibernate hybrid-sleep lock))
  553. (define (handle-action x)
  554. (enum x handle-actions))
  555. (define (sleep-list tokens)
  556. (unless (valid-list? tokens char-set:user-name)
  557. (error "invalid sleep list" tokens))
  558. (string-join tokens " "))
  559. (define-syntax ini-file-clause
  560. (syntax-rules ()
  561. ((_ config (prop (parser getter)))
  562. (string-append prop "=" (parser (getter config)) "\n"))
  563. ((_ config str)
  564. (string-append str "\n"))))
  565. (define-syntax-rule (ini-file config file clause ...)
  566. (plain-file file (string-append (ini-file-clause config clause) ...)))
  567. (ini-file
  568. config "logind.conf"
  569. "[Login]"
  570. ("KillUserProcesses" (yesno elogind-kill-user-processes?))
  571. ("KillOnlyUsers" (user-name-list elogind-kill-only-users))
  572. ("KillExcludeUsers" (user-name-list elogind-kill-exclude-users))
  573. ("InhibitDelayMaxSecs" (non-negative-integer elogind-inhibit-delay-max-seconds))
  574. ("HandlePowerKey" (handle-action elogind-handle-power-key))
  575. ("HandleSuspendKey" (handle-action elogind-handle-suspend-key))
  576. ("HandleHibernateKey" (handle-action elogind-handle-hibernate-key))
  577. ("HandleLidSwitch" (handle-action elogind-handle-lid-switch))
  578. ("HandleLidSwitchDocked" (handle-action elogind-handle-lid-switch-docked))
  579. ("PowerKeyIgnoreInhibited" (yesno elogind-power-key-ignore-inhibited?))
  580. ("SuspendKeyIgnoreInhibited" (yesno elogind-suspend-key-ignore-inhibited?))
  581. ("HibernateKeyIgnoreInhibited" (yesno elogind-hibernate-key-ignore-inhibited?))
  582. ("LidSwitchIgnoreInhibited" (yesno elogind-lid-switch-ignore-inhibited?))
  583. ("HoldoffTimeoutSecs" (non-negative-integer elogind-holdoff-timeout-seconds))
  584. ("IdleAction" (handle-action elogind-idle-action))
  585. ("IdleActionSeconds" (non-negative-integer elogind-idle-action-seconds))
  586. ("RuntimeDirectorySize"
  587. (identity
  588. (lambda (config)
  589. (match (elogind-runtime-directory-size-percent config)
  590. (#f (non-negative-integer (elogind-runtime-directory-size config)))
  591. (percent (string-append (non-negative-integer percent) "%"))))))
  592. ("RemoveIpc" (yesno elogind-remove-ipc?))
  593. "[Sleep]"
  594. ("SuspendState" (sleep-list elogind-suspend-state))
  595. ("SuspendMode" (sleep-list elogind-suspend-mode))
  596. ("HibernateState" (sleep-list elogind-hibernate-state))
  597. ("HibernateMode" (sleep-list elogind-hibernate-mode))
  598. ("HybridSleepState" (sleep-list elogind-hybrid-sleep-state))
  599. ("HybridSleepMode" (sleep-list elogind-hybrid-sleep-mode))))
  600. (define (elogind-dbus-service config)
  601. (list (wrapped-dbus-service (elogind-package config)
  602. "libexec/elogind/elogind"
  603. "ELOGIND_CONF_FILE"
  604. (elogind-configuration-file config))))
  605. (define (pam-extension-procedure config)
  606. "Return an extension for PAM-ROOT-SERVICE-TYPE that ensures that all the PAM
  607. services use 'pam_elogind.so', a module that allows elogind to keep track of
  608. logged-in users (run 'loginctl' to see elogind's world view of users and
  609. seats.)"
  610. (define pam-elogind
  611. (pam-entry
  612. (control "required")
  613. (module (file-append (elogind-package config)
  614. "/lib/security/pam_elogind.so"))))
  615. (list (lambda (pam)
  616. (pam-service
  617. (inherit pam)
  618. (session (cons pam-elogind (pam-service-session pam)))))))
  619. (define (elogind-shepherd-service config)
  620. "Return a Shepherd service to start elogind according to @var{config}."
  621. (list (shepherd-service
  622. (requirement '(dbus-system))
  623. (provision '(elogind))
  624. (start #~(make-forkexec-constructor
  625. (list #$(file-append (elogind-package config)
  626. "/libexec/elogind/elogind"))
  627. #:environment-variables
  628. (list (string-append "ELOGIND_CONF_FILE="
  629. #$(elogind-configuration-file
  630. config)))))
  631. (stop #~(make-kill-destructor)))))
  632. (define elogind-service-type
  633. (service-type (name 'elogind)
  634. (extensions
  635. (list (service-extension dbus-root-service-type
  636. elogind-dbus-service)
  637. (service-extension udev-service-type
  638. (compose list elogind-package))
  639. (service-extension polkit-service-type
  640. (compose list elogind-package))
  641. ;; Start elogind from the Shepherd rather than waiting
  642. ;; for bus activation. This ensures that it can handle
  643. ;; events like lid close, etc.
  644. (service-extension shepherd-root-service-type
  645. elogind-shepherd-service)
  646. ;; Provide the 'loginctl' command.
  647. (service-extension profile-service-type
  648. (compose list elogind-package))
  649. ;; Extend PAM with pam_elogind.so.
  650. (service-extension pam-root-service-type
  651. pam-extension-procedure)
  652. ;; We need /run/user, /run/systemd, etc.
  653. (service-extension file-system-service-type
  654. (const %elogind-file-systems))))
  655. (default-value (elogind-configuration))))
  656. (define* (elogind-service #:key (config (elogind-configuration)))
  657. "Return a service that runs the @command{elogind} login and seat management
  658. service. The @command{elogind} service integrates with PAM to allow other
  659. system components to know the set of logged-in users as well as their session
  660. types (graphical, console, remote, etc.). It can also clean up after users
  661. when they log out."
  662. (service elogind-service-type config))
  663. ;;;
  664. ;;; AccountsService service.
  665. ;;;
  666. (define %accountsservice-activation
  667. #~(begin
  668. (use-modules (guix build utils))
  669. (mkdir-p "/var/lib/AccountsService")))
  670. (define accountsservice-service-type
  671. (service-type (name 'accountsservice)
  672. (extensions
  673. (list (service-extension activation-service-type
  674. (const %accountsservice-activation))
  675. (service-extension dbus-root-service-type list)
  676. (service-extension polkit-service-type list)))))
  677. (define* (accountsservice-service #:key (accountsservice accountsservice))
  678. "Return a service that runs AccountsService, a system service that
  679. can list available accounts, change their passwords, and so on.
  680. AccountsService integrates with PolicyKit to enable unprivileged users to
  681. acquire the capability to modify their system configuration.
  682. @uref{https://www.freedesktop.org/wiki/Software/AccountsService/, the
  683. accountsservice web site} for more information."
  684. (service accountsservice-service-type accountsservice))
  685. ;;;
  686. ;;; GNOME desktop service.
  687. ;;;
  688. (define-record-type* <gnome-desktop-configuration> gnome-desktop-configuration
  689. make-gnome-desktop-configuration
  690. gnome-desktop-configuration
  691. (gnome-package gnome-package (default gnome)))
  692. (define gnome-desktop-service-type
  693. (service-type
  694. (name 'gnome-desktop)
  695. (extensions
  696. (list (service-extension polkit-service-type
  697. (compose list
  698. (package-direct-input-selector
  699. "gnome-settings-daemon")
  700. gnome-package))
  701. (service-extension profile-service-type
  702. (compose list
  703. gnome-package))))))
  704. (define* (gnome-desktop-service #:key (config (gnome-desktop-configuration)))
  705. "Return a service that adds the @code{gnome} package to the system profile,
  706. and extends polkit with the actions from @code{gnome-settings-daemon}."
  707. (service gnome-desktop-service-type config))
  708. ;;;
  709. ;;; XFCE desktop service.
  710. ;;;
  711. (define-record-type* <xfce-desktop-configuration> xfce-desktop-configuration
  712. make-xfce-desktop-configuration
  713. xfce-desktop-configuration
  714. (xfce xfce-package (default xfce)))
  715. (define xfce-desktop-service-type
  716. (service-type
  717. (name 'xfce-desktop)
  718. (extensions
  719. (list (service-extension polkit-service-type
  720. (compose list
  721. (package-direct-input-selector
  722. "thunar")
  723. xfce-package))
  724. (service-extension profile-service-type
  725. (compose list
  726. xfce-package))))))
  727. (define* (xfce-desktop-service #:key (config (xfce-desktop-configuration)))
  728. "Return a service that adds the @code{xfce} package to the system profile,
  729. and extends polkit with the ability for @code{thunar} to manipulate the file
  730. system as root from within a user session, after the user has authenticated
  731. with the administrator's password."
  732. (service xfce-desktop-service-type config))
  733. ;;;
  734. ;;; The default set of desktop services.
  735. ;;;
  736. (define %desktop-services
  737. ;; List of services typically useful for a "desktop" use case.
  738. (cons* (slim-service)
  739. ;; Screen lockers are a pretty useful thing and these are small.
  740. (screen-locker-service slock)
  741. (screen-locker-service xlockmore "xlock")
  742. ;; Add udev rules for MTP devices so that non-root users can access
  743. ;; them.
  744. (simple-service 'mtp udev-service-type (list libmtp))
  745. ;; The D-Bus clique.
  746. (service network-manager-service-type)
  747. (service wpa-supplicant-service-type) ;needed by NetworkManager
  748. (avahi-service)
  749. (udisks-service)
  750. (upower-service)
  751. (accountsservice-service)
  752. (colord-service)
  753. (geoclue-service)
  754. (polkit-service)
  755. (elogind-service)
  756. (dbus-service)
  757. (ntp-service)
  758. %base-services))
  759. ;;; desktop.scm ends here