desktop.scm 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2014-2021 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, 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
  7. ;;; Copyright © 2017 Nikita <nikita@n0.is>
  8. ;;; Copyright © 2018, 2020 Efraim Flashner <efraim@flashner.co.il>
  9. ;;; Copyright © 2018 Ricardo Wurmus <rekado@elephly.net>
  10. ;;; Copyright © 2017, 2019 Christopher Baines <mail@cbaines.net>
  11. ;;; Copyright © 2019 Tim Gesthuizen <tim.gesthuizen@yahoo.de>
  12. ;;; Copyright © 2019 David Wilson <david@daviwil.com>
  13. ;;; Copyright © 2020 Tobias Geerinckx-Rice <me@tobias.gr>
  14. ;;; Copyright © 2020 Reza Alizadeh Majd <r.majd@pantherx.org>
  15. ;;; Copyright © 2021 Brice Waegeneire <brice@waegenei.re>
  16. ;;;
  17. ;;; This file is part of GNU Guix.
  18. ;;;
  19. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  20. ;;; under the terms of the GNU General Public License as published by
  21. ;;; the Free Software Foundation; either version 3 of the License, or (at
  22. ;;; your option) any later version.
  23. ;;;
  24. ;;; GNU Guix is distributed in the hope that it will be useful, but
  25. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  26. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27. ;;; GNU General Public License for more details.
  28. ;;;
  29. ;;; You should have received a copy of the GNU General Public License
  30. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  31. (define-module (gnu services desktop)
  32. #:use-module (gnu services)
  33. #:use-module (gnu services shepherd)
  34. #:use-module (gnu services base)
  35. #:use-module (gnu services dbus)
  36. #:use-module (gnu services avahi)
  37. #:use-module (gnu services xorg)
  38. #:use-module (gnu services networking)
  39. #:use-module (gnu services sound)
  40. #:use-module ((gnu system file-systems)
  41. #:select (%elogind-file-systems file-system))
  42. #:autoload (gnu services sddm) (sddm-service-type)
  43. #:use-module (gnu system)
  44. #:use-module (gnu system setuid)
  45. #:use-module (gnu system shadow)
  46. #:use-module (gnu system uuid)
  47. #:use-module (gnu system pam)
  48. #:use-module (gnu packages glib)
  49. #:use-module (gnu packages admin)
  50. #:use-module (gnu packages cups)
  51. #:use-module (gnu packages freedesktop)
  52. #:use-module (gnu packages gnome)
  53. #:use-module (gnu packages xfce)
  54. #:use-module (gnu packages avahi)
  55. #:use-module (gnu packages xdisorg)
  56. #:use-module (gnu packages scanner)
  57. #:use-module (gnu packages suckless)
  58. #:use-module (gnu packages linux)
  59. #:use-module (gnu packages libusb)
  60. #:use-module (gnu packages lxqt)
  61. #:use-module (gnu packages mate)
  62. #:use-module (gnu packages nfs)
  63. #:use-module (gnu packages enlightenment)
  64. #:use-module (guix deprecation)
  65. #:use-module (guix records)
  66. #:use-module (guix packages)
  67. #:use-module (guix store)
  68. #:use-module (guix utils)
  69. #:use-module (guix gexp)
  70. #:use-module (srfi srfi-1)
  71. #:use-module (ice-9 format)
  72. #:use-module (ice-9 match)
  73. #:export (<upower-configuration>
  74. upower-configuration
  75. upower-configuration?
  76. upower-configuration-upower
  77. upower-configuration-watts-up-pro?
  78. upower-configuration-poll-batteries?
  79. upower-configuration-ignore-lid?
  80. upower-configuration-use-percentage-for-policy?
  81. upower-configuration-percentage-low
  82. upower-configuration-percentage-critical
  83. upower-configuration-percentage-action
  84. upower-configuration-time-low
  85. upower-configuration-time-critical
  86. upower-configuration-time-action
  87. upower-configuration-critical-power-action
  88. upower-service-type
  89. udisks-configuration
  90. udisks-configuration?
  91. udisks-service
  92. udisks-service-type
  93. colord-service-type
  94. geoclue-application
  95. geoclue-configuration
  96. geoclue-configuration?
  97. %standard-geoclue-applications
  98. geoclue-service
  99. geoclue-service-type
  100. bluetooth-service-type
  101. bluetooth-configuration
  102. bluetooth-configuration?
  103. bluetooth-service
  104. elogind-configuration
  105. elogind-configuration?
  106. elogind-service
  107. elogind-service-type
  108. %fontconfig-file-system
  109. fontconfig-file-system-service
  110. accountsservice-service-type
  111. accountsservice-service
  112. cups-pk-helper-service-type
  113. sane-service-type
  114. gnome-desktop-configuration
  115. gnome-desktop-configuration?
  116. gnome-desktop-service
  117. gnome-desktop-service-type
  118. mate-desktop-configuration
  119. mate-desktop-configuration?
  120. mate-desktop-service
  121. mate-desktop-service-type
  122. lxqt-desktop-configuration
  123. lxqt-desktop-configuration?
  124. lxqt-desktop-service-type
  125. xfce-desktop-configuration
  126. xfce-desktop-configuration?
  127. xfce-desktop-service
  128. xfce-desktop-service-type
  129. x11-socket-directory-service
  130. enlightenment-desktop-configuration
  131. enlightenment-desktop-configuration?
  132. enlightenment-desktop-service-type
  133. inputattach-configuration
  134. inputattach-configuration?
  135. inputattach-service-type
  136. polkit-wheel-service
  137. gnome-keyring-configuration
  138. gnome-keyring-configuration?
  139. gnome-keyring-service-type
  140. %desktop-services))
  141. ;;; Commentary:
  142. ;;;
  143. ;;; This module contains service definitions for a "desktop" environment.
  144. ;;;
  145. ;;; Code:
  146. ;;;
  147. ;;; Helpers.
  148. ;;;
  149. (define (bool value)
  150. (if value "true\n" "false\n"))
  151. (define (package-direct-input-selector input)
  152. (lambda (package)
  153. (match (assoc-ref (package-direct-inputs package) input)
  154. ((package . _) package))))
  155. ;;;
  156. ;;; Upower D-Bus service.
  157. ;;;
  158. (define-record-type* <upower-configuration>
  159. upower-configuration make-upower-configuration
  160. upower-configuration?
  161. (upower upower-configuration-upower
  162. (default upower))
  163. (watts-up-pro? upower-configuration-watts-up-pro?
  164. (default #f))
  165. (poll-batteries? upower-configuration-poll-batteries?
  166. (default #t))
  167. (ignore-lid? upower-configuration-ignore-lid?
  168. (default #f))
  169. (use-percentage-for-policy? upower-configuration-use-percentage-for-policy?
  170. (default #f))
  171. (percentage-low upower-configuration-percentage-low
  172. (default 10))
  173. (percentage-critical upower-configuration-percentage-critical
  174. (default 3))
  175. (percentage-action upower-configuration-percentage-action
  176. (default 2))
  177. (time-low upower-configuration-time-low
  178. (default 1200))
  179. (time-critical upower-configuration-time-critical
  180. (default 300))
  181. (time-action upower-configuration-time-action
  182. (default 120))
  183. (critical-power-action upower-configuration-critical-power-action
  184. (default 'hybrid-sleep)))
  185. (define* upower-configuration-file
  186. ;; Return an upower-daemon configuration file.
  187. (match-lambda
  188. (($ <upower-configuration> upower
  189. watts-up-pro? poll-batteries? ignore-lid? use-percentage-for-policy?
  190. percentage-low percentage-critical percentage-action time-low
  191. time-critical time-action critical-power-action)
  192. (plain-file "UPower.conf"
  193. (string-append
  194. "[UPower]\n"
  195. "EnableWattsUpPro=" (bool watts-up-pro?)
  196. "NoPollBatteries=" (bool (not poll-batteries?))
  197. "IgnoreLid=" (bool ignore-lid?)
  198. "UsePercentageForPolicy=" (bool use-percentage-for-policy?)
  199. "PercentageLow=" (number->string percentage-low) "\n"
  200. "PercentageCritical=" (number->string percentage-critical) "\n"
  201. "PercentageAction=" (number->string percentage-action) "\n"
  202. "TimeLow=" (number->string time-low) "\n"
  203. "TimeCritical=" (number->string time-critical) "\n"
  204. "TimeAction=" (number->string time-action) "\n"
  205. "CriticalPowerAction=" (match critical-power-action
  206. ('hybrid-sleep "HybridSleep")
  207. ('hibernate "Hibernate")
  208. ('power-off "PowerOff"))
  209. "\n")))))
  210. (define %upower-activation
  211. #~(begin
  212. (use-modules (guix build utils))
  213. (mkdir-p "/var/lib/upower")))
  214. (define (upower-dbus-service config)
  215. (list (wrapped-dbus-service (upower-configuration-upower config)
  216. "libexec/upowerd"
  217. `(("UPOWER_CONF_FILE_NAME"
  218. ,(upower-configuration-file config))))))
  219. (define (upower-shepherd-service config)
  220. "Return a shepherd service for UPower with CONFIG."
  221. (let ((upower (upower-configuration-upower config))
  222. (config (upower-configuration-file config)))
  223. (list (shepherd-service
  224. (documentation "Run the UPower power and battery monitor.")
  225. (provision '(upower-daemon))
  226. (requirement '(dbus-system udev))
  227. (start #~(make-forkexec-constructor
  228. (list (string-append #$upower "/libexec/upowerd"))
  229. #:environment-variables
  230. (list (string-append "UPOWER_CONF_FILE_NAME="
  231. #$config))))
  232. (stop #~(make-kill-destructor))))))
  233. (define upower-service-type
  234. (let ((upower-package (compose list upower-configuration-upower)))
  235. (service-type (name 'upower)
  236. (description
  237. "Run @command{upowerd}}, a system-wide monitor for power
  238. consumption and battery levels, with the given configuration settings. It
  239. implements the @code{org.freedesktop.UPower} D-Bus interface, and is notably
  240. used by GNOME.")
  241. (extensions
  242. (list (service-extension dbus-root-service-type
  243. upower-dbus-service)
  244. (service-extension shepherd-root-service-type
  245. upower-shepherd-service)
  246. (service-extension activation-service-type
  247. (const %upower-activation))
  248. (service-extension udev-service-type
  249. upower-package)
  250. ;; Make the 'upower' command visible.
  251. (service-extension profile-service-type
  252. upower-package)))
  253. (default-value (upower-configuration)))))
  254. ;;;
  255. ;;; GeoClue D-Bus service.
  256. ;;;
  257. ;; TODO: Export.
  258. (define-record-type* <geoclue-configuration>
  259. geoclue-configuration make-geoclue-configuration
  260. geoclue-configuration?
  261. (geoclue geoclue-configuration-geoclue
  262. (default geoclue))
  263. (whitelist geoclue-configuration-whitelist)
  264. (wifi-geolocation-url geoclue-configuration-wifi-geolocation-url)
  265. (submit-data? geoclue-configuration-submit-data?)
  266. (wifi-submission-url geoclue-configuration-wifi-submission-url)
  267. (submission-nick geoclue-configuration-submission-nick)
  268. (applications geoclue-configuration-applications))
  269. (define* (geoclue-application name #:key (allowed? #t) system? (users '()))
  270. "Configure default GeoClue access permissions for an application. NAME is
  271. the Desktop ID of the application, without the .desktop part. If ALLOWED? is
  272. true, the application will have access to location information by default.
  273. The boolean SYSTEM? value indicates that an application is a system component
  274. or not. Finally USERS is a list of UIDs of all users for which this
  275. application is allowed location info access. An empty users list means all
  276. users are allowed."
  277. (string-append
  278. "[" name "]\n"
  279. "allowed=" (bool allowed?)
  280. "system=" (bool system?)
  281. "users=" (string-join users ";") "\n"))
  282. (define %standard-geoclue-applications
  283. (list (geoclue-application "gnome-datetime-panel" #:system? #t)
  284. (geoclue-application "epiphany" #:system? #f)
  285. (geoclue-application "firefox" #:system? #f)))
  286. (define* (geoclue-configuration-file config)
  287. "Return a geoclue configuration file."
  288. (plain-file "geoclue.conf"
  289. (string-append
  290. "[agent]\n"
  291. "whitelist="
  292. (string-join (geoclue-configuration-whitelist config)
  293. ";") "\n"
  294. "[wifi]\n"
  295. "url=" (geoclue-configuration-wifi-geolocation-url config) "\n"
  296. "submit-data=" (bool (geoclue-configuration-submit-data? config))
  297. "submission-url="
  298. (geoclue-configuration-wifi-submission-url config) "\n"
  299. "submission-nick="
  300. (geoclue-configuration-submission-nick config)
  301. "\n"
  302. (string-join (geoclue-configuration-applications config)
  303. "\n"))))
  304. (define (geoclue-dbus-service config)
  305. (list (wrapped-dbus-service (geoclue-configuration-geoclue config)
  306. "libexec/geoclue"
  307. `(("GEOCLUE_CONFIG_FILE"
  308. ,(geoclue-configuration-file config))))))
  309. (define %geoclue-accounts
  310. (list (user-group (name "geoclue") (system? #t))
  311. (user-account
  312. (name "geoclue")
  313. (group "geoclue")
  314. (system? #t)
  315. (comment "GeoClue daemon user")
  316. (home-directory "/var/empty")
  317. (shell "/run/current-system/profile/sbin/nologin"))))
  318. (define geoclue-service-type
  319. (service-type (name 'geoclue)
  320. (extensions
  321. (list (service-extension dbus-root-service-type
  322. geoclue-dbus-service)
  323. (service-extension account-service-type
  324. (const %geoclue-accounts))))))
  325. (define* (geoclue-service #:key (geoclue geoclue)
  326. (whitelist '())
  327. (wifi-geolocation-url
  328. ;; Mozilla geolocation service:
  329. "https://location.services.mozilla.com/v1/geolocate?key=geoclue")
  330. (submit-data? #f)
  331. (wifi-submission-url
  332. "https://location.services.mozilla.com/v1/submit?key=geoclue")
  333. (submission-nick "geoclue")
  334. (applications %standard-geoclue-applications))
  335. "Return a service that runs the @command{geoclue} location service. This
  336. service provides a D-Bus interface to allow applications to request access to
  337. a user's physical location, and optionally to add information to online
  338. location databases. By default, only the GNOME date-time panel and the Icecat
  339. and Epiphany web browsers are able to ask for the user's location, and in the
  340. case of Icecat and Epiphany, both will ask the user for permission first. See
  341. @uref{https://wiki.freedesktop.org/www/Software/GeoClue/, the geoclue web
  342. site} for more information."
  343. (service geoclue-service-type
  344. (geoclue-configuration
  345. (geoclue geoclue)
  346. (whitelist whitelist)
  347. (wifi-geolocation-url wifi-geolocation-url)
  348. (submit-data? submit-data?)
  349. (wifi-submission-url wifi-submission-url)
  350. (submission-nick submission-nick)
  351. (applications applications))))
  352. ;;;
  353. ;;; Bluetooth.
  354. ;;;
  355. (define-record-type* <bluetooth-configuration>
  356. bluetooth-configuration make-bluetooth-configuration
  357. bluetooth-configuration?
  358. (bluez bluetooth-configuration-bluez (default bluez))
  359. ;;; [General]
  360. (name bluetooth-configuration-name (default "BlueZ"))
  361. (class bluetooth-configuration-class (default #x000000))
  362. (discoverable-timeout
  363. bluetooth-configuration-discoverable-timeout (default 180))
  364. (always-pairable? bluetooth-configuration-always-pairable? (default #f))
  365. (pairable-timeout bluetooth-configuration-pairable-timeout (default 0))
  366. ;;; MAYBE: Exclude into separate <device-id> record-type?
  367. (device-id bluetooth-configuration-device-id (default #f))
  368. (reverse-service-discovery?
  369. bluetooth-configuration-reverse-service-discovery (default #t))
  370. (name-resolving? bluetooth-configuration-name-resolving? (default #t))
  371. (debug-keys? bluetooth-configuration-debug-keys? (default #f))
  372. ;;; Possible values:
  373. ;;; 'dual, 'bredr, 'le
  374. (controller-mode bluetooth-configuration-controller-mode (default 'dual))
  375. ;;; Possible values:
  376. ;;; 'off, 'single, 'multiple
  377. (multi-profile bluetooth-configuration-multi-profile (default 'off))
  378. (fast-connectable? bluetooth-configuration-fast-connectable? (default #f))
  379. ;;; Possible values:
  380. ;;; for LE mode: 'off, 'network/on, 'device
  381. ;;; for Dual mode: 'off, 'network/on', 'device, 'limited-network, 'limited-device
  382. ;;; Source: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/src/main.conf#n68
  383. (privacy bluetooth-configuration-privacy (default 'off))
  384. ;;; Possible values:
  385. ;;; 'never, 'confirm, 'always
  386. (just-works-repairing
  387. bluetooth-configuration-just-works-repairing (default 'never))
  388. (temporary-timeout bluetooth-configuration-temporary-timeout (default 30))
  389. (refresh-discovery? bluetooth-configuration-refresh-discovery (default #t))
  390. ;;; Possible values: #t, #f, (uuid <uuid>)
  391. ;;; Possible UUIDs:
  392. ;;; d4992530-b9ec-469f-ab01-6c481c47da1c (BlueZ Experimental Debug)
  393. ;;; 671b10b5-42c0-4696-9227-eb28d1b049d6 (BlueZ Experimental Simultaneous Central and Peripheral)
  394. ;;; 15c0a148-c273-11ea-b3de-0242ac130004 (BlueZ Experimental LL privacy)
  395. ;;; 330859bc-7506-492d-9370-9a6f0614037f (BlueZ Experimental Bluetooth Quality Report)
  396. ;;; a6695ace-ee7f-4fb9-881a-5fac66c629af (BlueZ Experimental Offload Codecs)
  397. ;;; Source: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/src/main.conf#n110
  398. (experimental bluetooth-configuration-experimental (default #f))
  399. (remote-name-request-retry-delay
  400. bluetooth-configuration-remote-name-request-retry-delay (default 300))
  401. ;;; [BR]
  402. (page-scan-type bluetooth-configuration-page-scan-type (default #f))
  403. (page-scan-interval bluetooth-configuration-page-scan-interval (default #f))
  404. (page-scan-window bluetooth-configuration-page-scan-window (default #f))
  405. (inquiry-scan-type bluetooth-configuration-inquiry-scan-type (default #f))
  406. (inquiry-scan-interval bluetooth-configuration-inquiry-scan-interval (default #f))
  407. (inquiry-scan-window bluetooth-configuration-inquiry-scan-window (default #f))
  408. (link-supervision-timeout bluetooth-configuration-link-supervision-timeout (default #f))
  409. (page-timeout bluetooth-configuration-page-timeout (default #f))
  410. (min-sniff-interval bluetooth-configuration-min-sniff-interval (default #f))
  411. (max-sniff-interval bluetooth-configuration-max-sniff-interval (default #f))
  412. ;;; [LE]
  413. (min-advertisement-interval
  414. bluetooth-configuration-min-advertisement-interval (default #f))
  415. (max-advertisement-interval
  416. bluetooth-configuration-max-advertisement-interval (default #f))
  417. (multi-advertisement-rotation-interval
  418. bluetooth-configuration-multi-advertisement-rotation-interval (default #f))
  419. (scan-interval-auto-connect
  420. bluetooth-configuration-scan-interval-auto-connect (default #f))
  421. (scan-window-auto-connect
  422. bluetooth-configuration-scan-window-auto-connect (default #f))
  423. (scan-interval-suspend
  424. bluetooth-configuration-scan-interval-suspend (default #f))
  425. (scan-window-suspend
  426. bluetooth-configuration-scan-window-suspend (default #f))
  427. (scan-interval-discovery
  428. bluetooth-configuration-scan-interval-discovery (default #f))
  429. (scan-window-discovery
  430. bluetooth-configuration-scan-window-discovery (default #f))
  431. (scan-interval-adv-monitor
  432. bluetooth-configuration-scan-interval-adv-monitor (default #f))
  433. (scan-window-adv-monitor
  434. bluetooth-configuration-scan-window-adv-monitor (default #f))
  435. (scan-interval-connect
  436. bluetooth-configuration-scan-interval-connect (default #f))
  437. (scan-window-connect
  438. bluetooth-configuration-scan-window-connect (default #f))
  439. (min-connection-interval
  440. bluetooth-configuration-min-connection-interval (default #f))
  441. (max-connection-interval
  442. bluetooth-configuration-max-connection-interval (default #f))
  443. (connection-latency
  444. bluetooth-configuration-connection-latency (default #f))
  445. (connection-supervision-timeout
  446. bluetooth-configuration-connection-supervision-timeout (default #f))
  447. (autoconnect-timeout
  448. bluetooth-configuration-autoconnect-timeout (default #f))
  449. (adv-mon-allowlist-scan-duration
  450. bluetooth-configuration-adv-mon-allowlist-scan-duration (default 300))
  451. (adv-mon-no-filter-scan-duration
  452. bluetooth-configuration-adv-mon-no-filter-scan-duration (default 500))
  453. (enable-adv-mon-interleave-scan?
  454. bluetooth-configuration-enable-adv-mon-interleave-scan (default #t))
  455. ;;; [GATT]
  456. ;;; Possible values: 'yes, 'no, 'always
  457. (cache bluetooth-configuration-cache (default 'always))
  458. ;;; Possible values: 7 ... 16, 0 (don't care)
  459. (key-size bluetooth-configuration-key-size (default 0))
  460. ;;; Possible values: 23 ... 517
  461. (exchange-mtu bluetooth-configuration-exchange-mtu (default 517))
  462. ;;; Possible values: 1 ... 5
  463. (att-channels bluetooth-configuration-att-channels (default 3))
  464. ;;; [AVDTP]
  465. ;;; Possible values: 'basic, 'ertm
  466. (session-mode bluetooth-configuration-session-mode (default 'basic))
  467. ;;; Possible values: 'basic, 'streaming
  468. (stream-mode bluetooth-configuration-stream-mode (default 'basic))
  469. ;;; [Policy]
  470. (reconnect-uuids bluetooth-configuration-reconnect-uuids (default '()))
  471. (reconnect-attempts bluetooth-configuration-reconnect-attempts (default 7))
  472. (reconnect-intervals bluetooth-configuration-reconnect-intervals
  473. (default (list 1 2 4 8 16 32 64)))
  474. (auto-enable? bluetooth-configuration-auto-enable? (default #f))
  475. (resume-delay bluetooth-configuration-resume-delay (default 2))
  476. ;;; [AdvMon]
  477. ;;; Possible values:
  478. ;;; "0x00", "0xFF",
  479. ;;; "N = 0x00" ... "N = 0xFF"
  480. ;;; Source: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/src/main.conf#n286
  481. (rssi-sampling-period bluetooth-configuration-rssi-sampling-period
  482. (default #xFF)))
  483. (define (bluetooth-configuration-file config)
  484. "Return a configuration file for the systemd bluetooth service, as a string."
  485. (string-append
  486. "[General]"
  487. "\nName = " (bluetooth-configuration-name config)
  488. "\nClass = " (string-append
  489. "0x"
  490. (format #f "~6,'0x" (bluetooth-configuration-class config)))
  491. "\nDiscoverableTimeout = " (number->string
  492. (bluetooth-configuration-discoverable-timeout
  493. config))
  494. "\nAlwaysPairable = " (bool (bluetooth-configuration-always-pairable?
  495. config))
  496. "\nPairableTimeout = " (number->string
  497. (bluetooth-configuration-pairable-timeout
  498. config))
  499. (if (bluetooth-configuration-device-id config)
  500. (string-append "\nDeviceID = " (bluetooth-configuration-device-id config))
  501. "")
  502. "\nReverseServiceDiscovery = " (bool
  503. (bluetooth-configuration-reverse-service-discovery
  504. config))
  505. "\nNameResolving = " (bool (bluetooth-configuration-name-resolving? config))
  506. "\nDebugKeys = " (bool (bluetooth-configuration-debug-keys? config))
  507. "\nControllerMode = " (symbol->string
  508. (bluetooth-configuration-controller-mode config))
  509. "\nMultiProfile = " (symbol->string (bluetooth-configuration-multi-profile
  510. config))
  511. "\nFastConnectable = " (bool (bluetooth-configuration-fast-connectable? config))
  512. "\nPrivacy = " (symbol->string (bluetooth-configuration-privacy config))
  513. "\nJustWorksRepairing = " (symbol->string
  514. (bluetooth-configuration-just-works-repairing config))
  515. "\nTemporaryTimeout = " (number->string
  516. (bluetooth-configuration-temporary-timeout config))
  517. "\nRefreshDiscovery = " (bool (bluetooth-configuration-refresh-discovery config))
  518. "\nExperimental = " (let ((experimental (bluetooth-configuration-experimental config)))
  519. (cond ((or (eq? experimental #t)
  520. (eq? experimental #f)) (bool experimental))
  521. ((list? experimental)
  522. (string-join (map uuid->string experimental) ","))))
  523. "\nRemoteNameRequestRetryDelay = " (number->string
  524. (bluetooth-configuration-remote-name-request-retry-delay
  525. config))
  526. "\n[BR]"
  527. (if (bluetooth-configuration-page-scan-type config)
  528. (string-append
  529. "\nPageScanType = "
  530. (number->string (bluetooth-configuration-page-scan-type config)))
  531. "")
  532. (if (bluetooth-configuration-page-scan-interval config)
  533. (string-append
  534. "\nPageScanInterval = "
  535. (number->string (bluetooth-configuration-page-scan-interval config)))
  536. "")
  537. (if (bluetooth-configuration-page-scan-window config)
  538. (string-append
  539. "\nPageScanWindow = "
  540. (number->string (bluetooth-configuration-page-scan-window config)))
  541. "")
  542. (if (bluetooth-configuration-inquiry-scan-type config)
  543. (string-append
  544. "\nInquiryScanType = "
  545. (number->string (bluetooth-configuration-inquiry-scan-type config)))
  546. "")
  547. (if (bluetooth-configuration-inquiry-scan-interval config)
  548. (string-append
  549. "\nInquiryScanInterval = "
  550. (number->string (bluetooth-configuration-inquiry-scan-interval config)))
  551. "")
  552. (if (bluetooth-configuration-inquiry-scan-window config)
  553. (string-append
  554. "\nInquiryScanWindow = "
  555. (number->string (bluetooth-configuration-inquiry-scan-window config)))
  556. "")
  557. (if (bluetooth-configuration-link-supervision-timeout config)
  558. (string-append
  559. "\nLinkSupervisionTimeout = "
  560. (number->string (bluetooth-configuration-link-supervision-timeout config)))
  561. "")
  562. (if (bluetooth-configuration-page-timeout config)
  563. (string-append
  564. "\nPageTimeout = "
  565. (number->string (bluetooth-configuration-page-timeout config)))
  566. "")
  567. (if (bluetooth-configuration-min-sniff-interval config)
  568. (string-append
  569. "\nMinSniffInterval = "
  570. (number->string (bluetooth-configuration-min-sniff-interval config)))
  571. "")
  572. (if (bluetooth-configuration-max-sniff-interval config)
  573. (string-append
  574. "\nMaxSniffInterval = "
  575. (number->string (bluetooth-configuration-max-sniff-interval config)))
  576. "")
  577. "\n[LE]"
  578. (if (bluetooth-configuration-min-advertisement-interval config)
  579. (string-append
  580. "\nMinAdvertisementInterval = "
  581. (number->string (bluetooth-configuration-min-advertisement-interval config)))
  582. "")
  583. (if (bluetooth-configuration-max-advertisement-interval config)
  584. (string-append
  585. "\nMaxAdvertisementInterval = "
  586. (number->string (bluetooth-configuration-max-advertisement-interval config)))
  587. "")
  588. (if (bluetooth-configuration-multi-advertisement-rotation-interval config)
  589. (string-append
  590. "\nMultiAdvertisementRotationInterval = "
  591. (number->string
  592. (bluetooth-configuration-multi-advertisement-rotation-interval config)))
  593. "")
  594. (if (bluetooth-configuration-scan-interval-auto-connect config)
  595. (string-append
  596. "\nScanIntervalAutoConnect = "
  597. (number->string (bluetooth-configuration-scan-interval-auto-connect config)))
  598. "")
  599. (if (bluetooth-configuration-scan-window-auto-connect config)
  600. (string-append
  601. "\nScanWindowAutoConnect = "
  602. (number->string (bluetooth-configuration-scan-window-auto-connect config)))
  603. "")
  604. (if (bluetooth-configuration-scan-interval-suspend config)
  605. (string-append
  606. "\nScanIntervalSuspend = "
  607. (number->string (bluetooth-configuration-scan-interval-suspend config)))
  608. "")
  609. (if (bluetooth-configuration-scan-window-suspend config)
  610. (string-append
  611. "\nScanWindowSuspend = "
  612. (number->string (bluetooth-configuration-scan-window-suspend config)))
  613. "")
  614. (if (bluetooth-configuration-scan-interval-discovery config)
  615. (string-append
  616. "\nScanIntervalDiscovery = "
  617. (number->string (bluetooth-configuration-scan-interval-discovery config)))
  618. "")
  619. (if (bluetooth-configuration-scan-window-discovery config)
  620. (string-append
  621. "\nScanWindowDiscovery = "
  622. (number->string (bluetooth-configuration-scan-window-discovery config)))
  623. "")
  624. (if (bluetooth-configuration-scan-interval-adv-monitor config)
  625. (string-append
  626. "\nScanIntervalAdvMonitor = "
  627. (number->string (bluetooth-configuration-scan-interval-adv-monitor config)))
  628. "")
  629. (if (bluetooth-configuration-scan-window-adv-monitor config)
  630. (string-append
  631. "\nScanWindowAdvMonitor = "
  632. (number->string (bluetooth-configuration-scan-window-adv-monitor config)))
  633. "")
  634. (if (bluetooth-configuration-scan-interval-connect config)
  635. (string-append
  636. "\nScanIntervalConnect = "
  637. (number->string (bluetooth-configuration-scan-interval-connect config)))
  638. "")
  639. (if (bluetooth-configuration-scan-window-connect config)
  640. (string-append
  641. "\nScanWindowConnect = "
  642. (number->string (bluetooth-configuration-scan-window-connect config)))
  643. "")
  644. (if (bluetooth-configuration-min-connection-interval config)
  645. (string-append
  646. "\nMinConnectionInterval = "
  647. (number->string (bluetooth-configuration-min-connection-interval config)))
  648. "")
  649. (if (bluetooth-configuration-max-connection-interval config)
  650. (string-append
  651. "\nMaxConnectionInterval = "
  652. (number->string (bluetooth-configuration-max-connection-interval config)))
  653. "")
  654. (if (bluetooth-configuration-connection-latency config)
  655. (string-append
  656. "\nConnectionLatency = "
  657. (number->string (bluetooth-configuration-connection-latency config)))
  658. "")
  659. (if (bluetooth-configuration-connection-supervision-timeout config)
  660. (string-append
  661. "\nConnectionSupervisionTimeout = "
  662. (number->string (bluetooth-configuration-connection-supervision-timeout config)))
  663. "")
  664. (if (bluetooth-configuration-autoconnect-timeout config)
  665. (string-append
  666. "\nAutoconnecttimeout = "
  667. (number->string (bluetooth-configuration-autoconnect-timeout config)))
  668. "")
  669. "\nAdvMonAllowlistScanDuration = " (number->string
  670. (bluetooth-configuration-adv-mon-allowlist-scan-duration
  671. config))
  672. "\nAdvMonNoFilterScanDuration = " (number->string
  673. (bluetooth-configuration-adv-mon-no-filter-scan-duration
  674. config))
  675. "\nEnableAdvMonInterleaveScan = " (number->string
  676. (if (eq? #t
  677. (bluetooth-configuration-enable-adv-mon-interleave-scan
  678. config))
  679. 1 0))
  680. "\n[GATT]"
  681. "\nCache = " (symbol->string (bluetooth-configuration-cache config))
  682. "\nKeySize = " (number->string (bluetooth-configuration-key-size config))
  683. "\nExchangeMTU = " (number->string (bluetooth-configuration-exchange-mtu config))
  684. "\nChannels = " (number->string (bluetooth-configuration-att-channels config))
  685. "\n[AVDTP]"
  686. "\nSessionMode = " (symbol->string (bluetooth-configuration-session-mode config))
  687. "\nStreamMode = " (symbol->string (bluetooth-configuration-stream-mode config))
  688. "\n[Policy]"
  689. (let ((uuids (bluetooth-configuration-reconnect-uuids config)))
  690. (if (not (eq? '() uuids))
  691. (string-append
  692. "\nReconnectUUIDs = "
  693. (string-join (map uuid->string uuids) ","))
  694. ""))
  695. "\nReconnectAttempts = " (number->string
  696. (bluetooth-configuration-reconnect-attempts config))
  697. "\nReconnectIntervals = " (string-join
  698. (map number->string
  699. (bluetooth-configuration-reconnect-intervals
  700. config))
  701. ",")
  702. "\nAutoEnable = " (bool (bluetooth-configuration-auto-enable?
  703. config))
  704. "\nResumeDelay = " (number->string (bluetooth-configuration-resume-delay config))
  705. "\n[AdvMon]"
  706. "\nRSSISamplingPeriod = " (string-append
  707. "0x"
  708. (format #f "~2,'0x"
  709. (bluetooth-configuration-rssi-sampling-period config)))))
  710. (define (bluetooth-directory config)
  711. (computed-file "etc-bluetooth"
  712. #~(begin
  713. (mkdir #$output)
  714. (chdir #$output)
  715. (call-with-output-file "main.conf"
  716. (lambda (port)
  717. (display #$(bluetooth-configuration-file config)
  718. port))))))
  719. (define (bluetooth-shepherd-service config)
  720. "Return a shepherd service for @command{bluetoothd}."
  721. (shepherd-service
  722. (provision '(bluetooth))
  723. (requirement '(dbus-system udev))
  724. (documentation "Run the bluetoothd daemon.")
  725. (start #~(make-forkexec-constructor
  726. (list #$(file-append (bluetooth-configuration-bluez config)
  727. "/libexec/bluetooth/bluetoothd"))))
  728. (stop #~(make-kill-destructor))))
  729. (define bluetooth-service-type
  730. (service-type
  731. (name 'bluetooth)
  732. (extensions
  733. (list (service-extension dbus-root-service-type
  734. (compose list bluetooth-configuration-bluez))
  735. (service-extension udev-service-type
  736. (compose list bluetooth-configuration-bluez))
  737. (service-extension etc-service-type
  738. (lambda (config)
  739. `(("bluetooth"
  740. ,(bluetooth-directory config)))))
  741. (service-extension shepherd-root-service-type
  742. (compose list bluetooth-shepherd-service))))
  743. (default-value (bluetooth-configuration))
  744. (description "Run the @command{bluetoothd} daemon, which manages all the
  745. Bluetooth devices and provides a number of D-Bus interfaces.")))
  746. (define* (bluetooth-service #:key (bluez bluez) (auto-enable? #f))
  747. "Return a service that runs the @command{bluetoothd} daemon, which manages
  748. all the Bluetooth devices and provides a number of D-Bus interfaces. When
  749. AUTO-ENABLE? is true, the bluetooth controller is powered automatically at
  750. boot.
  751. Users need to be in the @code{lp} group to access the D-Bus service.
  752. "
  753. (service bluetooth-service-type
  754. (bluetooth-configuration
  755. (bluez bluez)
  756. (auto-enable? auto-enable?))))
  757. ;;;
  758. ;;; Colord D-Bus service.
  759. ;;;
  760. (define %colord-activation
  761. #~(begin
  762. (use-modules (guix build utils))
  763. (mkdir-p "/var/lib/colord")
  764. (let ((user (getpwnam "colord")))
  765. (chown "/var/lib/colord"
  766. (passwd:uid user) (passwd:gid user)))))
  767. (define %colord-accounts
  768. (list (user-group (name "colord") (system? #t))
  769. (user-account
  770. (name "colord")
  771. (group "colord")
  772. (system? #t)
  773. (comment "colord daemon user")
  774. (home-directory "/var/empty")
  775. (shell (file-append shadow "/sbin/nologin")))))
  776. (define colord-service-type
  777. (service-type (name 'colord)
  778. (extensions
  779. (list (service-extension account-service-type
  780. (const %colord-accounts))
  781. (service-extension activation-service-type
  782. (const %colord-activation))
  783. ;; Colord is a D-Bus service that dbus-daemon can
  784. ;; activate.
  785. (service-extension dbus-root-service-type list)
  786. ;; Colord provides "color device" rules for udev.
  787. (service-extension udev-service-type list)
  788. ;; It provides polkit "actions".
  789. (service-extension polkit-service-type list)))
  790. (default-value colord)
  791. (description
  792. "Run @command{colord}, a system service with a D-Bus
  793. interface to manage the color profiles of input and output devices such as
  794. screens and scanners.")))
  795. ;;;
  796. ;;; UDisks.
  797. ;;;
  798. (define-record-type* <udisks-configuration>
  799. udisks-configuration make-udisks-configuration
  800. udisks-configuration?
  801. (udisks udisks-configuration-udisks
  802. (default udisks)))
  803. (define %udisks-activation
  804. (with-imported-modules '((guix build utils))
  805. #~(begin
  806. (use-modules (guix build utils))
  807. (let ((run-dir "/var/run/udisks2"))
  808. (mkdir-p run-dir)
  809. (chmod run-dir #o700)))))
  810. (define udisks-service-type
  811. (let ((udisks-package (lambda (config)
  812. (list (udisks-configuration-udisks config)))))
  813. (service-type (name 'udisks)
  814. (extensions
  815. (list (service-extension polkit-service-type
  816. udisks-package)
  817. (service-extension dbus-root-service-type
  818. udisks-package)
  819. (service-extension udev-service-type
  820. udisks-package)
  821. (service-extension activation-service-type
  822. (const %udisks-activation))
  823. ;; Profile 'udisksctl' & co. in the system profile.
  824. (service-extension profile-service-type
  825. udisks-package))))))
  826. (define* (udisks-service #:key (udisks udisks))
  827. "Return a service for @uref{http://udisks.freedesktop.org/docs/latest/,
  828. UDisks}, a @dfn{disk management} daemon that provides user interfaces with
  829. notifications and ways to mount/unmount disks. Programs that talk to UDisks
  830. include the @command{udisksctl} command, part of UDisks, and GNOME Disks."
  831. (service udisks-service-type
  832. (udisks-configuration (udisks udisks))))
  833. ;;;
  834. ;;; Elogind login and seat management service.
  835. ;;;
  836. (define-record-type* <elogind-configuration> elogind-configuration
  837. make-elogind-configuration
  838. elogind-configuration?
  839. (elogind elogind-package
  840. (default elogind))
  841. (kill-user-processes? elogind-kill-user-processes?
  842. (default #f))
  843. (kill-only-users elogind-kill-only-users
  844. (default '()))
  845. (kill-exclude-users elogind-kill-exclude-users
  846. (default '("root")))
  847. (inhibit-delay-max-seconds elogind-inhibit-delay-max-seconds
  848. (default 5))
  849. (handle-power-key elogind-handle-power-key
  850. (default 'poweroff))
  851. (handle-suspend-key elogind-handle-suspend-key
  852. (default 'suspend))
  853. (handle-hibernate-key elogind-handle-hibernate-key
  854. ;; (default 'hibernate)
  855. ;; XXX Ignore it for now, since we don't
  856. ;; yet handle resume-from-hibernation in
  857. ;; our initrd.
  858. (default 'ignore))
  859. (handle-lid-switch elogind-handle-lid-switch
  860. (default 'suspend))
  861. (handle-lid-switch-docked elogind-handle-lid-switch-docked
  862. (default 'ignore))
  863. (handle-lid-switch-external-power elogind-handle-lid-switch-external-power
  864. (default 'ignore))
  865. (power-key-ignore-inhibited? elogind-power-key-ignore-inhibited?
  866. (default #f))
  867. (suspend-key-ignore-inhibited? elogind-suspend-key-ignore-inhibited?
  868. (default #f))
  869. (hibernate-key-ignore-inhibited? elogind-hibernate-key-ignore-inhibited?
  870. (default #f))
  871. (lid-switch-ignore-inhibited? elogind-lid-switch-ignore-inhibited?
  872. (default #t))
  873. (holdoff-timeout-seconds elogind-holdoff-timeout-seconds
  874. (default 30))
  875. (idle-action elogind-idle-action
  876. (default 'ignore))
  877. (idle-action-seconds elogind-idle-action-seconds
  878. (default (* 30 60)))
  879. (runtime-directory-size-percent elogind-runtime-directory-size-percent
  880. (default 10))
  881. (runtime-directory-size elogind-runtime-directory-size
  882. (default #f))
  883. (remove-ipc? elogind-remove-ipc?
  884. (default #t))
  885. (suspend-state elogind-suspend-state
  886. (default '("mem" "standby" "freeze")))
  887. (suspend-mode elogind-suspend-mode
  888. (default '()))
  889. (hibernate-state elogind-hibernate-state
  890. (default '("disk")))
  891. (hibernate-mode elogind-hibernate-mode
  892. (default '("platform" "shutdown")))
  893. (hybrid-sleep-state elogind-hybrid-sleep-state
  894. (default '("disk")))
  895. (hybrid-sleep-mode elogind-hybrid-sleep-mode
  896. (default
  897. '("suspend" "platform" "shutdown"))))
  898. (define (elogind-configuration-file config)
  899. (define (yesno x)
  900. (match x
  901. (#t "yes")
  902. (#f "no")
  903. (_ (error "expected #t or #f, instead got:" x))))
  904. (define char-set:user-name
  905. (string->char-set "abcdefghijklmnopqrstuvwxyz0123456789_-"))
  906. (define (valid-list? l pred)
  907. (and-map (lambda (x) (string-every pred x)) l))
  908. (define (user-name-list users)
  909. (unless (valid-list? users char-set:user-name)
  910. (error "invalid user list" users))
  911. (string-join users " "))
  912. (define (enum val allowed)
  913. (unless (memq val allowed)
  914. (error "invalid value" val allowed))
  915. (symbol->string val))
  916. (define (non-negative-integer x)
  917. (unless (exact-integer? x) (error "not an integer" x))
  918. (when (negative? x) (error "negative number not allowed" x))
  919. (number->string x))
  920. (define handle-actions
  921. '(ignore poweroff reboot halt kexec suspend hibernate hybrid-sleep lock))
  922. (define (handle-action x)
  923. (enum x handle-actions))
  924. (define (sleep-list tokens)
  925. (unless (valid-list? tokens char-set:user-name)
  926. (error "invalid sleep list" tokens))
  927. (string-join tokens " "))
  928. (define-syntax ini-file-clause
  929. (syntax-rules ()
  930. ((_ config (prop (parser getter)))
  931. (string-append prop "=" (parser (getter config)) "\n"))
  932. ((_ config str)
  933. (string-append str "\n"))))
  934. (define-syntax-rule (ini-file config file clause ...)
  935. (plain-file file (string-append (ini-file-clause config clause) ...)))
  936. (ini-file
  937. config "logind.conf"
  938. "[Login]"
  939. ("KillUserProcesses" (yesno elogind-kill-user-processes?))
  940. ("KillOnlyUsers" (user-name-list elogind-kill-only-users))
  941. ("KillExcludeUsers" (user-name-list elogind-kill-exclude-users))
  942. ("InhibitDelayMaxSec" (non-negative-integer elogind-inhibit-delay-max-seconds))
  943. ("HandlePowerKey" (handle-action elogind-handle-power-key))
  944. ("HandleSuspendKey" (handle-action elogind-handle-suspend-key))
  945. ("HandleHibernateKey" (handle-action elogind-handle-hibernate-key))
  946. ("HandleLidSwitch" (handle-action elogind-handle-lid-switch))
  947. ("HandleLidSwitchDocked" (handle-action elogind-handle-lid-switch-docked))
  948. ("HandleLidSwitchExternalPower" (handle-action elogind-handle-lid-switch-external-power))
  949. ("PowerKeyIgnoreInhibited" (yesno elogind-power-key-ignore-inhibited?))
  950. ("SuspendKeyIgnoreInhibited" (yesno elogind-suspend-key-ignore-inhibited?))
  951. ("HibernateKeyIgnoreInhibited" (yesno elogind-hibernate-key-ignore-inhibited?))
  952. ("LidSwitchIgnoreInhibited" (yesno elogind-lid-switch-ignore-inhibited?))
  953. ("HoldoffTimeoutSec" (non-negative-integer elogind-holdoff-timeout-seconds))
  954. ("IdleAction" (handle-action elogind-idle-action))
  955. ("IdleActionSec" (non-negative-integer elogind-idle-action-seconds))
  956. ("RuntimeDirectorySize"
  957. (identity
  958. (lambda (config)
  959. (match (elogind-runtime-directory-size-percent config)
  960. (#f (non-negative-integer (elogind-runtime-directory-size config)))
  961. (percent (string-append (non-negative-integer percent) "%"))))))
  962. ("RemoveIPC" (yesno elogind-remove-ipc?))
  963. "[Sleep]"
  964. ("SuspendState" (sleep-list elogind-suspend-state))
  965. ("SuspendMode" (sleep-list elogind-suspend-mode))
  966. ("HibernateState" (sleep-list elogind-hibernate-state))
  967. ("HibernateMode" (sleep-list elogind-hibernate-mode))
  968. ("HybridSleepState" (sleep-list elogind-hybrid-sleep-state))
  969. ("HybridSleepMode" (sleep-list elogind-hybrid-sleep-mode))))
  970. (define (elogind-dbus-service config)
  971. (list (wrapped-dbus-service (elogind-package config)
  972. "libexec/elogind/elogind"
  973. `(("ELOGIND_CONF_FILE"
  974. ,(elogind-configuration-file config))))))
  975. (define (pam-extension-procedure config)
  976. "Return an extension for PAM-ROOT-SERVICE-TYPE that ensures that all the PAM
  977. services use 'pam_elogind.so', a module that allows elogind to keep track of
  978. logged-in users (run 'loginctl' to see elogind's world view of users and
  979. seats.)"
  980. (define pam-elogind
  981. (pam-entry
  982. (control "required")
  983. (module (file-append (elogind-package config)
  984. "/lib/security/pam_elogind.so"))))
  985. (list (lambda (pam)
  986. (pam-service
  987. (inherit pam)
  988. (session (cons pam-elogind (pam-service-session pam)))))))
  989. (define (elogind-shepherd-service config)
  990. "Return a Shepherd service to start elogind according to @var{config}."
  991. (list (shepherd-service
  992. (requirement '(dbus-system))
  993. (provision '(elogind))
  994. (start #~(make-forkexec-constructor
  995. (list #$(file-append (elogind-package config)
  996. "/libexec/elogind/elogind"))
  997. #:environment-variables
  998. (list (string-append "ELOGIND_CONF_FILE="
  999. #$(elogind-configuration-file
  1000. config)))))
  1001. (stop #~(make-kill-destructor)))))
  1002. (define elogind-service-type
  1003. (service-type (name 'elogind)
  1004. (extensions
  1005. (list (service-extension dbus-root-service-type
  1006. elogind-dbus-service)
  1007. (service-extension udev-service-type
  1008. (compose list elogind-package))
  1009. (service-extension polkit-service-type
  1010. (compose list elogind-package))
  1011. ;; Start elogind from the Shepherd rather than waiting
  1012. ;; for bus activation. This ensures that it can handle
  1013. ;; events like lid close, etc.
  1014. (service-extension shepherd-root-service-type
  1015. elogind-shepherd-service)
  1016. ;; Provide the 'loginctl' command.
  1017. (service-extension profile-service-type
  1018. (compose list elogind-package))
  1019. ;; Extend PAM with pam_elogind.so.
  1020. (service-extension pam-root-service-type
  1021. pam-extension-procedure)
  1022. ;; We need /run/user, /run/systemd, etc.
  1023. (service-extension file-system-service-type
  1024. (const %elogind-file-systems))))
  1025. (default-value (elogind-configuration))))
  1026. (define* (elogind-service #:key (config (elogind-configuration)))
  1027. "Return a service that runs the @command{elogind} login and seat management
  1028. service. The @command{elogind} service integrates with PAM to allow other
  1029. system components to know the set of logged-in users as well as their session
  1030. types (graphical, console, remote, etc.). It can also clean up after users
  1031. when they log out."
  1032. (service elogind-service-type config))
  1033. ;;;
  1034. ;;; Fontconfig and other desktop file-systems.
  1035. ;;;
  1036. (define %fontconfig-file-system
  1037. (file-system
  1038. (device "none")
  1039. (mount-point "/var/cache/fontconfig")
  1040. (type "tmpfs")
  1041. (flags '(read-only))
  1042. (check? #f)))
  1043. ;; The global fontconfig cache directory can sometimes contain stale entries,
  1044. ;; possibly referencing fonts that have been GC'd, so mount it read-only.
  1045. ;; As mentioned https://debbugs.gnu.org/cgi/bugreport.cgi?bug=36924#8 and
  1046. ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=38046#10 and elsewhere.
  1047. (define fontconfig-file-system-service
  1048. (simple-service 'fontconfig-file-system
  1049. file-system-service-type
  1050. (list %fontconfig-file-system)))
  1051. ;;;
  1052. ;;; AccountsService service.
  1053. ;;;
  1054. (define %accountsservice-activation
  1055. #~(begin
  1056. (use-modules (guix build utils))
  1057. (mkdir-p "/var/lib/AccountsService")))
  1058. (define accountsservice-service-type
  1059. (service-type (name 'accountsservice)
  1060. (extensions
  1061. (list (service-extension activation-service-type
  1062. (const %accountsservice-activation))
  1063. (service-extension dbus-root-service-type list)
  1064. (service-extension polkit-service-type list)))
  1065. (default-value accountsservice)))
  1066. (define* (accountsservice-service #:key (accountsservice accountsservice))
  1067. "Return a service that runs AccountsService, a system service that
  1068. can list available accounts, change their passwords, and so on.
  1069. AccountsService integrates with PolicyKit to enable unprivileged users to
  1070. acquire the capability to modify their system configuration.
  1071. @uref{https://www.freedesktop.org/wiki/Software/AccountsService/, the
  1072. accountsservice web site} for more information."
  1073. (service accountsservice-service-type accountsservice))
  1074. ;;;
  1075. ;;; cups-pk-helper service.
  1076. ;;;
  1077. (define cups-pk-helper-service-type
  1078. (service-type
  1079. (name 'cups-pk-helper)
  1080. (description
  1081. "PolicyKit helper to configure CUPS with fine-grained privileges.")
  1082. (extensions
  1083. (list (service-extension dbus-root-service-type list)
  1084. (service-extension polkit-service-type list)))
  1085. (default-value cups-pk-helper)))
  1086. ;;;
  1087. ;;; Scanner access via SANE.
  1088. ;;;
  1089. (define %sane-accounts
  1090. ;; The '60-libsane.rules' udev rules refers to the "scanner" group.
  1091. (list (user-group (name "scanner") (system? #t))))
  1092. (define sane-service-type
  1093. (service-type
  1094. (name 'sane)
  1095. (description
  1096. "This service provides access to scanners @i{via}
  1097. @uref{http://www.sane-project.org, SANE} by installing the necessary udev
  1098. rules.")
  1099. (default-value sane-backends-minimal)
  1100. (extensions
  1101. (list (service-extension udev-service-type list)
  1102. (service-extension account-service-type
  1103. (const %sane-accounts))))))
  1104. ;;;
  1105. ;;; GNOME desktop service.
  1106. ;;;
  1107. (define-record-type* <gnome-desktop-configuration> gnome-desktop-configuration
  1108. make-gnome-desktop-configuration
  1109. gnome-desktop-configuration?
  1110. (gnome gnome-package (default gnome)))
  1111. (define (gnome-packages config packages)
  1112. "Return the list of GNOME dependencies from CONFIG which names are part of
  1113. the given PACKAGES list."
  1114. (let ((gnome (gnome-package config)))
  1115. (map (lambda (name)
  1116. ((package-direct-input-selector name) gnome))
  1117. packages)))
  1118. (define (gnome-udev-rules config)
  1119. "Return the list of GNOME dependencies that provide udev rules."
  1120. (gnome-packages config '("gnome-settings-daemon")))
  1121. (define (gnome-polkit-settings config)
  1122. "Return the list of GNOME dependencies that provide polkit actions and
  1123. rules."
  1124. (gnome-packages config
  1125. '("gnome-settings-daemon"
  1126. "gnome-control-center"
  1127. "gnome-system-monitor"
  1128. "gvfs")))
  1129. (define gnome-desktop-service-type
  1130. (service-type
  1131. (name 'gnome-desktop)
  1132. (extensions
  1133. (list (service-extension udev-service-type
  1134. gnome-udev-rules)
  1135. (service-extension polkit-service-type
  1136. gnome-polkit-settings)
  1137. (service-extension profile-service-type
  1138. (compose list
  1139. gnome-package))))
  1140. (default-value (gnome-desktop-configuration))
  1141. (description "Run the GNOME desktop environment.")))
  1142. (define-deprecated (gnome-desktop-service #:key (config
  1143. (gnome-desktop-configuration)))
  1144. gnome-desktop-service-type
  1145. "Return a service that adds the @code{gnome} package to the system profile,
  1146. and extends polkit with the actions from @code{gnome-settings-daemon}."
  1147. (service gnome-desktop-service-type config))
  1148. ;; MATE Desktop service.
  1149. ;; TODO: Add mate-screensaver.
  1150. (define-record-type* <mate-desktop-configuration> mate-desktop-configuration
  1151. make-mate-desktop-configuration
  1152. mate-desktop-configuration?
  1153. (mate-package mate-package (default mate)))
  1154. (define (mate-polkit-extension config)
  1155. "Return the list of packages for CONFIG's MATE package that extend polkit."
  1156. (let ((mate (mate-package config)))
  1157. (map (lambda (input)
  1158. ((package-direct-input-selector input) mate))
  1159. '("mate-system-monitor" ;kill, renice processes
  1160. "mate-settings-daemon" ;date/time settings
  1161. "mate-power-manager" ;modify brightness
  1162. "mate-control-center" ;RandR, display properties FIXME
  1163. "mate-applets")))) ;CPU frequency scaling
  1164. (define mate-desktop-service-type
  1165. (service-type
  1166. (name 'mate-desktop)
  1167. (extensions
  1168. (list (service-extension polkit-service-type
  1169. mate-polkit-extension)
  1170. (service-extension profile-service-type
  1171. (compose list
  1172. mate-package))))
  1173. (default-value (mate-desktop-configuration))
  1174. (description "Run the MATE desktop environment.")))
  1175. (define-deprecated (mate-desktop-service #:key
  1176. (config
  1177. (mate-desktop-configuration)))
  1178. mate-desktop-service-type
  1179. "Return a service that adds the @code{mate} package to the system profile,
  1180. and extends polkit with the actions from @code{mate-settings-daemon}."
  1181. (service mate-desktop-service-type config))
  1182. ;;;
  1183. ;;; XFCE desktop service.
  1184. ;;;
  1185. (define-record-type* <xfce-desktop-configuration> xfce-desktop-configuration
  1186. make-xfce-desktop-configuration
  1187. xfce-desktop-configuration?
  1188. (xfce xfce-package (default xfce)))
  1189. (define (xfce-polkit-settings config)
  1190. "Return the list of XFCE dependencies that provide polkit actions and
  1191. rules."
  1192. (let ((xfce (xfce-package config)))
  1193. (map (lambda (name)
  1194. ((package-direct-input-selector name) xfce))
  1195. '("thunar"
  1196. "xfce4-power-manager"))))
  1197. (define xfce-desktop-service-type
  1198. (service-type
  1199. (name 'xfce-desktop)
  1200. (extensions
  1201. (list (service-extension polkit-service-type
  1202. xfce-polkit-settings)
  1203. (service-extension profile-service-type
  1204. (compose list xfce-package))))
  1205. (default-value (xfce-desktop-configuration))
  1206. (description "Run the Xfce desktop environment.")))
  1207. (define-deprecated (xfce-desktop-service #:key (config
  1208. (xfce-desktop-configuration)))
  1209. xfce-desktop-service-type
  1210. "Return a service that adds the @code{xfce} package to the system profile,
  1211. and extends polkit with the ability for @code{thunar} to manipulate the file
  1212. system as root from within a user session, after the user has authenticated
  1213. with the administrator's password."
  1214. (service xfce-desktop-service-type config))
  1215. +
  1216. ;;;
  1217. ;;; Lxqt desktop service.
  1218. ;;;
  1219. (define-record-type* <lxqt-desktop-configuration> lxqt-desktop-configuration
  1220. make-lxqt-desktop-configuration
  1221. lxqt-desktop-configuration?
  1222. (lxqt lxqt-package
  1223. (default lxqt)))
  1224. (define (lxqt-polkit-settings config)
  1225. "Return the list of LXQt dependencies that provide polkit actions and
  1226. rules."
  1227. (let ((lxqt (lxqt-package config)))
  1228. (map (lambda (name)
  1229. ((package-direct-input-selector name) lxqt))
  1230. '("lxqt-admin"))))
  1231. (define lxqt-desktop-service-type
  1232. (service-type
  1233. (name 'lxqt-desktop)
  1234. (extensions
  1235. (list (service-extension polkit-service-type
  1236. lxqt-polkit-settings)
  1237. (service-extension profile-service-type
  1238. (compose list lxqt-package))))
  1239. (default-value (lxqt-desktop-configuration))
  1240. (description "Run LXQt desktop environment.")))
  1241. ;;;
  1242. ;;; X11 socket directory service
  1243. ;;;
  1244. (define x11-socket-directory-service
  1245. ;; Return a service that creates /tmp/.X11-unix. When using X11, libxcb
  1246. ;; takes care of creating that directory. However, when using XWayland, we
  1247. ;; need to create beforehand. Thus, create it unconditionally here.
  1248. (simple-service 'x11-socket-directory
  1249. activation-service-type
  1250. (with-imported-modules '((guix build utils))
  1251. #~(begin
  1252. (use-modules (guix build utils))
  1253. (let ((directory "/tmp/.X11-unix"))
  1254. (mkdir-p directory)
  1255. (chmod directory #o1777))))))
  1256. ;;;
  1257. ;;; Enlightenment desktop service.
  1258. ;;;
  1259. (define-record-type* <enlightenment-desktop-configuration>
  1260. enlightenment-desktop-configuration make-enlightenment-desktop-configuration
  1261. enlightenment-desktop-configuration?
  1262. ;; <package>
  1263. (enlightenment enlightenment-package
  1264. (default enlightenment)))
  1265. (define (enlightenment-setuid-programs enlightenment-desktop-configuration)
  1266. (match-record enlightenment-desktop-configuration
  1267. <enlightenment-desktop-configuration>
  1268. (enlightenment)
  1269. (map file-like->setuid-program
  1270. (list (file-append enlightenment
  1271. "/lib/enlightenment/utils/enlightenment_sys")
  1272. (file-append enlightenment
  1273. "/lib/enlightenment/utils/enlightenment_system")
  1274. (file-append enlightenment
  1275. "/lib/enlightenment/utils/enlightenment_ckpasswd")))))
  1276. (define enlightenment-desktop-service-type
  1277. (service-type
  1278. (name 'enlightenment-desktop)
  1279. (extensions
  1280. (list (service-extension dbus-root-service-type
  1281. (compose list
  1282. (package-direct-input-selector
  1283. "efl")
  1284. enlightenment-package))
  1285. (service-extension setuid-program-service-type
  1286. enlightenment-setuid-programs)
  1287. (service-extension profile-service-type
  1288. (compose list
  1289. enlightenment-package))))
  1290. (default-value (enlightenment-desktop-configuration))
  1291. (description
  1292. "Return a service that adds the @code{enlightenment} package to the system
  1293. profile, and extends dbus with the ability for @code{efl} to generate
  1294. thumbnails and makes setuid the programs which enlightenment needs to function
  1295. as expected.")))
  1296. ;;;
  1297. ;;; inputattach-service-type
  1298. ;;;
  1299. (define-record-type* <inputattach-configuration>
  1300. inputattach-configuration
  1301. make-inputattach-configuration
  1302. inputattach-configuration?
  1303. (device-type inputattach-configuration-device-type
  1304. (default "wacom"))
  1305. (device inputattach-configuration-device
  1306. (default "/dev/ttyS0"))
  1307. (baud-rate inputattach-configuration-baud-rate
  1308. (default #f))
  1309. (log-file inputattach-configuration-log-file
  1310. (default #f)))
  1311. (define inputattach-shepherd-service
  1312. (match-lambda
  1313. (($ <inputattach-configuration> type device baud-rate log-file)
  1314. (let ((args (append (if baud-rate
  1315. (list "--baud" (number->string baud-rate))
  1316. '())
  1317. (list (string-append "--" type)
  1318. device))))
  1319. (list (shepherd-service
  1320. (provision '(inputattach))
  1321. (requirement '(udev))
  1322. (documentation "inputattach daemon")
  1323. (start #~(make-forkexec-constructor
  1324. (cons (string-append #$inputattach
  1325. "/bin/inputattach")
  1326. (quote #$args))
  1327. #:log-file #$log-file))
  1328. (stop #~(make-kill-destructor))))))))
  1329. (define inputattach-service-type
  1330. (service-type
  1331. (name 'inputattach)
  1332. (extensions
  1333. (list (service-extension shepherd-root-service-type
  1334. inputattach-shepherd-service)))
  1335. (default-value (inputattach-configuration))
  1336. (description "Return a service that runs inputattach on a device and
  1337. dispatches events from it.")))
  1338. ;;;
  1339. ;;; gnome-keyring-service-type
  1340. ;;;
  1341. (define-record-type* <gnome-keyring-configuration> gnome-keyring-configuration
  1342. make-gnome-keyring-configuration
  1343. gnome-keyring-configuration?
  1344. (keyring gnome-keyring-package (default gnome-keyring))
  1345. (pam-services gnome-keyring-pam-services (default '(("gdm-password" . login)
  1346. ("passwd" . passwd)))))
  1347. (define (pam-gnome-keyring config)
  1348. (define (%pam-keyring-entry . arguments)
  1349. (pam-entry
  1350. (control "optional")
  1351. (module (file-append (gnome-keyring-package config)
  1352. "/lib/security/pam_gnome_keyring.so"))
  1353. (arguments arguments)))
  1354. (list
  1355. (lambda (service)
  1356. (case (assoc-ref (gnome-keyring-pam-services config)
  1357. (pam-service-name service))
  1358. ((login)
  1359. (pam-service
  1360. (inherit service)
  1361. (auth (append (pam-service-auth service)
  1362. (list (%pam-keyring-entry))))
  1363. (session (append (pam-service-session service)
  1364. (list (%pam-keyring-entry "auto_start"))))))
  1365. ((passwd)
  1366. (pam-service
  1367. (inherit service)
  1368. (password (append (pam-service-password service)
  1369. (list (%pam-keyring-entry))))))
  1370. (else service)))))
  1371. (define gnome-keyring-service-type
  1372. (service-type
  1373. (name 'gnome-keyring)
  1374. (extensions (list
  1375. (service-extension pam-root-service-type pam-gnome-keyring)))
  1376. (default-value (gnome-keyring-configuration))
  1377. (description "Return a service, that adds the @code{gnome-keyring} package
  1378. to the system profile and extends PAM with entries using
  1379. @code{pam_gnome_keyring.so}, unlocking a user's login keyring when they log in
  1380. or setting its password with passwd.")))
  1381. ;;;
  1382. ;;; polkit-wheel-service -- Allow wheel group to perform admin actions
  1383. ;;;
  1384. (define polkit-wheel
  1385. (file-union
  1386. "polkit-wheel"
  1387. `(("share/polkit-1/rules.d/wheel.rules"
  1388. ,(plain-file
  1389. "wheel.rules"
  1390. "polkit.addAdminRule(function(action, subject) {
  1391. return [\"unix-group:wheel\"];
  1392. });
  1393. ")))))
  1394. (define polkit-wheel-service
  1395. (simple-service 'polkit-wheel polkit-service-type (list polkit-wheel)))
  1396. ;;;
  1397. ;;; The default set of desktop services.
  1398. ;;;
  1399. (define* (desktop-services-for-system #:optional
  1400. (system (or (%current-target-system)
  1401. (%current-system))))
  1402. ;; List of services typically useful for a "desktop" use case.
  1403. ;; Since GDM depends on Rust (gdm -> gnome-shell -> gjs -> mozjs -> rust)
  1404. ;; and Rust is currently unavailable on non-x86_64 platforms, default to
  1405. ;; SDDM there (FIXME).
  1406. (cons* (if (string-prefix? "x86_64" system)
  1407. (service gdm-service-type)
  1408. (service sddm-service-type))
  1409. ;; Screen lockers are a pretty useful thing and these are small.
  1410. (screen-locker-service slock)
  1411. (screen-locker-service xlockmore "xlock")
  1412. ;; Add udev rules for MTP devices so that non-root users can access
  1413. ;; them.
  1414. (simple-service 'mtp udev-service-type (list libmtp))
  1415. ;; Add udev rules for scanners.
  1416. (service sane-service-type)
  1417. ;; Add polkit rules, so that non-root users in the wheel group can
  1418. ;; perform administrative tasks (similar to "sudo").
  1419. polkit-wheel-service
  1420. ;; Allow desktop users to also mount NTFS and NFS file systems
  1421. ;; without root.
  1422. (simple-service 'mount-setuid-helpers setuid-program-service-type
  1423. (map (lambda (program)
  1424. (setuid-program
  1425. (program program)))
  1426. (list (file-append nfs-utils "/sbin/mount.nfs")
  1427. (file-append ntfs-3g "/sbin/mount.ntfs-3g"))))
  1428. ;; The global fontconfig cache directory can sometimes contain
  1429. ;; stale entries, possibly referencing fonts that have been GC'd,
  1430. ;; so mount it read-only.
  1431. fontconfig-file-system-service
  1432. ;; NetworkManager and its applet.
  1433. (service network-manager-service-type)
  1434. (service wpa-supplicant-service-type) ;needed by NetworkManager
  1435. (simple-service 'network-manager-applet
  1436. profile-service-type
  1437. (list network-manager-applet))
  1438. (service modem-manager-service-type)
  1439. (service usb-modeswitch-service-type)
  1440. ;; The D-Bus clique.
  1441. (service avahi-service-type)
  1442. (udisks-service)
  1443. (service upower-service-type)
  1444. (accountsservice-service)
  1445. (service cups-pk-helper-service-type)
  1446. (service colord-service-type)
  1447. (geoclue-service)
  1448. (service polkit-service-type)
  1449. (elogind-service)
  1450. (dbus-service)
  1451. (service ntp-service-type)
  1452. x11-socket-directory-service
  1453. (service pulseaudio-service-type)
  1454. (service alsa-service-type)
  1455. %base-services))
  1456. (define-syntax %desktop-services
  1457. (identifier-syntax (desktop-services-for-system)))
  1458. ;;; desktop.scm ends here