services: Add 'modify-services'.
authorLudovic Courtès <ludo@gnu.org>
Wed, 28 Oct 2015 20:36:07 +0000 (21:36 +0100)
committerLudovic Courtès <ludo@gnu.org>
Wed, 28 Oct 2015 20:58:25 +0000 (21:58 +0100)
* gnu/services.scm (%modify-service, modify-services): New macros.
* gnu/services/base.scm (mingetty-service-type, guix-service-type):
  Export.
* emacs/guix-devel.el (guix-devel-keywords): Add 'modify-services'.
  Ditto in 'guix-devel-scheme-indent' call.
* doc/guix.texi (Using the Configuration System): Give an example of
  'modify-services'.
  (Service Reference): Document it.

.dir-locals.el
doc/guix.texi
emacs/guix-devel.el
gnu/services.scm
gnu/services/base.scm

index 54d5bda..0873c1d 100644 (file)
@@ -23,6 +23,7 @@
    (eval . (put 'lambda* 'scheme-indent-function 1))
    (eval . (put 'substitute* 'scheme-indent-function 1))
    (eval . (put 'modify-phases 'scheme-indent-function 1))
+   (eval . (put 'modify-services 'scheme-indent-function 1))
    (eval . (put 'with-directory-excursion 'scheme-indent-function 1))
    (eval . (put 'package 'scheme-indent-function 0))
    (eval . (put 'origin 'scheme-indent-function 0))
index 0a38279..01e2804 100644 (file)
@@ -5363,16 +5363,40 @@ The @code{services} field lists @dfn{system services} to be made
 available when the system starts (@pxref{Services}).
 The @code{operating-system} declaration above specifies that, in
 addition to the basic services, we want the @command{lshd} secure shell
-daemon listening on port 2222, and allowing remote @code{root} logins
-(@pxref{Invoking lshd,,, lsh, GNU lsh Manual}).  Under the hood,
+daemon listening on port 2222 (@pxref{Networking Services,
+@code{lsh-service}}).  Under the hood,
 @code{lsh-service} arranges so that @code{lshd} is started with the
 right command-line options, possibly with supporting configuration files
