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