system.scm 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
  3. ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
  4. ;;; Copyright © 2015, 2016 Alex Kost <alezost@gmail.com>
  5. ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com>
  6. ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
  7. ;;;
  8. ;;; This file is part of GNU Guix.
  9. ;;;
  10. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  11. ;;; under the terms of the GNU General Public License as published by
  12. ;;; the Free Software Foundation; either version 3 of the License, or (at
  13. ;;; your option) any later version.
  14. ;;;
  15. ;;; GNU Guix is distributed in the hope that it will be useful, but
  16. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. ;;; GNU General Public License for more details.
  19. ;;;
  20. ;;; You should have received a copy of the GNU General Public License
  21. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  22. (define-module (gnu system)
  23. #:use-module (guix store)
  24. #:use-module (guix monads)
  25. #:use-module (guix gexp)
  26. #:use-module (guix records)
  27. #:use-module (guix packages)
  28. #:use-module (guix derivations)
  29. #:use-module (guix profiles)
  30. #:use-module (guix ui)
  31. #:use-module (gnu packages base)
  32. #:use-module (gnu packages bash)
  33. #:use-module (gnu packages guile)
  34. #:use-module (gnu packages admin)
  35. #:use-module (gnu packages linux)
  36. #:use-module (gnu packages pciutils)
  37. #:use-module (gnu packages package-management)
  38. #:use-module (gnu packages less)
  39. #:use-module (gnu packages zile)
  40. #:use-module (gnu packages nano)
  41. #:use-module (gnu packages gawk)
  42. #:use-module (gnu packages man)
  43. #:use-module (gnu packages texinfo)
  44. #:use-module (gnu packages compression)
  45. #:use-module (gnu packages firmware)
  46. #:use-module (gnu services)
  47. #:use-module (gnu services shepherd)
  48. #:use-module (gnu services base)
  49. #:use-module (gnu bootloader)
  50. #:use-module (gnu system shadow)
  51. #:use-module (gnu system nss)
  52. #:use-module (gnu system locale)
  53. #:use-module (gnu system pam)
  54. #:use-module (gnu system linux-initrd)
  55. #:use-module (gnu system uuid)
  56. #:use-module (gnu system file-systems)
  57. #:use-module (gnu system mapped-devices)
  58. #:use-module (ice-9 match)
  59. #:use-module (srfi srfi-1)
  60. #:use-module (srfi srfi-26)
  61. #:use-module (srfi srfi-34)
  62. #:use-module (srfi srfi-35)
  63. #:use-module (rnrs bytevectors)
  64. #:export (operating-system
  65. operating-system?
  66. operating-system-bootloader
  67. operating-system-services
  68. operating-system-user-services
  69. operating-system-packages
  70. operating-system-host-name
  71. operating-system-hosts-file
  72. operating-system-kernel
  73. operating-system-kernel-file
  74. operating-system-kernel-arguments
  75. operating-system-initrd
  76. operating-system-users
  77. operating-system-groups
  78. operating-system-issue
  79. operating-system-timezone
  80. operating-system-locale
  81. operating-system-locale-definitions
  82. operating-system-locale-libcs
  83. operating-system-mapped-devices
  84. operating-system-file-systems
  85. operating-system-store-file-system
  86. operating-system-user-mapped-devices
  87. operating-system-boot-mapped-devices
  88. operating-system-activation-script
  89. operating-system-user-accounts
  90. operating-system-shepherd-service-names
  91. operating-system-derivation
  92. operating-system-profile
  93. operating-system-bootcfg
  94. operating-system-etc-directory
  95. operating-system-locale-directory
  96. operating-system-boot-script
  97. system-linux-image-file-name
  98. boot-parameters
  99. boot-parameters?
  100. boot-parameters-label
  101. boot-parameters-root-device
  102. boot-parameters-bootloader-name
  103. boot-parameters-store-device
  104. boot-parameters-store-mount-point
  105. boot-parameters-kernel
  106. boot-parameters-kernel-arguments
  107. boot-parameters-initrd
  108. read-boot-parameters
  109. read-boot-parameters-file
  110. boot-parameters->menu-entry
  111. local-host-aliases
  112. %setuid-programs
  113. %base-packages
  114. %base-firmware))
  115. ;;; Commentary:
  116. ;;;
  117. ;;; This module supports whole-system configuration.
  118. ;;;
  119. ;;; Code:
  120. (define (bootable-kernel-arguments kernel-arguments system.drv root-device)
  121. "Prepend extra arguments to KERNEL-ARGUMENTS that allow SYSTEM.DRV to be
  122. booted from ROOT-DEVICE"
  123. (cons* (string-append "--root="
  124. (if (uuid? root-device)
  125. ;; Note: Always use the DCE format because that's
  126. ;; what (gnu build linux-boot) expects for the
  127. ;; '--root' kernel command-line option.
  128. (uuid->string (uuid-bytevector root-device) 'dce)
  129. root-device))
  130. #~(string-append "--system=" #$system.drv)
  131. #~(string-append "--load=" #$system.drv "/boot")
  132. kernel-arguments))
  133. ;; System-wide configuration.
  134. ;; TODO: Add per-field docstrings/stexi.
  135. (define-record-type* <operating-system> operating-system
  136. make-operating-system
  137. operating-system?
  138. (kernel operating-system-kernel ; package
  139. (default linux-libre))
  140. (kernel-arguments operating-system-user-kernel-arguments
  141. (default '())) ; list of gexps/strings
  142. (bootloader operating-system-bootloader) ; <bootloader-configuration>
  143. (initrd operating-system-initrd ; (list fs) -> M derivation
  144. (default base-initrd))
  145. (firmware operating-system-firmware ; list of packages
  146. (default %base-firmware))
  147. (host-name operating-system-host-name) ; string
  148. (hosts-file operating-system-hosts-file ; file-like | #f
  149. (default #f))
  150. (mapped-devices operating-system-mapped-devices ; list of <mapped-device>
  151. (default '()))
  152. (file-systems operating-system-file-systems) ; list of fs
  153. (swap-devices operating-system-swap-devices ; list of strings
  154. (default '()))
  155. (users operating-system-users ; list of user accounts
  156. (default %base-user-accounts))
  157. (groups operating-system-groups ; list of user groups
  158. (default %base-groups))
  159. (skeletons operating-system-skeletons ; list of name/monadic value
  160. (default (default-skeletons)))
  161. (issue operating-system-issue ; string
  162. (default %default-issue))
  163. (packages operating-system-packages ; list of (PACKAGE OUTPUT...)
  164. (default %base-packages)) ; or just PACKAGE
  165. (timezone operating-system-timezone) ; string
  166. (locale operating-system-locale ; string
  167. (default "en_US.utf8"))
  168. (locale-definitions operating-system-locale-definitions ; list of <locale-definition>
  169. (default %default-locale-definitions))
  170. (locale-libcs operating-system-locale-libcs ; list of <packages>
  171. (default %default-locale-libcs))
  172. (name-service-switch operating-system-name-service-switch ; <name-service-switch>
  173. (default %default-nss))
  174. (services operating-system-user-services ; list of monadic services
  175. (default %base-services))
  176. (pam-services operating-system-pam-services ; list of PAM services
  177. (default (base-pam-services)))
  178. (setuid-programs operating-system-setuid-programs
  179. (default %setuid-programs)) ; list of string-valued gexps
  180. (sudoers-file operating-system-sudoers-file ; file-like
  181. (default %sudoers-specification)))
  182. (define (operating-system-kernel-arguments os system.drv root-device)
  183. "Return all the kernel arguments, including the ones not specified
  184. directly by the user."
  185. (bootable-kernel-arguments (operating-system-user-kernel-arguments os)
  186. system.drv
  187. root-device))
  188. ;;;
  189. ;;; Boot parameters
  190. ;;;
  191. (define-record-type* <boot-parameters>
  192. boot-parameters make-boot-parameters boot-parameters?
  193. (label boot-parameters-label)
  194. ;; Because we will use the 'store-device' to create the GRUB search command,
  195. ;; the 'store-device' has slightly different semantics than 'root-device'.
  196. ;; The 'store-device' can be a file system uuid, a file system label, or #f,
  197. ;; but it cannot be a device path such as "/dev/sda3", since GRUB would not
  198. ;; understand that. The 'root-device', on the other hand, corresponds
  199. ;; exactly to the device field of the <file-system> object representing the
  200. ;; OS's root file system, so it might be a device path like "/dev/sda3".
  201. (root-device boot-parameters-root-device)
  202. (bootloader-name boot-parameters-bootloader-name)
  203. (store-device boot-parameters-store-device)
  204. (store-mount-point boot-parameters-store-mount-point)
  205. (kernel boot-parameters-kernel)
  206. (kernel-arguments boot-parameters-kernel-arguments)
  207. (initrd boot-parameters-initrd))
  208. (define (ensure-not-/dev device)
  209. "If DEVICE starts with a slash, return #f. This is meant to filter out
  210. Linux device names such as /dev/sda, and to preserve GRUB device names and
  211. file system labels."
  212. (if (and (string? device) (string-prefix? "/" device))
  213. #f
  214. device))
  215. (define (read-boot-parameters port)
  216. "Read boot parameters from PORT and return the corresponding
  217. <boot-parameters> object or #f if the format is unrecognized."
  218. (define device-sexp->device
  219. (match-lambda
  220. (('uuid (? symbol? type) (? bytevector? bv))
  221. (bytevector->uuid bv type))
  222. ((? bytevector? bv) ;old format
  223. (bytevector->uuid bv 'dce))
  224. ((? string? device)
  225. device)))
  226. (match (read port)
  227. (('boot-parameters ('version 0)
  228. ('label label) ('root-device root)
  229. ('kernel linux)
  230. rest ...)
  231. (boot-parameters
  232. (label label)
  233. (root-device (device-sexp->device root))
  234. (bootloader-name
  235. (match (assq 'bootloader-name rest)
  236. ((_ args) args)
  237. (#f 'grub))) ; for compatibility reasons.
  238. ;; In the past, we would store the directory name of the kernel instead
  239. ;; of the absolute file name of its image. Detect that and correct it.
  240. (kernel (if (string=? linux (direct-store-path linux))
  241. (string-append linux "/"
  242. (system-linux-image-file-name))
  243. linux))
  244. (kernel-arguments
  245. (match (assq 'kernel-arguments rest)
  246. ((_ args) args)
  247. (#f '()))) ;the old format
  248. (initrd
  249. (match (assq 'initrd rest)
  250. (('initrd ('string-append directory file)) ;the old format
  251. (string-append directory file))
  252. (('initrd (? string? file))
  253. file)))
  254. (store-device
  255. ;; Linux device names like "/dev/sda1" are not suitable GRUB device
  256. ;; identifiers, so we just filter them out.
  257. (ensure-not-/dev
  258. (match (assq 'store rest)
  259. (('store ('device #f) _ ...)
  260. root-device)
  261. (('store ('device device) _ ...)
  262. (device-sexp->device device))
  263. (_ ;the old format
  264. root-device))))
  265. (store-mount-point
  266. (match (assq 'store rest)
  267. (('store ('device _) ('mount-point mount-point) _ ...)
  268. mount-point)
  269. (_ ;the old format
  270. "/")))))
  271. (x ;unsupported format
  272. (warning (G_ "unrecognized boot parameters for '~a'~%")
  273. system)
  274. #f)))
  275. (define (read-boot-parameters-file system)
  276. "Read boot parameters from SYSTEM's (system or generation) \"parameters\"
  277. file and returns the corresponding <boot-parameters> object or #f if the
  278. format is unrecognized.
  279. The object has its kernel-arguments extended in order to make it bootable."
  280. (let* ((file (string-append system "/parameters"))
  281. (params (call-with-input-file file read-boot-parameters))
  282. (root (boot-parameters-root-device params))
  283. (kernel-arguments (boot-parameters-kernel-arguments params)))
  284. (if params
  285. (boot-parameters
  286. (inherit params)
  287. (kernel-arguments (bootable-kernel-arguments kernel-arguments
  288. system root)))
  289. #f)))
  290. (define (boot-parameters->menu-entry conf)
  291. (menu-entry
  292. (label (boot-parameters-label conf))
  293. (device (boot-parameters-store-device conf))
  294. (device-mount-point (boot-parameters-store-mount-point conf))
  295. (linux (boot-parameters-kernel conf))
  296. (linux-arguments (boot-parameters-kernel-arguments conf))
  297. (initrd (boot-parameters-initrd conf))))
  298. ;;;
  299. ;;; Services.
  300. ;;;
  301. (define (non-boot-file-system-service os)
  302. "Return the file system service for the file systems of OS that are not
  303. marked as 'needed-for-boot'."
  304. (define file-systems
  305. (remove file-system-needed-for-boot?
  306. (operating-system-file-systems os)))
  307. (define (device-mappings fs)
  308. (let ((device (file-system-device fs)))
  309. (if (string? device) ;title is 'device
  310. (filter (lambda (md)
  311. (string=? (string-append "/dev/mapper/"
  312. (mapped-device-target md))
  313. device))
  314. (operating-system-mapped-devices os))
  315. '())))
  316. (define (add-dependencies fs)
  317. ;; Add the dependencies due to device mappings to FS.
  318. (file-system
  319. (inherit fs)
  320. (dependencies
  321. (delete-duplicates (append (device-mappings fs)
  322. (file-system-dependencies fs))
  323. eq?))))
  324. (service file-system-service-type
  325. (map add-dependencies file-systems)))
  326. (define (mapped-device-user device file-systems)
  327. "Return a file system among FILE-SYSTEMS that uses DEVICE, or #f."
  328. (let ((target (string-append "/dev/mapper/" (mapped-device-target device))))
  329. (find (lambda (fs)
  330. (or (member device (file-system-dependencies fs))
  331. (and (eq? 'device (file-system-title fs))
  332. (string=? (file-system-device fs) target))))
  333. file-systems)))
  334. (define (operating-system-user-mapped-devices os)
  335. "Return the subset of mapped devices that can be installed in
  336. user-land--i.e., those not needed during boot."
  337. (let ((devices (operating-system-mapped-devices os))
  338. (file-systems (operating-system-file-systems os)))
  339. (filter (lambda (md)
  340. (let ((user (mapped-device-user md file-systems)))
  341. (or (not user)
  342. (not (file-system-needed-for-boot? user)))))
  343. devices)))
  344. (define (operating-system-boot-mapped-devices os)
  345. "Return the subset of mapped devices that must be installed during boot,
  346. from the initrd."
  347. (let ((devices (operating-system-mapped-devices os))
  348. (file-systems (operating-system-file-systems os)))
  349. (filter (lambda (md)
  350. (let ((user (mapped-device-user md file-systems)))
  351. (and user (file-system-needed-for-boot? user))))
  352. devices)))
  353. (define (device-mapping-services os)
  354. "Return the list of device-mapping services for OS as a list."
  355. (map device-mapping-service
  356. (operating-system-user-mapped-devices os)))
  357. (define (swap-services os)
  358. "Return the list of swap services for OS."
  359. (map swap-service (operating-system-swap-devices os)))
  360. (define* (system-linux-image-file-name #:optional (system (%current-system)))
  361. "Return the basename of the kernel image file for SYSTEM."
  362. ;; FIXME: Evaluate the conditional based on the actual current system.
  363. (cond
  364. ((string-prefix? "arm" (%current-system)) "zImage")
  365. ((string-prefix? "mips" (%current-system)) "vmlinuz")
  366. ((string-prefix? "aarch64" (%current-system)) "Image")
  367. (else "bzImage")))
  368. (define (operating-system-kernel-file os)
  369. "Return an object representing the absolute file name of the kernel image of
  370. OS."
  371. (file-append (operating-system-kernel os)
  372. "/" (system-linux-image-file-name os)))
  373. (define* (operating-system-directory-base-entries os #:key container?)
  374. "Return the basic entries of the 'system' directory of OS for use as the
  375. value of the SYSTEM-SERVICE-TYPE service."
  376. (let ((locale (operating-system-locale-directory os)))
  377. (with-monad %store-monad
  378. (if container?
  379. (return `(("locale" ,locale)))
  380. (mlet %store-monad
  381. ((kernel -> (operating-system-kernel os))
  382. (initrd (operating-system-initrd-file os))
  383. (params (operating-system-boot-parameters-file os)))
  384. (return `(("kernel" ,kernel)
  385. ("parameters" ,params)
  386. ("initrd" ,initrd)
  387. ("locale" ,locale)))))))) ;used by libc
  388. (define* (essential-services os #:key container?)
  389. "Return the list of essential services for OS. These are special services
  390. that implement part of what's declared in OS are responsible for low-level
  391. bookkeeping. CONTAINER? determines whether to return the list of services for
  392. a container or that of a \"bare metal\" system."
  393. (define known-fs
  394. (map file-system-mount-point (operating-system-file-systems os)))
  395. (let* ((mappings (device-mapping-services os))
  396. (root-fs (root-file-system-service))
  397. (other-fs (non-boot-file-system-service os))
  398. (unmount (user-unmount-service known-fs))
  399. (swaps (swap-services os))
  400. (procs (service user-processes-service-type))
  401. (host-name (host-name-service (operating-system-host-name os)))
  402. (entries (operating-system-directory-base-entries
  403. os #:container? container?)))
  404. (cons* (service system-service-type entries)
  405. %boot-service
  406. ;; %SHEPHERD-ROOT-SERVICE must come first so that the gexp that
  407. ;; execs shepherd comes last in the boot script (XXX). Likewise,
  408. ;; the cleanup service must come last so that its gexp runs before
  409. ;; activation code.
  410. %shepherd-root-service
  411. %activation-service
  412. (service cleanup-service-type #f)
  413. (pam-root-service (operating-system-pam-services os))
  414. (account-service (append (operating-system-accounts os)
  415. (operating-system-groups os))
  416. (operating-system-skeletons os))
  417. (operating-system-etc-service os)
  418. (service fstab-service-type '())
  419. (session-environment-service
  420. (operating-system-environment-variables os))
  421. host-name procs root-fs unmount
  422. (service setuid-program-service-type
  423. (operating-system-setuid-programs os))
  424. (service profile-service-type
  425. (operating-system-packages os))
  426. other-fs
  427. (append mappings swaps
  428. ;; Add the firmware service, unless we are building for a
  429. ;; container.
  430. (if container?
  431. '()
  432. (list %linux-bare-metal-service
  433. (service firmware-service-type
  434. (operating-system-firmware os))))))))
  435. (define* (operating-system-services os #:key container?)
  436. "Return all the services of OS, including \"internal\" services that do not
  437. explicitly appear in OS."
  438. (append (operating-system-user-services os)
  439. (essential-services os #:container? container?)))
  440. ;;;
  441. ;;; /etc.
  442. ;;;
  443. (define %base-firmware
  444. ;; Firmware usable by default.
  445. (list ath9k-htc-firmware
  446. openfwwf-firmware))
  447. (define %base-packages
  448. ;; Default set of packages globally visible. It should include anything
  449. ;; required for basic administrator tasks.
  450. (cons* procps psmisc which less zile nano
  451. pciutils usbutils
  452. util-linux inetutils isc-dhcp
  453. (@ (gnu packages admin) shadow) ;for 'passwd'
  454. ;; wireless-tools is deprecated in favor of iw, but it's still what
  455. ;; many people are familiar with, so keep it around.
  456. iw wireless-tools rfkill
  457. iproute
  458. net-tools ; XXX: remove when Inetutils suffices
  459. man-db
  460. info-reader ;the standalone Info reader (no Perl)
  461. ;; The 'sudo' command is already in %SETUID-PROGRAMS, but we also
  462. ;; want the other commands and the man pages (notably because
  463. ;; auto-completion in Emacs shell relies on man pages.)
  464. sudo
  465. ;; Get 'insmod' & co. from kmod, not module-init-tools, since udev
  466. ;; already depends on it anyway.
  467. kmod eudev
  468. e2fsprogs kbd
  469. bash-completion
  470. ;; XXX: We don't use (canonical-package guile-2.2) here because that
  471. ;; would create a collision in the global profile between the GMP
  472. ;; variant propagated by 'guile-final' and the GMP variant propagated
  473. ;; by 'gnutls', itself propagated by 'guix'.
  474. guile-2.2
  475. ;; The packages below are also in %FINAL-INPUTS, so take them from
  476. ;; there to avoid duplication.
  477. (map canonical-package
  478. (list bash coreutils findutils grep sed
  479. diffutils patch gawk tar gzip bzip2 xz lzip))))
  480. (define %default-issue
  481. ;; Default contents for /etc/issue.
  482. "
  483. This is the GNU system. Welcome.\n")
  484. (define (local-host-aliases host-name)
  485. "Return aliases for HOST-NAME, to be used in /etc/hosts."
  486. (string-append "127.0.0.1 localhost " host-name "\n"
  487. "::1 localhost " host-name "\n"))
  488. (define (default-/etc/hosts host-name)
  489. "Return the default /etc/hosts file."
  490. (plain-file "hosts" (local-host-aliases host-name)))
  491. (define* (operating-system-etc-service os)
  492. "Return a <service> that builds containing the static part of the /etc
  493. directory."
  494. (let ((login.defs (plain-file "login.defs" "# Empty for now.\n"))
  495. (issue (plain-file "issue" (operating-system-issue os)))
  496. (nsswitch (plain-file "nsswitch.conf"
  497. (name-service-switch->string
  498. (operating-system-name-service-switch os))))
  499. ;; Startup file for POSIX-compliant login shells, which set system-wide
  500. ;; environment variables.
  501. (profile (mixed-text-file "profile" "\
  502. # Crucial variables that could be missing in the profiles' 'etc/profile'
  503. # because they would require combining both profiles.
  504. # FIXME: See <http://bugs.gnu.org/20255>.
  505. export MANPATH=$HOME/.guix-profile/share/man:/run/current-system/profile/share/man
  506. export INFOPATH=$HOME/.guix-profile/share/info:/run/current-system/profile/share/info
  507. export XDG_DATA_DIRS=$HOME/.guix-profile/share:/run/current-system/profile/share
  508. export XDG_CONFIG_DIRS=$HOME/.guix-profile/etc/xdg:/run/current-system/profile/etc/xdg
  509. # Make sure libXcursor finds cursors installed into user or system profiles. See <http://bugs.gnu.org/24445>
  510. export XCURSOR_PATH=$HOME/.icons:$HOME/.guix-profile/share/icons:/run/current-system/profile/share/icons
  511. # Ignore the default value of 'PATH'.
  512. unset PATH
  513. # Load the system profile's settings.
  514. GUIX_PROFILE=/run/current-system/profile ; \\
  515. . /run/current-system/profile/etc/profile
  516. # Prepend setuid programs.
  517. export PATH=/run/setuid-programs:$PATH
  518. # Since 'lshd' does not use pam_env, /etc/environment must be explicitly
  519. # loaded when someone logs in via SSH. See <http://bugs.gnu.org/22175>.
  520. # We need 'PATH' to be defined here, for 'cat' and 'cut'. Do this before
  521. # reading the user's 'etc/profile' to allow variables to be overridden.
  522. if [ -f /etc/environment -a -n \"$SSH_CLIENT\" \\
  523. -a -z \"$LINUX_MODULE_DIRECTORY\" ]
  524. then
  525. . /etc/environment
  526. export `cat /etc/environment | cut -d= -f1`
  527. fi
  528. if [ -f \"$HOME/.guix-profile/etc/profile\" ]
  529. then
  530. # Load the user profile's settings.
  531. GUIX_PROFILE=\"$HOME/.guix-profile\" ; \\
  532. . \"$HOME/.guix-profile/etc/profile\"
  533. else
  534. # At least define this one so that basic things just work
  535. # when the user installs their first package.
  536. export PATH=\"$HOME/.guix-profile/bin:$PATH\"
  537. fi
  538. # Set the umask, notably for users logging in via 'lsh'.
  539. # See <http://bugs.gnu.org/22650>.
  540. umask 022
  541. # Allow Hunspell-based applications (IceCat, LibreOffice, etc.) to
  542. # find dictionaries.
  543. export DICPATH=\"$HOME/.guix-profile/share/hunspell:/run/current-system/profile/share/hunspell\"
  544. # Allow GStreamer-based applications to find plugins.
  545. export GST_PLUGIN_PATH=\"$HOME/.guix-profile/lib/gstreamer-1.0\"
  546. if [ -n \"$BASH_VERSION\" -a -f /etc/bashrc ]
  547. then
  548. # Load Bash-specific initialization code.
  549. . /etc/bashrc
  550. fi
  551. "))
  552. (bashrc (plain-file "bashrc" "\
  553. # Bash-specific initialization.
  554. # The 'bash-completion' package.
  555. if [ -f /run/current-system/profile/etc/profile.d/bash_completion.sh ]
  556. then
  557. # Bash-completion sources ~/.bash_completion. It installs a dynamic
  558. # completion loader that searches its own completion files as well
  559. # as those in ~/.guix-profile and /run/current-system/profile.
  560. source /run/current-system/profile/etc/profile.d/bash_completion.sh
  561. fi\n")))
  562. (etc-service
  563. `(("services" ,(file-append net-base "/etc/services"))
  564. ("protocols" ,(file-append net-base "/etc/protocols"))
  565. ("rpc" ,(file-append net-base "/etc/rpc"))
  566. ("login.defs" ,#~#$login.defs)
  567. ("issue" ,#~#$issue)
  568. ("nsswitch.conf" ,#~#$nsswitch)
  569. ("profile" ,#~#$profile)
  570. ("bashrc" ,#~#$bashrc)
  571. ("hosts" ,#~#$(or (operating-system-hosts-file os)
  572. (default-/etc/hosts (operating-system-host-name os))))
  573. ;; Write the operating-system-host-name to /etc/hostname to prevent
  574. ;; NetworkManager from changing the system's hostname when connecting
  575. ;; to certain networks. Some discussion at
  576. ;; https://lists.gnu.org/archive/html/help-guix/2017-09/msg00037.html
  577. ("hostname" ,(plain-file "hostname" (operating-system-host-name os)))
  578. ("localtime" ,(file-append tzdata "/share/zoneinfo/"
  579. (operating-system-timezone os)))
  580. ("sudoers" ,(operating-system-sudoers-file os))))))
  581. (define %root-account
  582. ;; Default root account.
  583. (user-account
  584. (name "root")
  585. (password "")
  586. (uid 0) (group "root")
  587. (comment "System administrator")
  588. (home-directory "/root")))
  589. (define (operating-system-accounts os)
  590. "Return the user accounts for OS, including an obligatory 'root' account,
  591. and excluding accounts requested by services."
  592. ;; Make sure there's a root account.
  593. (if (find (lambda (user)
  594. (and=> (user-account-uid user) zero?))
  595. (operating-system-users os))
  596. (operating-system-users os)
  597. (cons %root-account (operating-system-users os))))
  598. (define (maybe-string->file file-name thing)
  599. "If THING is a string, return a <plain-file> with THING as its content.
  600. Otherwise just return THING.
  601. This is for backward-compatibility of fields that used to be strings and are
  602. now file-like objects.."
  603. (match thing
  604. ((? string?)
  605. (warning (G_ "using a string for file '~a' is deprecated; \
  606. use 'plain-file' instead~%")
  607. file-name)
  608. (plain-file file-name thing))
  609. (x
  610. x)))
  611. (define (maybe-file->monadic file-name thing)
  612. "If THING is a value in %STORE-MONAD, return it as is; otherwise return
  613. THING in the %STORE-MONAD.
  614. This is for backward-compatibility of fields that used to be monadic values
  615. and are now file-like objects."
  616. (with-monad %store-monad
  617. (match thing
  618. ((? procedure?)
  619. (warning (G_ "using a monadic value for '~a' is deprecated; \
  620. use 'plain-file' instead~%")
  621. file-name)
  622. thing)
  623. (x
  624. (return x)))))
  625. (define (operating-system-etc-directory os)
  626. "Return that static part of the /etc directory of OS."
  627. (etc-directory
  628. (fold-services (operating-system-services os)
  629. #:target-type etc-service-type)))
  630. (define (operating-system-environment-variables os)
  631. "Return the environment variables of OS for
  632. @var{session-environment-service-type}, to be used in @file{/etc/environment}."
  633. `(("LANG" . ,(operating-system-locale os))
  634. ;; Note: No need to set 'TZ' since (1) we provide /etc/localtime, and (2)
  635. ;; it doesn't work for setuid binaries. See <https://bugs.gnu.org/29212>.
  636. ("TZDIR" . ,(file-append tzdata "/share/zoneinfo"))
  637. ;; Tell 'modprobe' & co. where to look for modules.
  638. ("LINUX_MODULE_DIRECTORY" . "/run/booted-system/kernel/lib/modules")
  639. ;; These variables are honored by OpenSSL (libssl) and Git.
  640. ("SSL_CERT_DIR" . "/etc/ssl/certs")
  641. ("SSL_CERT_FILE" . "/etc/ssl/certs/ca-certificates.crt")
  642. ("GIT_SSL_CAINFO" . "/etc/ssl/certs/ca-certificates.crt")
  643. ;; 'GTK_DATA_PREFIX' must name one directory where GTK+ themes are
  644. ;; searched for.
  645. ("GTK_DATA_PREFIX" . "/run/current-system/profile")
  646. ;; By default, applications that use D-Bus, such as Emacs, abort at startup
  647. ;; when /etc/machine-id is missing. Make sure these warnings are non-fatal.
  648. ("DBUS_FATAL_WARNINGS" . "0")
  649. ;; XXX: Normally we wouldn't need to do this, but our glibc@2.23 package
  650. ;; used to look things up in 'PREFIX/lib/locale' instead of
  651. ;; '/run/current-system/locale' as was intended. Keep this hack around so
  652. ;; that people who still have glibc@2.23-using packages in their profiles
  653. ;; can use them correctly.
  654. ;; TODO: Remove when glibc@2.23 is long gone.
  655. ("GUIX_LOCPATH" . "/run/current-system/locale")))
  656. (define %setuid-programs
  657. ;; Default set of setuid-root programs.
  658. (let ((shadow (@ (gnu packages admin) shadow)))
  659. (list (file-append shadow "/bin/passwd")
  660. (file-append shadow "/bin/su")
  661. (file-append shadow "/bin/newuidmap")
  662. (file-append shadow "/bin/newgidmap")
  663. (file-append inetutils "/bin/ping")
  664. (file-append inetutils "/bin/ping6")
  665. (file-append sudo "/bin/sudo")
  666. (file-append fuse "/bin/fusermount"))))
  667. (define %sudoers-specification
  668. ;; Default /etc/sudoers contents: 'root' and all members of the 'wheel'
  669. ;; group can do anything. See
  670. ;; <http://www.sudo.ws/sudo/man/1.8.10/sudoers.man.html>.
  671. ;; TODO: Add a declarative API.
  672. (plain-file "sudoers" "\
  673. root ALL=(ALL) ALL
  674. %wheel ALL=(ALL) ALL\n"))
  675. (define* (operating-system-activation-script os #:key container?)
  676. "Return the activation script for OS---i.e., the code that \"activates\" the
  677. stateful part of OS, including user accounts and groups, special directories,
  678. etc."
  679. (let* ((services (operating-system-services os #:container? container?))
  680. (activation (fold-services services
  681. #:target-type activation-service-type)))
  682. (activation-service->script activation)))
  683. (define* (operating-system-boot-script os #:key container?)
  684. "Return the boot script for OS---i.e., the code started by the initrd once
  685. we're running in the final root. When CONTAINER? is true, skip all
  686. hardware-related operations as necessary when booting a Linux container."
  687. (let* ((services (operating-system-services os #:container? container?))
  688. (boot (fold-services services #:target-type boot-service-type)))
  689. ;; BOOT is the script as a monadic value.
  690. (service-value boot)))
  691. (define (operating-system-user-accounts os)
  692. "Return the list of user accounts of OS."
  693. (let* ((services (operating-system-services os))
  694. (account (fold-services services
  695. #:target-type account-service-type)))
  696. (filter user-account?
  697. (service-value account))))
  698. (define (operating-system-shepherd-service-names os)
  699. "Return the list of Shepherd service names for OS."
  700. (append-map shepherd-service-provision
  701. (service-value
  702. (fold-services (operating-system-services os)
  703. #:target-type
  704. shepherd-root-service-type))))
  705. (define* (operating-system-derivation os #:key container?)
  706. "Return a derivation that builds OS."
  707. (let* ((services (operating-system-services os #:container? container?))
  708. (system (fold-services services)))
  709. ;; SYSTEM contains the derivation as a monadic value.
  710. (service-value system)))
  711. (define* (operating-system-profile os #:key container?)
  712. "Return a derivation that builds the system profile of OS."
  713. (mlet* %store-monad
  714. ((services -> (operating-system-services os #:container? container?))
  715. (profile (fold-services services
  716. #:target-type profile-service-type)))
  717. (match profile
  718. (("profile" profile)
  719. (return profile)))))
  720. (define (operating-system-root-file-system os)
  721. "Return the root file system of OS."
  722. (find (match-lambda
  723. (($ <file-system> device title "/") #t)
  724. (x #f))
  725. (operating-system-file-systems os)))
  726. (define (operating-system-initrd-file os)
  727. "Return a gexp denoting the initrd file of OS."
  728. (define boot-file-systems
  729. (filter file-system-needed-for-boot?
  730. (operating-system-file-systems os)))
  731. (define mapped-devices
  732. (operating-system-boot-mapped-devices os))
  733. (define make-initrd
  734. (operating-system-initrd os))
  735. (mlet %store-monad ((initrd (make-initrd boot-file-systems
  736. #:linux (operating-system-kernel os)
  737. #:mapped-devices mapped-devices)))
  738. (return (file-append initrd "/initrd"))))
  739. (define (locale-name->definition* name)
  740. "Variant of 'locale-name->definition' that raises an error upon failure."
  741. (match (locale-name->definition name)
  742. (#f
  743. (raise (condition
  744. (&message
  745. (message (format #f (G_ "~a: invalid locale name") name))))))
  746. (def def)))
  747. (define (operating-system-locale-directory os)
  748. "Return the directory containing the locales compiled for the definitions
  749. listed in OS. The C library expects to find it under
  750. /run/current-system/locale."
  751. (define name
  752. (operating-system-locale os))
  753. (define definitions
  754. ;; While we're at it, check whether NAME is defined and add it if needed.
  755. (if (member name (map locale-definition-name
  756. (operating-system-locale-definitions os)))
  757. (operating-system-locale-definitions os)
  758. (cons (locale-name->definition* name)
  759. (operating-system-locale-definitions os))))
  760. (locale-directory definitions
  761. #:libcs (operating-system-locale-libcs os)))
  762. (define (kernel->boot-label kernel)
  763. "Return a label for the bootloader menu entry that boots KERNEL."
  764. (string-append "GNU with "
  765. (string-titlecase (package-name kernel)) " "
  766. (package-version kernel)
  767. " (beta)"))
  768. (define (store-file-system file-systems)
  769. "Return the file system object among FILE-SYSTEMS that contains the store."
  770. (match (filter (lambda (fs)
  771. (and (file-system-mount? fs)
  772. (not (memq 'bind-mount (file-system-flags fs)))
  773. (string-prefix? (file-system-mount-point fs)
  774. (%store-prefix))))
  775. file-systems)
  776. ((and candidates (head . tail))
  777. (reduce (lambda (fs1 fs2)
  778. (if (> (string-length (file-system-mount-point fs1))
  779. (string-length (file-system-mount-point fs2)))
  780. fs1
  781. fs2))
  782. head
  783. candidates))))
  784. (define (operating-system-store-file-system os)
  785. "Return the file system that contains the store of OS."
  786. (store-file-system (operating-system-file-systems os)))
  787. (define* (operating-system-bootcfg os #:optional (old-entries '()))
  788. "Return the bootloader configuration file for OS. Use OLD-ENTRIES
  789. (which is a list of <menu-entry>) to populate the \"old entries\" menu."
  790. (mlet* %store-monad
  791. ((system (operating-system-derivation os))
  792. (root-fs -> (operating-system-root-file-system os))
  793. (root-device -> (file-system-device root-fs))
  794. (params (operating-system-boot-parameters os system root-device))
  795. (entry -> (boot-parameters->menu-entry params))
  796. (bootloader-conf -> (operating-system-bootloader os)))
  797. ((bootloader-configuration-file-generator
  798. (bootloader-configuration-bootloader bootloader-conf))
  799. bootloader-conf (list entry) #:old-entries old-entries)))
  800. (define (fs->boot-device fs)
  801. "Given FS, a <file-system> object, return a value suitable for use as the
  802. device in a <menu-entry>."
  803. (case (file-system-title fs)
  804. ((uuid label device) (file-system-device fs))
  805. (else #f)))
  806. (define (operating-system-boot-parameters os system.drv root-device)
  807. "Return a monadic <boot-parameters> record that describes the boot parameters
  808. of OS. SYSTEM.DRV is either a derivation or #f. If it's a derivation, adds
  809. kernel arguments for that derivation to <boot-parameters>."
  810. (mlet* %store-monad
  811. ((initrd (operating-system-initrd-file os))
  812. (store -> (operating-system-store-file-system os))
  813. (bootloader -> (bootloader-configuration-bootloader
  814. (operating-system-bootloader os)))
  815. (bootloader-name -> (bootloader-name bootloader))
  816. (label -> (kernel->boot-label (operating-system-kernel os))))
  817. (return (boot-parameters
  818. (label label)
  819. (root-device root-device)
  820. (kernel (operating-system-kernel-file os))
  821. (kernel-arguments
  822. (if system.drv
  823. (operating-system-kernel-arguments os system.drv root-device)
  824. (operating-system-user-kernel-arguments os)))
  825. (initrd initrd)
  826. (bootloader-name bootloader-name)
  827. (store-device (ensure-not-/dev (fs->boot-device store)))
  828. (store-mount-point (file-system-mount-point store))))))
  829. (define (device->sexp device)
  830. "Serialize DEVICE as an sexp (really, as an object with a read syntax.)"
  831. (match device
  832. ((? uuid? uuid)
  833. `(uuid ,(uuid-type uuid) ,(uuid-bytevector uuid)))
  834. (_
  835. device)))
  836. (define* (operating-system-boot-parameters-file os #:optional (system.drv #f))
  837. "Return a file that describes the boot parameters of OS. The primary use of
  838. this file is the reconstruction of GRUB menu entries for old configurations.
  839. SYSTEM.DRV is optional. If given, adds kernel arguments for that system to the
  840. returned file (since the returned file is then usually stored into the
  841. content-addressed \"system\" directory, it's usually not a good idea
  842. to give it because the content hash would change by the content hash
  843. being stored into the \"parameters\" file)."
  844. (mlet* %store-monad ((root -> (operating-system-root-file-system os))
  845. (device -> (file-system-device root))
  846. (params (operating-system-boot-parameters os
  847. system.drv
  848. device)))
  849. (gexp->file "parameters"
  850. #~(boot-parameters
  851. (version 0)
  852. (label #$(boot-parameters-label params))
  853. (root-device
  854. #$(device->sexp
  855. (boot-parameters-root-device params)))
  856. (kernel #$(boot-parameters-kernel params))
  857. (kernel-arguments
  858. #$(boot-parameters-kernel-arguments params))
  859. (initrd #$(boot-parameters-initrd params))
  860. (bootloader-name #$(boot-parameters-bootloader-name params))
  861. (store
  862. (device
  863. #$(device->sexp (boot-parameters-store-device params)))
  864. (mount-point #$(boot-parameters-store-mount-point params))))
  865. #:set-load-path? #f)))
  866. (define-gexp-compiler (operating-system-compiler (os <operating-system>)
  867. system target)
  868. ((store-lift
  869. (lambda (store)
  870. ;; XXX: This is not super elegant but we can't pass SYSTEM and TARGET to
  871. ;; 'operating-system-derivation'.
  872. (run-with-store store (operating-system-derivation os)
  873. #:system system
  874. #:target target)))))
  875. ;;; system.scm ends here