Subject: [PATCH v2 3/4] services: guix: Add guix-build-coordinator-agent-service-type.

From: Christopher Baines <[email-masked]>
Date: Sat, 19 Sep 2020 11:10:58 +0100

* gnu/services/guix.scm (<guix-build-coordinator-agent-configuration>): New
record type.
(guix-build-coordinator-agent-configuration,
guix-build-coordinator-agent-configuration?,
guix-build-coordinator-agent-configuration-package,
guix-build-coordinator-agent-configuration-user,
guix-build-coordinator-agent-configuration-coordinator,
guix-build-coordinator-agent-configuration-uuid),
guix-build-coordinator-agent-configuration-password,
guix-build-coordinator-agent-configuration-password-file,
guix-build-coordinator-agent-configuration-systems,
guix-build-coordinator-agent-configuration-max-parallel-builds,
guix-build-coordinator-agent-configuration-derivation-substitute-urls,
guix-build-coordinator-agent-configuration-non-derivation-substitute-urls,
guix-build-coordinator-agent-shepherd-services,
guix-build-coordinator-agent-activation,
guix-build-coordinator-agent-account): New procedures.
(guix-build-coordinator-agent-service-type): New variable.
* doc/guix.texi (Guix Services): Document it.
---
 doc/guix.texi         |  50 +++++++++++++++++
 gnu/services/guix.scm | 121 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 171 insertions(+)

diff --git a/doc/guix.texi b/doc/guix.texi
index 4f3f0e851f..b2dde30ddb 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -27554,6 +27554,56 @@ The Guile package with which to run the Guix Build Coordinator.
 @end table
 @end deftp
 
