branch: main
commit fc0e5e1bc0805ccf6dab2b943220e6fe2c843f83
Author: Ludovic Courtès <[email protected]>
AuthorDate: Fri Mar 21 17:28:40 2025 +0100

    register: Support socket activation.
    
    * src/cuirass/scripts/register.scm (listening-sockets): New procedure.
    (cuirass-register): Use it.
    * doc/cuirass.texi (Invocation): Document it.
---
 doc/cuirass.texi                 | 22 +++++++++++++++++++++-
 src/cuirass/scripts/register.scm | 24 +++++++++++++++++++++---
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/doc/cuirass.texi b/doc/cuirass.texi
index f832c76..04f91f2 100644
--- a/doc/cuirass.texi
+++ b/doc/cuirass.texi
@@ -507,7 +507,27 @@ cuirass register --specifications @var{specs}
 This starts a Cuirass registration instance building @var{specs} and
 storing the results using the default PostgreSQL database.
 
-Additionally the following options can be used.
+@cindex socket activation
+Alternatively, the @command{cuirass register} process can be
+@dfn{socket-activated} (@pxref{Service De- and Constructors,
+@code{make-system-constructor},, shepherd, The GNU Shepherd Manual}).
+In that case, the service manager (which could be the Shepherd or
+systemd) must provide it with two open stream-oriented sockets:
+
+@itemize @code
+@item bridge
+this socket allows other Cuirass process to communicate with this one
+and should be bound to @file{/var/run/cuirass/bridge};
+@item remote-builds
+this is the socket @command{cuirass remote-server} connects to should be
+bound to @file{/var/run/cuirass/remote-builds}.
+@end itemize
+
+Using the socket activation mechanism ensures proper synchronization
+among the various @command{cuirass} process when they start up.
+
+The full list of options @command{cuirass register} supports is given
+below.
 
 @table @code
 @item --one-shot
diff --git a/src/cuirass/scripts/register.scm b/src/cuirass/scripts/register.scm
index 836dfe4..a71d2ff 100644
--- a/src/cuirass/scripts/register.scm
+++ b/src/cuirass/scripts/register.scm
@@ -105,6 +105,24 @@
   (log-info "opening bridge socket at '~a'" (%bridge-socket-file-name))
   (open-unix-listening-socket (%bridge-socket-file-name)))
 
+(define (listening-sockets)
+  "Return a list of name/port pairs corresponding to each server socket
+accepting incoming connections."
+  (match (activation-sockets)
+    (()
+     ;; Not socket-activated so explicitly open these sockets.
+     `((bridge . ,(open-bridge-socket))
+       (remote-builds . ,(open-unix-listening-socket
+                          (%remote-server-socket-file-name)))))
+    (lst
+     (log-info "socket-activated with the following sockets:~{ ~a~}"
+               (map car lst))
+     (unless (and (assoc-ref lst 'bridge)
+                  (assoc-ref lst 'remote-builds))
+       (log-error "missing some sockets")
+       (exit 1))
+     lst)))
+
 (define (bridge channel                           ;currently unused
                 socket registry)
   (define (serve-client socket)
@@ -272,10 +290,10 @@
                    (leave (G_ "'--one-shot' is currently unimplemented~%"))
                    (let* ((exit-channel (make-channel))
                           (event-log-service (spawn-event-log-service))
+                          (sockets (listening-sockets))
                           (builder (if (option-ref opts 'build-remote #f)
                                        (spawn-remote-builder
-                                        (open-unix-listening-socket
-                                         (%remote-server-socket-file-name))
+                                        (assoc-ref sockets 'remote-builds)
                                         event-log-service)
                                        (spawn-local-builder 
event-log-service)))
                           (evaluator (spawn-jobset-evaluator
@@ -310,7 +328,7 @@
                        ;; Spawn the bridge through which other 'cuirass'
                        ;; processes, such as 'cuirass web', may talk to the
                        ;; registry.
-                       (spawn-bridge (open-bridge-socket) registry))
+                       (spawn-bridge (assoc-ref sockets 'bridge) registry))
 
                      ;; Periodically delete old GC roots.
                      (spawn-gc-root-cleaner gc-root-ttl

Reply via email to