offload: Have 'build-machines' honor its argument.
[jackhill/guix/guix.git] / gnu / system.scm
CommitLineData
033adfe7 1;;; GNU Guix --- Functional package management for GNU
735c6dd7 2;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org>
033adfe7
LC
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (gnu system)
20 #:use-module (guix store)
21 #:use-module (guix monads)
22 #:use-module (guix records)
23 #:use-module (guix packages)
24 #:use-module (guix derivations)
033adfe7
LC
25 #:use-module (gnu packages base)
26 #:use-module (gnu packages bash)
9de46ffb 27 #:use-module (gnu packages admin)
033adfe7
LC
28 #:use-module (gnu packages package-management)
29 #:use-module (gnu system dmd)
30 #:use-module (gnu system grub)
31 #:use-module (gnu system shadow)
32 #:use-module (gnu system linux)
735c6dd7 33 #:use-module (gnu system linux-initrd)
033adfe7
LC
34 #:use-module (ice-9 match)
35 #:use-module (srfi srfi-1)
36 #:use-module (srfi srfi-26)
37 #:export (operating-system
38 operating-system?
39 operating-system-services
40 operating-system-packages
fd3bfc44
LC
41 operating-system-bootloader-entries
42 operating-system-host-name
43 operating-system-kernel
44 operating-system-initrd
45 operating-system-users
46 operating-system-groups
47 operating-system-packages
48 operating-system-timezone
49 operating-system-locale
50 operating-system-services
033adfe7
LC
51
52 operating-system-derivation))
53
54;;; Commentary:
55;;;
56;;; This module supports whole-system configuration.
57;;;
58;;; Code:
59
60;; System-wide configuration.
61;; TODO: Add per-field docstrings/stexi.
62(define-record-type* <operating-system> operating-system
63 make-operating-system
64 operating-system?
65 (kernel operating-system-kernel ; package
66 (default linux-libre))
67 (bootloader operating-system-bootloader ; package
68 (default grub))
69 (bootloader-entries operating-system-bootloader-entries ; list
70 (default '()))
735c6dd7
LC
71 (initrd operating-system-initrd ; monadic derivation
72 (default (gnu-system-initrd)))
033adfe7
LC
73
74 (host-name operating-system-host-name) ; string
75
76 (file-systems operating-system-file-systems ; list of fs
77 (default '()))
78
79 (users operating-system-users ; list of user accounts
80 (default '()))
81 (groups operating-system-groups ; list of user groups
82 (default (list (user-group
83 (name "root")
84 (id 0))
85 (user-group
86 (name "users")
87 (id 100)
88 (members '("guest"))))))
89
90 (packages operating-system-packages ; list of (PACKAGE OUTPUT...)
4f62d8d6
LC
91 (default (list coreutils ; or just PACKAGE
92 grep
93 sed
94 findutils
95 guile
96 bash
97 (@ (gnu packages dmd) dmd)
3141a8bd
LC
98 guix
99 tzdata)))
033adfe7
LC
100
101 (timezone operating-system-timezone) ; string
102 (locale operating-system-locale) ; string
103
104 (services operating-system-services ; list of monadic services
105 (default
106 (let ((motd (text-file "motd" "
107This is the GNU operating system, welcome!\n\n")))
108 (list (mingetty-service "tty1" #:motd motd)
109 (mingetty-service "tty2" #:motd motd)
110 (mingetty-service "tty3" #:motd motd)
111 (mingetty-service "tty4" #:motd motd)
112 (mingetty-service "tty5" #:motd motd)
113 (mingetty-service "tty6" #:motd motd)
114 (syslog-service)
115 (guix-service)
116 (nscd-service)
117
118 ;; QEMU networking settings.
119 (static-networking-service "eth0" "10.0.2.10"
120 #:name-servers '("10.0.2.3")
121 #:gateway "10.0.2.2"))))))
122
123
124\f
125;;;
126;;; Derivation.
127;;;
128
129(define* (union inputs
130 #:key (guile (%guile-for-build)) (system (%current-system))
131 (name "union"))
132 "Return a derivation that builds the union of INPUTS. INPUTS is a list of
133input tuples."
134 (define builder
135 '(begin
136 (use-modules (guix build union))
137
138 (setvbuf (current-output-port) _IOLBF)
139 (setvbuf (current-error-port) _IOLBF)
140
141 (let ((output (assoc-ref %outputs "out"))
142 (inputs (map cdr %build-inputs)))
143 (format #t "building union `~a' with ~a packages...~%"
144 output (length inputs))
145 (union-build output inputs))))
146
147 (mlet %store-monad
148 ((inputs (sequence %store-monad
149 (map (match-lambda
4f62d8d6 150 ((or ((? package? p)) (? package? p))
033adfe7
LC
151 (mlet %store-monad
152 ((drv (package->derivation p system)))
153 (return `(,name ,drv))))
4f62d8d6 154 (((? package? p) output)
033adfe7
LC
155 (mlet %store-monad
156 ((drv (package->derivation p system)))
157 (return `(,name ,drv ,output))))
158 (x
159 (return x)))
160 inputs))))
161 (derivation-expression name builder
162 #:system system
163 #:inputs inputs
164 #:modules '((guix build union))
165 #:guile-for-build guile)))
166
167(define* (file-union files
168 #:key (inputs '()) (name "file-union"))
169 "Return a derivation that builds a directory containing all of FILES. Each
170item in FILES must be a list where the first element is the file name to use
171in the new directory, and the second element is the target file.
172
173The subset of FILES corresponding to plain store files is automatically added
174as an inputs; additional inputs, such as derivations, are taken from INPUTS."
175 (mlet %store-monad ((inputs (lower-inputs inputs)))
176 (let* ((outputs (append-map (match-lambda
177 ((_ (? derivation? drv))
178 (list (derivation->output-path drv)))
179 ((_ (? derivation? drv) sub-drv ...)
180 (map (cut derivation->output-path drv <>)
181 sub-drv))
182 (_ '()))
183 inputs))
184 (inputs (append inputs
185 (filter (match-lambda
186 ((_ file)
187 ;; Elements of FILES that are store
188 ;; files and that do not correspond to
189 ;; the output of INPUTS are considered
190 ;; inputs (still here?).
191 (and (direct-store-path? file)
192 (not (member file outputs)))))
193 files))))
194 (derivation-expression name
195 `(let ((out (assoc-ref %outputs "out")))
196 (mkdir out)
197 (chdir out)
198 ,@(map (match-lambda
199 ((name target)
200 `(symlink ,target ,name)))
201 files))
202
203 #:inputs inputs))))
204
205(define (links inputs)
206 "Return a directory with symbolic links to all of INPUTS. This is
207essentially useful when one wants to keep references to all of INPUTS, be they
208directories or regular files."
209 (define builder
210 '(begin
211 (use-modules (srfi srfi-1))
212
213 (let ((out (assoc-ref %outputs "out")))
214 (mkdir out)
215 (chdir out)
216 (fold (lambda (file number)
217 (symlink file (number->string number))
218 (+ 1 number))
219 0
220 (map cdr %build-inputs))
221 #t)))
222
223 (mlet %store-monad ((inputs (lower-inputs inputs)))
224 (derivation-expression "links" builder
225 #:inputs inputs)))
226
227(define* (etc-directory #:key
3141a8bd 228 (locale "C") (timezone "Europe/Paris")
033adfe7
LC
229 (accounts '())
230 (groups '())
231 (pam-services '())
232 (profile "/var/run/current-system/profile"))
233 "Return a derivation that builds the static part of the /etc directory."
234 (mlet* %store-monad
235 ((services (package-file net-base "etc/services"))
236 (protocols (package-file net-base "etc/protocols"))
237 (rpc (package-file net-base "etc/rpc"))
238 (passwd (passwd-file accounts))
239 (shadow (passwd-file accounts #:shadow? #t))
240 (group (group-file groups))
241 (pam.d (pam-services->directory pam-services))
242 (login.defs (text-file "login.defs" "# Empty for now.\n"))
243 (issue (text-file "issue" "
244This is an alpha preview of the GNU system. Welcome.
245
246This image features the GNU Guix package manager, which was used to
247build it (http://www.gnu.org/software/guix/). The init system is
248GNU dmd (http://www.gnu.org/software/dmd/).
249
250You can log in as 'guest' or 'root' with no password.
251"))
252
3141a8bd
LC
253 ;; Assume TZDATA is installed---e.g., as part of the system packages.
254 ;; Users can choose not to have it.
255 (tzdir (package-file tzdata "share/zoneinfo"))
256
033adfe7
LC
257 ;; TODO: Generate bashrc from packages' search-paths.
258 (bashrc (text-file "bashrc" (string-append "
259export PS1='\\u@\\h\\$ '
3141a8bd
LC
260
261export LC_ALL=\"" locale "\"
262export TZ=\"" timezone "\"
263export TZDIR=\"" tzdir "\"
264
033adfe7
LC
265export PATH=$HOME/.guix-profile/bin:" profile "/bin:" profile "/sbin
266export CPATH=$HOME/.guix-profile/include:" profile "/include
267export LIBRARY_PATH=$HOME/.guix-profile/lib:" profile "/lib
268alias ls='ls -p --color'
269alias ll='ls -l'
270")))
271
272 (files -> `(("services" ,services)
273 ("protocols" ,protocols)
274 ("rpc" ,rpc)
275 ("pam.d" ,(derivation->output-path pam.d))
276 ("login.defs" ,login.defs)
277 ("issue" ,issue)
278 ("profile" ,bashrc)
279 ("passwd" ,passwd)
280 ("shadow" ,shadow)
281 ("group" ,group))))
282 (file-union files
283 #:inputs `(("net" ,net-base)
284 ("pam.d" ,pam.d))
285 #:name "etc")))
286
287(define (operating-system-derivation os)
288 "Return a derivation that builds OS."
289 (mlet* %store-monad
290 ((services (sequence %store-monad
291 (cons (host-name-service
292 (operating-system-host-name os))
293 (operating-system-services os))))
294 (pam-services ->
295 ;; Services known to PAM.
296 (delete-duplicates
297 (cons %pam-other-services
298 (append-map service-pam-services services))))
299
300 (bash-file (package-file bash "bin/bash"))
9de46ffb 301 (dmd-file (package-file (@ (gnu packages admin) dmd) "bin/dmd"))
033adfe7
LC
302 (accounts -> (cons (user-account
303 (name "root")
304 (password "")
305 (uid 0) (gid 0)
306 (comment "System administrator")
78ed0038 307 (home-directory "/"))
033adfe7
LC
308 (append (operating-system-users os)
309 (append-map service-user-accounts
310 services))))
311 (groups -> (append (operating-system-groups os)
312 (append-map service-user-groups services)))
313 (packages -> (operating-system-packages os))
314
315 ;; TODO: Replace with a real profile with a manifest.
316 (profile-drv (union packages
317 #:name "default-profile"))
318 (profile -> (derivation->output-path profile-drv))
319 (etc-drv (etc-directory #:accounts accounts #:groups groups
320 #:pam-services pam-services
3141a8bd
LC
321 #:locale (operating-system-locale os)
322 #:timezone (operating-system-timezone os)
033adfe7
LC
323 #:profile profile))
324 (etc -> (derivation->output-path etc-drv))
325 (dmd-conf (dmd-configuration-file services etc))
326
327
328 (boot (text-file "boot"
329 (object->string
330 `(execl ,dmd-file "dmd"
331 "--config" ,dmd-conf))))
332 (kernel -> (operating-system-kernel os))
333 (kernel-dir (package-file kernel))
735c6dd7
LC
334 (initrd (operating-system-initrd os))
335 (initrd-file -> (string-append (derivation->output-path initrd)
336 "/initrd"))
033adfe7
LC
337 (entries -> (list (menu-entry
338 (label (string-append
339 "GNU system with "
340 (package-full-name kernel)
341 " (technology preview)"))
342 (linux kernel)
fc4bc4b6 343 (linux-arguments `("--root=/dev/sda1"
033adfe7 344 ,(string-append "--load=" boot)))
735c6dd7 345 (initrd initrd-file))))
033adfe7
LC
346 (grub.cfg (grub-configuration-file entries))
347 (extras (links (delete-duplicates
78ed0038
LC
348 (append (append-map service-inputs services)
349 (append-map user-account-inputs accounts))))))
033adfe7
LC
350 (file-union `(("boot" ,boot)
351 ("kernel" ,kernel-dir)
352 ("initrd" ,initrd-file)
353 ("dmd.conf" ,dmd-conf)
033adfe7
LC
354 ("profile" ,profile)
355 ("grub.cfg" ,grub.cfg)
356 ("etc" ,etc)
78ed0038 357 ("system-inputs" ,(derivation->output-path extras)))
033adfe7
LC
358 #:inputs `(("kernel" ,kernel)
359 ("initrd" ,initrd)
360 ("bash" ,bash)
361 ("profile" ,profile-drv)
362 ("etc" ,etc-drv)
78ed0038 363 ("system-inputs" ,extras))
033adfe7
LC
364 #:name "system")))
365
366;;; system.scm ends here