-generated as needed (@pxref{Defining Services}).  @xref{operating-system
-Reference}, for details about the available @code{operating-system}
-fields.
+generated as needed (@pxref{Defining Services}).
+
+@cindex customization, of services
+@findex modify-services
+Occasionally, instead of using the base services as is, you will want to
+customize them.  For instance, to change the configuration of
+@code{guix-daemon} and Mingetty (the console log-in), you may write the
+following instead of @var{%base-services}:
+
+@lisp
+(modify-services %base-services
+  (guix-service-type config =>
+                     (guix-configuration
+                      (inherit config)
+                      (use-substitutes? #f)
+                      (extra-options '("--gc-keep-outputs"))))
+  (mingetty-service-type config =>
+                         (mingetty-configuration
+                          (inherit config)
+                          (motd (plain-file "motd" "Hi there!")))))
+@end lisp
+
+@noindent
+The effect here is to change the options passed to @command{guix-daemon}
+when it is started, as well as the ``message of the day'' that appears
+when logging in at the console.  @xref{Service Reference,
+@code{modify-services}}, for more on that.
 
 The configuration for a typical ``desktop'' usage, with the X11 display
-server, a desktop environment, network management, an SSH server, and
+server, a desktop environment, network management, power management, and
 more, would look like this:
 
 @lisp
@@ -5382,6 +5406,8 @@ more, would look like this:
 @xref{Desktop Services}, for the exact list of services provided by
 @var{%desktop-services}.  @xref{X.509 Certificates}, for background
 information about the @code{nss-certs} package that is used here.
+@xref{operating-system Reference}, for details about all the available
+@code{operating-system} fields.
 
 Assuming the above snippet is stored in the @file{my-system-config.scm}
 file, the @command{guix system reconfigure my-system-config.scm} command
@@ -7539,6 +7565,41 @@ Here is an example of how a service is created and manipulated:
 @result{} #t
 @end example
 
+The @code{modify-services} form provides a handy way to change the
+parameters of some of the services of a list such as
+@var{%base-services} (@pxref{Base Services, @code{%base-services}}).  Of
+course, you could always use standard list combinators such as
+@code{map} and @code{fold} to do that (@pxref{SRFI-1, List Library,,
+guile, GNU Guile Reference Manual}); @code{modify-services} simply
+provides a more concise form for this common pattern.
+
+@deffn {Scheme Syntax} modify-services @var{services} @
+  (@var{type} @var{variable} => @var{body}) @dots{}
+
+Modify the services listed in @var{services} according to the given
+clauses.  Each clause has the form:
+
+@example
+(@var{type} @var{variable} => @var{body})
+@end example
+
+where @var{type} is a service type, such as @var{guix-service-type}, and
+@var{variable} is an identifier that is bound within @var{body} to the
+value of the service of that @var{type}.  @xref{Using the Configuration
+System}, for an example.
+
+This is a shorthand for:
+
+@example
+(map (lambda (service) @dots{}) @var{services})
+@end example
+@end deffn
+
+Next comes the programming interface for service types.  This is
+something you want to know when writing new service definitions, but not
+necessarily when simply looking for ways to customize your
+@code{operating-system} declaration.
+
 @deftp {Data Type} service-type
 @cindex service type
 This is the representation of a @dfn{service type} (@pxref{Service Types
index 170ce1a..8eb0309 100644 (file)
@@ -198,6 +198,7 @@ to find 'modify-phases' keywords."
     "mbegin"
     "mlet"
     "mlet*"
+    "modify-services"
     "munless"
     "mwhen"
     "run-with-state"
@@ -288,6 +289,7 @@ Each rule should have a form (SYMBOL VALUE).  See `put' for details."
   (mlet 2)
   (mlet* 2)
   (modify-phases 1)
+  (modify-services 1)
   (munless 1)
   (mwhen 1)
   (operating-system 0)
index d0fe0ad..8182523 100644 (file)
@@ -48,6 +48,7 @@
             service-kind
             service-parameters
 
+            modify-services
             service-back-edges
             fold-services
 
   (parameters service-parameters))
 
 
+(define-syntax %modify-service
+  (syntax-rules (=>)
+    ((_ service)
+     service)
+    ((_ svc (kind param => exp ...) clauses ...)
+     (if (eq? (service-kind svc) kind)
+         (let ((param (service-parameters svc)))
+           (service (service-kind svc)
+                    (begin exp ...)))
+         (%modify-service svc clauses ...)))))
+
+(define-syntax modify-services
+  (syntax-rules ()
+    "Modify the services listed in SERVICES according to CLAUSES.  Each clause
+must have the form:
+
+  (TYPE VARIABLE => BODY)
+
+where TYPE is a service type, such as 'guix-service-type', and VARIABLE is an
+identifier that is bound within BODY to the value of the service of that
+TYPE.  Consider this example:
+
+  (modify-services %base-services
+    (guix-service-type config =>
+                       (guix-configuration
+                        (inherit config)
+                        (use-substitutes? #f)
+                        (extra-options '(\"--gc-keep-derivations\"))))
+    (mingetty-service-type config =>
+                           (mingetty-configuration
+                            (inherit config)
+                            (motd (plain-file \"motd\" \"Hi there!\")))))
+
+It changes the configuration of the GUIX-SERVICE-TYPE instance, and that of
+all the MINGETTY-SERVICE-TYPE instances.
+
+This is a shorthand for (map (lambda (svc) ...) %base-services)."
+    ((_ services clauses ...)
+     (map (lambda (service)
+            (%modify-service service clauses ...))
+          services))))
 
 \f
 ;;;
index 618cef8..b8e8ccd 100644 (file)
@@ -57,6 +57,7 @@
             mingetty-configuration
             mingetty-configuration?
             mingetty-service
+            mingetty-service-type
 
             %nscd-default-caches
             %nscd-default-configuration
@@ -74,6 +75,7 @@
             guix-configuration
             guix-configuration?
             guix-service
+            guix-service-type
 
             %base-services))