summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi26
-rw-r--r--doc/images/service-graph.dot5
-rw-r--r--gnu/services.scm51
-rw-r--r--gnu/system.scm54
-rw-r--r--gnu/system/linux-container.scm18
-rw-r--r--guix/scripts/system.scm6
6 files changed, 103 insertions, 57 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 74e0977db50..6ab98deef3a 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -7589,8 +7589,11 @@ as arrows, a typical system might provide something like this:
7589 7589
7590@image{images/service-graph,,5in,Typical service extension graph.} 7590@image{images/service-graph,,5in,Typical service extension graph.}
7591 7591
7592At the bottom, we see the @dfn{boot service}, which produces the boot 7592@cindex system service
7593script that is executed at boot time from the initial RAM disk. 7593At the bottom, we see the @dfn{system service}, which produces the
7594directory containing everything to run and boot the system, as returned
7595by the @command{guix system build} command. @xref{Service Reference},
7596to learn about the other service types shown here.
7594@xref{system-extension-graph, the @command{guix system extension-graph} 7597@xref{system-extension-graph, the @command{guix system extension-graph}
7595command}, for information on how to generate this representation for a 7598command}, for information on how to generate this representation for a
7596particular operating system definition. 7599particular operating system definition.
@@ -7853,12 +7856,14 @@ Return true if @var{obj} is a service extension.
7853 7856
7854At the core of the service abstraction lies the @code{fold-services} 7857At the core of the service abstraction lies the @code{fold-services}
7855procedure, which is responsible for ``compiling'' a list of services 7858procedure, which is responsible for ``compiling'' a list of services
7856down to a single boot script. In essence, it propagates service 7859down to a single directory that contains everything needed to boot and
7857extensions down the service graph, updating each node parameters on the 7860run the system---the directory shown by the @command{guix system build}
7858way, until it reaches the root node. 7861command (@pxref{Invoking guix system}). In essence, it propagates
7862service extensions down the service graph, updating each node parameters
7863on the way, until it reaches the root node.
7859 7864
7860@deffn {Scheme Procedure} fold-services @var{services} @ 7865@deffn {Scheme Procedure} fold-services @var{services} @
7861 [#:target-type @var{boot-service-type}] 7866 [#:target-type @var{system-service-type}]
7862Fold @var{services} by propagating their extensions down to the root of 7867Fold @var{services} by propagating their extensions down to the root of
7863type @var{target-type}; return the root service adjusted accordingly. 7868type @var{target-type}; return the root service adjusted accordingly.
7864@end deffn 7869@end deffn
@@ -7866,9 +7871,14 @@ type @var{target-type}; return the root service adjusted accordingly.
7866Lastly, the @code{(gnu services)} module also defines several essential 7871Lastly, the @code{(gnu services)} module also defines several essential
7867service types, some of which are listed below. 7872service types, some of which are listed below.
7868 7873
7874@defvr {Scheme Variable} system-service-type
7875This is the root of the service graph. It produces the system directory
7876as returned by the @command{guix system build} command.
7877@end defvr
7878
7869@defvr {Scheme Variable} boot-service-type 7879@defvr {Scheme Variable} boot-service-type
7870The type of the ``boot service'', which is the root of the service 7880The type of the ``boot service'', which produces the @dfn{boot script}.
7871graph. 7881The boot script is what the initial RAM disk runs when booting.
7872@end defvr 7882@end defvr
7873 7883
7874@defvr {Scheme Variable} etc-service-type 7884@defvr {Scheme Variable} etc-service-type
diff --git a/doc/images/service-graph.dot b/doc/images/service-graph.dot
index 3397b878e96..04f231bb098 100644
--- a/doc/images/service-graph.dot
+++ b/doc/images/service-graph.dot
@@ -4,7 +4,8 @@ digraph "Service Type Dependencies" {
4 etc [shape = box, fontname = Helvetica]; 4 etc [shape = box, fontname = Helvetica];
5 accounts [shape = box, fontname = Helvetica]; 5 accounts [shape = box, fontname = Helvetica];
6 activation [shape = box, fontname = Helvetica]; 6 activation [shape = box, fontname = Helvetica];
7 boot [shape = house, fontname = Helvetica]; 7 boot [shape = box, fontname = Helvetica];
8 system [shape = house, fontname = Helvetica];
8 lshd -> dmd; 9 lshd -> dmd;
9 lshd -> pam; 10 lshd -> pam;
10 udev -> dmd; 11 udev -> dmd;
@@ -32,4 +33,6 @@ digraph "Service Type Dependencies" {
32 guix -> dmd; 33 guix -> dmd;
33 guix -> activation; 34 guix -> activation;
34 guix -> accounts; 35 guix -> accounts;
36 boot -> system;
37 etc -> system;
35} 38}
diff --git a/gnu/services.scm b/gnu/services.scm
index ecf3532e52e..8a66d453dfd 100644
--- a/gnu/services.scm
+++ b/gnu/services.scm
@@ -60,6 +60,7 @@
60 ambiguous-target-service-error-service 60 ambiguous-target-service-error-service
61 ambiguous-target-service-error-target-type 61 ambiguous-target-service-error-target-type
62 62
63 system-service-type
63 boot-service-type 64 boot-service-type
64 activation-service-type 65 activation-service-type
65 activation-service->script 66 activation-service->script
@@ -89,9 +90,10 @@
89;;; by providing one procedure to compose extensions, and one procedure to 90;;; by providing one procedure to compose extensions, and one procedure to
90;;; extend itself. 91;;; extend itself.
91;;; 92;;;
92;;; A notable service type is BOOT-SERVICE-TYPE, which has a single instance, 93;;; A notable service type is SYSTEM-SERVICE-TYPE, which has a single
93;;; %BOOT-SERVICE. %BOOT-SERVICE constitutes the root of the service DAG. It 94;;; instance, which is the root of the service DAG. Its value is the
94;;; produces the boot script that the initrd loads. 95;;; derivation that produces the 'system' directory as returned by
96;;; 'operating-system-derivation'.
95;;; 97;;;
96;;; The 'fold-services' procedure can be passed a list of procedures, which it 98;;; The 'fold-services' procedure can be passed a list of procedures, which it
97;;; "folds" by propagating extensions down the graph; it returns the root 99;;; "folds" by propagating extensions down the graph; it returns the root
@@ -182,6 +184,25 @@ This is a shorthand for (map (lambda (svc) ...) %base-services)."
182;;; Core services. 184;;; Core services.
183;;; 185;;;
184 186
187(define (system-derivation mentries mextensions)
188 "Return as a monadic value the derivation of the 'system' directory
189containing the given entries."
190 (mlet %store-monad ((entries mentries)
191 (extensions (sequence %store-monad mextensions)))
192 (lower-object
193 (file-union "system"
194 (append entries (concatenate extensions))))))
195
196(define system-service-type
197 ;; This is the ultimate service type, the root of the service DAG. The
198 ;; service of this type is extended by monadic name/item pairs. These items
199 ;; end up in the "system directory" as returned by
200 ;; 'operating-system-derivation'.
201 (service-type (name 'system)
202 (extensions '())
203 (compose identity)
204 (extend system-derivation)))
205
185(define (compute-boot-script _ mexps) 206(define (compute-boot-script _ mexps)
186 (mlet %store-monad ((gexps (sequence %store-monad mexps))) 207 (mlet %store-monad ((gexps (sequence %store-monad mexps)))
187 (gexp->file "boot" 208 (gexp->file "boot"
@@ -203,17 +224,25 @@ This is a shorthand for (map (lambda (svc) ...) %base-services)."
203 ;; Activate the system and spawn dmd. 224 ;; Activate the system and spawn dmd.
204 #$@gexps)))) 225 #$@gexps))))
205 226
227(define (boot-script-entry mboot)
228 "Return, as a monadic value, an entry for the boot script in the system
229directory."
230 (mlet %store-monad ((boot mboot))
231 (return `(("boot" ,boot)))))
232
206(define boot-service-type 233(define boot-service-type
207 ;; The service of this type is extended by being passed gexps as monadic 234 ;; The service of this type is extended by being passed gexps as monadic
208 ;; values. It aggregates them in a single script, as a monadic value, which 235 ;; values. It aggregates them in a single script, as a monadic value, which
209 ;; becomes its 'parameters'. It is the only service that extends nothing. 236 ;; becomes its 'parameters'. It is the only service that extends nothing.
210 (service-type (name 'boot) 237 (service-type (name 'boot)
211 (extensions '()) 238 (extensions
239 (list (service-extension system-service-type
240 boot-script-entry)))
212 (compose append) 241 (compose append)
213 (extend compute-boot-script))) 242 (extend compute-boot-script)))
214 243
215(define %boot-service 244(define %boot-service
216 ;; This is the ultimate service, the root of the service DAG. 245 ;; The service that produces the boot script.
217 (service boot-service-type #t)) 246 (service boot-service-type #t))
218 247
219(define* (file-union name files) ;FIXME: Factorize. 248(define* (file-union name files) ;FIXME: Factorize.
@@ -351,6 +380,12 @@ ACTIVATION-SCRIPT-TYPE."
351(define (files->etc-directory files) 380(define (files->etc-directory files)
352 (file-union "etc" files)) 381 (file-union "etc" files))
353 382
383(define (etc-entry files)
384 "Return an entry for the /etc directory consisting of FILES in the system
385directory."
386 (with-monad %store-monad
387 (return `(("etc" ,(files->etc-directory files))))))
388
354(define etc-service-type 389(define etc-service-type
355 (service-type (name 'etc) 390 (service-type (name 'etc)
356 (extensions 391 (extensions
@@ -359,7 +394,8 @@ ACTIVATION-SCRIPT-TYPE."
359 (lambda (files) 394 (lambda (files)
360 (let ((etc 395 (let ((etc
361 (files->etc-directory files))) 396 (files->etc-directory files)))
362 #~(activate-etc #$etc)))))) 397 #~(activate-etc #$etc))))
398 (service-extension system-service-type etc-entry)))
363 (compose concatenate) 399 (compose concatenate)
364 (extend append))) 400 (extend append)))
365 401
@@ -450,7 +486,8 @@ kernel."
450 (lambda (node) 486 (lambda (node)
451 (reverse (vhash-foldq* cons '() node edges))))) 487 (reverse (vhash-foldq* cons '() node edges)))))
452 488
453(define* (fold-services services #:key (target-type boot-service-type)) 489(define* (fold-services services
490 #:key (target-type system-service-type))
454 "Fold SERVICES by propagating their extensions down to the root of type 491 "Fold SERVICES by propagating their extensions down to the root of type
455TARGET-TYPE; return the root service adjusted accordingly." 492TARGET-TYPE; return the root service adjusted accordingly."
456 (define dependents 493 (define dependents
diff --git a/gnu/system.scm b/gnu/system.scm
index 8fed857b399..c26d27028b0 100644
--- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -254,6 +254,24 @@ from the initrd."
254 "Return the list of swap services for OS." 254 "Return the list of swap services for OS."
255 (map swap-service (operating-system-swap-devices os))) 255 (map swap-service (operating-system-swap-devices os)))
256 256
257(define* (operating-system-directory-base-entries os #:key container?)
258 "Return the basic entries of the 'system' directory of OS for use as the
259value of the SYSTEM-SERVICE-TYPE service."
260 (mlet* %store-monad ((profile (operating-system-profile os))
261 (locale (operating-system-locale-directory os)))
262 (if container?
263 (return `(("profile" ,profile)
264 ("locale" ,locale)))
265 (mlet %store-monad
266 ((kernel -> (operating-system-kernel os))
267 (initrd (operating-system-initrd-file os))
268 (params (operating-system-parameters-file os)))
269 (return `(("kernel" ,kernel)
270 ("parameters" ,params)
271 ("initrd" ,initrd)
272 ("profile" ,profile)
273 ("locale" ,locale))))))) ;used by libc
274
257(define* (essential-services os #:key container?) 275(define* (essential-services os #:key container?)
258 "Return the list of essential services for OS. These are special services 276 "Return the list of essential services for OS. These are special services
259that implement part of what's declared in OS are responsible for low-level 277that implement part of what's declared in OS are responsible for low-level
@@ -269,8 +287,11 @@ a container or that of a \"bare metal\" system."
269 (swaps (swap-services os)) 287 (swaps (swap-services os))
270 (procs (user-processes-service 288 (procs (user-processes-service
271 (map service-parameters other-fs))) 289 (map service-parameters other-fs)))
272 (host-name (host-name-service (operating-system-host-name os)))) 290 (host-name (host-name-service (operating-system-host-name os)))
273 (cons* %boot-service 291 (entries (operating-system-directory-base-entries
292 os #:container? container?)))
293 (cons* (service system-service-type entries)
294 %boot-service
274 295
275 ;; %DMD-ROOT-SERVICE must come first so that the gexp that execs 296 ;; %DMD-ROOT-SERVICE must come first so that the gexp that execs
276 ;; dmd comes last in the boot script (XXX). 297 ;; dmd comes last in the boot script (XXX).
@@ -607,10 +628,17 @@ etc."
607we're running in the final root. When CONTAINER? is true, skip all 628we're running in the final root. When CONTAINER? is true, skip all
608hardware-related operations as necessary when booting a Linux container." 629hardware-related operations as necessary when booting a Linux container."
609 (let* ((services (operating-system-services os #:container? container?)) 630 (let* ((services (operating-system-services os #:container? container?))
610 (boot (fold-services services))) 631 (boot (fold-services services #:target-type boot-service-type)))
611 ;; BOOT is the script as a monadic value. 632 ;; BOOT is the script as a monadic value.
612 (service-parameters boot))) 633 (service-parameters boot)))
613 634
635(define* (operating-system-derivation os #:key container?)
636 "Return a derivation that builds OS."
637 (let* ((services (operating-system-services os #:container? container?))
638 (system (fold-services services)))
639 ;; SYSTEM contains the derivation as a monadic value.
640 (service-parameters system)))
641
614(define (operating-system-root-file-system os) 642(define (operating-system-root-file-system os)
615 "Return the root file system of OS." 643 "Return the root file system of OS."
616 (find (match-lambda 644 (find (match-lambda
@@ -693,24 +721,4 @@ this file is the reconstruction of GRUB menu entries for old configurations."
693 #$(operating-system-kernel-arguments os)) 721 #$(operating-system-kernel-arguments os))
694 (initrd #$initrd))))) 722 (initrd #$initrd)))))
695 723
696(define (operating-system-derivation os)
697 "Return a derivation that builds OS."
698 (mlet* %store-monad
699 ((profile (operating-system-profile os))
700 (etc -> (operating-system-etc-directory os))
701 (boot (operating-system-boot-script os))
702 (kernel -> (operating-system-kernel os))
703 (initrd (operating-system-initrd-file os))
704 (locale (operating-system-locale-directory os))
705 (params (operating-system-parameters-file os)))
706 (lower-object
707 (file-union "system"
708 `(("boot" ,#~#$boot)
709 ("kernel" ,#~#$kernel)
710 ("parameters" ,#~#$params)
711 ("initrd" ,initrd)
712 ("profile" ,#~#$profile)
713 ("locale" ,#~#$locale) ;used by libc
714 ("etc" ,#~#$etc))))))
715
716;;; system.scm ends here 724;;; system.scm ends here
diff --git a/gnu/system/linux-container.scm b/gnu/system/linux-container.scm
index c2eb773931d..4f38c5cb0aa 100644
--- a/gnu/system/linux-container.scm
+++ b/gnu/system/linux-container.scm
@@ -47,20 +47,6 @@
47 (check? #f) 47 (check? #f)
48 (create-mount-point? #t))))) 48 (create-mount-point? #t)))))
49 49
50(define (system-container os)
51 "Return a derivation that builds OS as a Linux container."
52 (mlet* %store-monad
53 ((profile (operating-system-profile os))
54 (etc -> (operating-system-etc-directory os))
55 (boot (operating-system-boot-script os #:container? #t))
56 (locale (operating-system-locale-directory os)))
57 (lower-object
58 (file-union "system-container"
59 `(("boot" ,#~#$boot)
60 ("profile" ,#~#$profile)
61 ("locale" ,#~#$locale)
62 ("etc" ,#~#$etc))))))
63
64(define (containerized-operating-system os mappings) 50(define (containerized-operating-system os mappings)
65 "Return an operating system based on OS for use in a Linux container 51 "Return an operating system based on OS for use in a Linux container
66environment. MAPPINGS is a list of <file-system-mapping> to realize in the 52environment. MAPPINGS is a list of <file-system-mapping> to realize in the
@@ -95,7 +81,9 @@ that will be shared with the host system."
95 (operating-system-file-systems os))) 81 (operating-system-file-systems os)))
96 (specs (map file-system->spec file-systems))) 82 (specs (map file-system->spec file-systems)))
97 83
98 (mlet* %store-monad ((os-drv (system-container os))) 84 (mlet* %store-monad ((os-drv (operating-system-derivation
85 os
86 #:container? #t)))
99 87
100 (define script 88 (define script
101 #~(begin 89 #~(begin
diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm
index 7be734785a1..7a8a751df98 100644
--- a/guix/scripts/system.scm
+++ b/guix/scripts/system.scm
@@ -491,10 +491,10 @@ building anything."
491(define (export-extension-graph os port) 491(define (export-extension-graph os port)
492 "Export the service extension graph of OS to PORT." 492 "Export the service extension graph of OS to PORT."
493 (let* ((services (operating-system-services os)) 493 (let* ((services (operating-system-services os))
494 (boot (find (lambda (service) 494 (system (find (lambda (service)
495 (eq? (service-kind service) boot-service-type)) 495 (eq? (service-kind service) system-service-type))
496 services))) 496 services)))
497 (export-graph (list boot) (current-output-port) 497 (export-graph (list system) (current-output-port)
498 #:node-type (service-node-type services) 498 #:node-type (service-node-type services)
499 #:reverse-edges? #t))) 499 #:reverse-edges? #t)))
500 500