desktop.scm 37 KB

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