+@defvar {Scheme Variable} guix-build-coordinator-agent-service-type
+Service type for a Guix Build Coordinator agent.  Its value must be a
+@code{guix-build-coordinator-agent-configuration} object.
+@end defvar
+
+@deftp {Data Type} guix-build-coordinator-agent-configuration
+Data type representing the configuration a Guix Build Coordinator agent.
+
+@table @asis
+@item @code{package} (default: @code{guix-build-coordinator})
+The Guix Build Coordinator package to use.
+
+@item @code{user} (default: @code{"guix-build-coordinator-agent"})
+The system user to run the service as.
+
+@item @code{coordinator} (default: @code{"http://localhost:8745"})
+The URI to use when connecting to the coordinator.
+
+@item @code{uuid}
+The UUID of the agent.  This should be generated by the coordinator
+process, stored in the coordinator database, and used by the intended
+agent.
+
+@item @code{password} (default: @code{#f})
+The password to use when connecting to the coordinator.  A file to read
+the password from can also be specified, and this is more secure.
+
+@item @code{password-file} (default: @code{#f})
+A file containing the password to use when connecting to the
+coordinator.
+
+@item @code{systems} (default: @var{#f})
+The systems for which this agent should fetch builds.  The agent process
+will use the current system it's running on as the default.
+
+@item @code{max-parallel-builds} (default: @code{1})
+The number of builds to perform in parallel.
+
+@item @code{derivation-substitute-urls} (default: @code{1})
+URLs from which to attempt to fetch substitutes for derivations, if the
+derivations aren't already available.
+
+@item @code{non-derivation-substitute-urls} (default: @code{1})
+URLs from which to attempt to fetch substitutes for build inputs, if the
+input store items aren't already available.
+
+@end table
+@end deftp
+
+
 @subsubheading Guix Data Service
 The @uref{http://data.guix.gnu.org,Guix Data Service} processes, stores
 and provides data about GNU Guix.  This includes information about
diff --git a/gnu/services/guix.scm b/gnu/services/guix.scm
index 1bacd61190..e4f5cf57b9 100644
--- a/gnu/services/guix.scm
+++ b/gnu/services/guix.scm
@@ -50,6 +50,21 @@
 
             guix-build-coordinator-service-type
 
+            guix-build-coordinator-agent-configuration
+            guix-build-coordinator-agent-configuration?
+            guix-build-coordinator-agent-configuration-package
+            guix-build-coordinator-agent-configuration-user
+            guix-build-coordinator-agent-configuration-coordinator
+            guix-build-coordinator-agent-configuration-uuid
+            guix-build-coordinator-agent-configuration-password
+            guix-build-coordinator-agent-configuration-password-file
+            guix-build-coordinator-agent-configuration-systems
+            guix-build-coordinator-agent-configuration-max-parallel-builds
+            guix-build-coordinator-agent-configuration-derivation-substitute-urls
+            guix-build-coordinator-agent-configuration-non-derivation-substitute-urls
+
+            guix-build-coordinator-agent-service-type
+
             <guix-data-service-configuration>
             guix-data-service-configuration
             guix-data-service-configuration?
@@ -95,6 +110,33 @@
   (guile                           guix-build-coordinator-configuration-guile
                                    (default guile-3.0-latest)))
 
+(define-record-type* <guix-build-coordinator-agent-configuration>
+  guix-build-coordinator-agent-configuration
+  make-guix-build-coordinator-agent-configuration
+  guix-build-coordinator-agent-configuration?
+  (package             guix-build-coordinator-agent-configuration-package
+                       (default guix-build-coordinator))
+  (user                guix-build-coordinator-agent-configuration-user
+                       (default "guix-build-coordinator-agent"))
+  (coordinator         guix-build-coordinator-agent-configuration-coordinator
+                       (default "http://localhost:8745"))
+  (uuid                guix-build-coordinator-agent-configuration-uuid)
+  (password            guix-build-coordinator-agent-configuration-password
+                       (default #f))
+  (password-file       guix-build-coordinator-agent-configuration-password-file
+                       (default #f))
+  (systems             guix-build-coordinator-agent-configuration-systems
+                       (default #f))
+  (max-parallel-builds
+   guix-build-coordinator-agent-configuration-max-parallel-builds
+   (default 1))
+  (derivation-substitute-urls
+   guix-build-coordinator-agent-configuration-derivation-substitute-urls
+   (default #f))
+  (non-derivation-substitute-urls
+   guix-build-coordinator-agent-configuration-non-derivation-substitute-urls
+   (default #f)))
+
 (define* (make-guix-build-coordinator-start-script database-uri-string
                                                    allocation-strategy
                                                    pid-file
@@ -239,6 +281,85 @@
    (description
     "Run an instance of the Guix Build Coordinator.")))
 
+(define (guix-build-coordinator-agent-shepherd-services config)
+  (match-record config <guix-build-coordinator-agent-configuration>
+    (package user coordinator uuid password password-file max-parallel-builds
+             derivation-substitute-urls non-derivation-substitute-urls
+             systems)
+    (list
+     (shepherd-service
+      (documentation "Guix Build Coordinator Agent")
+      (provision '(guix-build-coordinator-agent))
+      (requirement '(networking))
+      (start #~(make-forkexec-constructor
+                (list #$(file-append package "/bin/guix-build-coordinator-agent")
+                      #$(string-append "--coordinator=" coordinator)
+                      #$(string-append "--uuid=" uuid)
+                      #$@(if password
+                             #~(#$(string-append "--password=" password))
+                             #~())
+                      #$@(if password-file
+                             #~(#$(string-append "--password-file=" password-file))
+                             #~())
+                      #$(simple-format #f "--max-parallel-builds=~A"
+                                       max-parallel-builds)
+                      #$@(if derivation-substitute-urls
+                             #~(#$(string-append
+                                   "--derivation-substitute-urls="
+                                 (string-join derivation-substitute-urls " ")))
+                             #~())
+                      #$@(if non-derivation-substitute-urls
+                             #~(#$(string-append
+                                   "--non-derivation-substitute-urls="
+                                   (string-join derivation-substitute-urls " ")))
+                             #~())
+                      #$@(map (lambda (system)
+                                (string-append "--system=" system))
+                              (or systems '())))
+                #:user #$user
+                #:pid-file "/var/run/guix-build-coordinator-agent/pid"
+                #:environment-variables
+                `(,(string-append
+                    "GUIX_LOCPATH=" #$glibc-utf8-locales "/lib/locale")
+                  "LC_ALL=en_US.utf8")
+                #:log-file "/var/log/guix-build-coordinator/agent.log"))
+      (stop #~(make-kill-destructor))))))
+
+(define (guix-build-coordinator-agent-activation config)
+  #~(begin
+      (use-modules (guix build utils))
+
+      (mkdir-p "/var/log/guix-build-coordinator")
+
+      ;; Allow writing the PID file
+      (mkdir-p "/var/run/guix-build-coordinator-agent")
+      (chown "/var/run/guix-build-coordinator-agent"
+             (passwd:uid %user)
+             (passwd:gid %user))))
+
+(define (guix-build-coordinator-agent-account config)
+  (list (user-account
+         (name (guix-build-coordinator-agent-configuration-user config))
+         (group "nogroup")
+         (system? #t)
+         (comment "Guix Build Coordinator agent user")
+         (home-directory "/var/empty")
+         (shell (file-append shadow "/sbin/nologin")))))
+
+(define guix-build-coordinator-agent-service-type
+  (service-type
+   (name 'guix-build-coordinator-agent)
+   (extensions
+    (list
+     (service-extension shepherd-root-service-type
+                        guix-build-coordinator-agent-shepherd-services)
+     (service-extension activation-service-type
+                        guix-build-coordinator-agent-activation)
+     (service-extension account-service-type
+                        guix-build-coordinator-agent-account)))
+   (description
+    "Run a Guix Build Coordinator agent.")))
+
 
 ;;;
 ;;; Guix Data Service
-- 
2.28.0