desktop.scm 43 KB

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