1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2019 Christopher Baines <mail@cbaines.net>
4 ;;; This file is part of GNU Guix.
6 ;;; GNU Guix is free software; you can redistribute it and/or modify
7 ;;; it under the terms of the GNU General Public License as published by
8 ;;; the Free Software Foundation, either version 3 of the License, or
9 ;;; (at your option) any later version.
11 ;;; GNU Guix is distributed in the hope that it will be useful,
12 ;;; but 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.
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/>.
19 (define-module (gnu services guix)
20 #:use-module (srfi srfi-1)
21 #:use-module (ice-9 match)
22 #:use-module (guix gexp)
23 #:use-module (guix records)
24 #:use-module (guix packages)
25 #:use-module ((gnu packages base)
26 #:select (glibc-utf8-locales))
27 #:use-module (gnu packages admin)
28 #:use-module (gnu packages databases)
29 #:use-module (gnu packages web)
30 #:use-module (gnu packages guile)
31 #:use-module (gnu packages guile-xyz)
32 #:use-module (gnu packages package-management)
33 #:use-module (gnu services)
34 #:use-module (gnu services base)
35 #:use-module (gnu services admin)
36 #:use-module (gnu services shepherd)
37 #:use-module (gnu services getmail)
38 #:use-module (gnu system shadow)
39 #:export (guix-build-coordinator-configuration
40 guix-build-coordinator-configuration?
41 guix-build-coordinator-configuration-package
42 guix-build-coordinator-configuration-user
43 guix-build-coordinator-configuration-group
44 guix-build-coordinator-configuration-datastore-uri-string
45 guix-build-coordinator-configuration-agent-communication-uri-string
46 guix-build-coordinator-configuration-client-communication-uri-string
47 guix-build-coordinator-configuration-allocation-strategy
48 guix-build-coordinator-configuration-hooks
49 guix-build-coordinator-configuration-guile
51 guix-build-coordinator-service-type
53 guix-build-coordinator-agent-configuration
54 guix-build-coordinator-agent-configuration?
55 guix-build-coordinator-agent-configuration-package
56 guix-build-coordinator-agent-configuration-user
57 guix-build-coordinator-agent-configuration-coordinator
58 guix-build-coordinator-agent-configuration-authentication
59 guix-build-coordinator-agent-configuration-systems
60 guix-build-coordinator-agent-configuration-max-parallel-builds
61 guix-build-coordinator-agent-configuration-max-1min-load-average
62 guix-build-coordinator-agent-configuration-derivation-substitute-urls
63 guix-build-coordinator-agent-configuration-non-derivation-substitute-urls
65 guix-build-coordinator-agent-password-auth
66 guix-build-coordinator-agent-password-auth?
67 guix-build-coordinator-agent-password-auth-uuid
68 guix-build-coordinator-agent-password-auth-password
70 guix-build-coordinator-agent-password-file-auth
71 guix-build-coordinator-agent-password-file-auth?
72 guix-build-coordinator-agent-password-file-auth-uuid
73 guix-build-coordinator-agent-password-file-auth-password-file
75 guix-build-coordinator-agent-dynamic-auth
76 guix-build-coordinator-agent-dynamic-auth?
77 guix-build-coordinator-agent-dynamic-auth-agent-name
78 guix-build-coordinator-agent-dynamic-auth-token
80 guix-build-coordinator-agent-dynamic-auth-with-file
81 guix-build-coordinator-agent-dynamic-auth-with-file?
82 guix-build-coordinator-agent-dynamic-auth-with-file-agent-name
83 guix-build-coordinator-agent-dynamic-auth-with-file-token-file
85 guix-build-coordinator-agent-service-type
87 guix-build-coordinator-queue-builds-configuration
88 guix-build-coordinator-queue-builds-configuration?
89 guix-build-coordinator-queue-builds-configuration-package
90 guix-build-coordinator-queue-builds-configuration-user
91 guix-build-coordinator-queue-builds-coordinator
92 guix-build-coordinator-queue-builds-configuration-systems
93 guix-build-coordinator-queue-builds-configuration-system-and-targets
94 guix-build-coordinator-queue-builds-configuration-guix-data-service
95 guix-build-coordinator-queue-builds-configuration-processed-commits-file
97 guix-build-coordinator-queue-builds-service-type
99 <guix-data-service-configuration>
100 guix-data-service-configuration
101 guix-data-service-configuration?
102 guix-data-service-package
103 guix-data-service-user
104 guix-data-service-group
105 guix-data-service-port
106 guix-data-service-host
107 guix-data-service-getmail-idle-mailboxes
108 guix-data-service-commits-getmail-retriever-configuration
110 guix-data-service-type))
114 ;;; Services specifically related to GNU Guix.
118 (define-record-type* <guix-build-coordinator-configuration>
119 guix-build-coordinator-configuration make-guix-build-coordinator-configuration
120 guix-build-coordinator-configuration?
121 (package guix-build-coordinator-configuration-package
122 (default guix-build-coordinator))
123 (user guix-build-coordinator-configuration-user
124 (default "guix-build-coordinator"))
125 (group guix-build-coordinator-configuration-group
126 (default "guix-build-coordinator"))
128 guix-build-coordinator-configuration-datastore-uri-string
129 (default "sqlite:///var/lib/guix-build-coordinator/guix_build_coordinator.db"))
130 (agent-communication-uri-string
131 guix-build-coordinator-configuration-agent-communication-uri-string
132 (default "http://0.0.0.0:8745"))
133 (client-communication-uri-string
134 guix-build-coordinator-configuration-client-communication-uri-string
135 (default "http://127.0.0.1:8746"))
137 guix-build-coordinator-configuration-allocation-strategy
138 (default #~basic-build-allocation-strategy))
139 (hooks guix-build-coordinator-configuration-hooks
141 (guile guix-build-coordinator-configuration-guile
142 (default guile-3.0-latest)))
144 (define-record-type* <guix-build-coordinator-agent-configuration>
145 guix-build-coordinator-agent-configuration
146 make-guix-build-coordinator-agent-configuration
147 guix-build-coordinator-agent-configuration?
148 (package guix-build-coordinator-agent-configuration-package
149 (default guix-build-coordinator))
150 (user guix-build-coordinator-agent-configuration-user
151 (default "guix-build-coordinator-agent"))
152 (coordinator guix-build-coordinator-agent-configuration-coordinator
153 (default "http://localhost:8745"))
154 (authentication guix-build-coordinator-agent-configuration-authentication)
155 (systems guix-build-coordinator-agent-configuration-systems
158 guix-build-coordinator-agent-configuration-max-parallel-builds
160 (max-1min-load-average
161 guix-build-coordinator-agent-configuration-max-1min-load-average
163 (derivation-substitute-urls
164 guix-build-coordinator-agent-configuration-derivation-substitute-urls
166 (non-derivation-substitute-urls
167 guix-build-coordinator-agent-configuration-non-derivation-substitute-urls
170 (define-record-type* <guix-build-coordinator-agent-password-auth>
171 guix-build-coordinator-agent-password-auth
172 make-guix-build-coordinator-agent-password-auth
173 guix-build-coordinator-agent-password-auth?
174 (uuid guix-build-coordinator-agent-password-auth-uuid)
175 (password guix-build-coordinator-agent-password-auth-password))
177 (define-record-type* <guix-build-coordinator-agent-password-file-auth>
178 guix-build-coordinator-agent-password-file-auth
179 make-guix-build-coordinator-agent-password-file-auth
180 guix-build-coordinator-agent-password-file-auth?
181 (uuid guix-build-coordinator-agent-password-file-auth-uuid)
183 guix-build-coordinator-agent-password-file-auth-password-file))
185 (define-record-type* <guix-build-coordinator-agent-dynamic-auth>
186 guix-build-coordinator-agent-dynamic-auth
187 make-guix-build-coordinator-agent-dynamic-auth
188 guix-build-coordinator-agent-dynamic-auth?
189 (agent-name guix-build-coordinator-agent-dynamic-auth-agent-name)
190 (token guix-build-coordinator-agent-dynamic-auth-token))
192 (define-record-type* <guix-build-coordinator-agent-dynamic-auth-with-file>
193 guix-build-coordinator-agent-dynamic-auth-with-file
194 make-guix-build-coordinator-agent-dynamic-auth-with-file
195 guix-build-coordinator-agent-dynamic-auth-with-file?
196 (agent-name guix-build-coordinator-agent-dynamic-auth-with-file-agent-name)
197 (token-file guix-build-coordinator-agent-dynamic-auth-with-file-token-file))
199 (define-record-type* <guix-build-coordinator-queue-builds-configuration>
200 guix-build-coordinator-queue-builds-configuration
201 make-guix-build-coordinator-queue-builds-configuration
202 guix-build-coordinator-queue-builds-configuration?
203 (package guix-build-coordinator-queue-builds-configuration-package
204 (default guix-build-coordinator))
205 (user guix-build-coordinator-queue-builds-configuration-user
206 (default "guix-build-coordinator-queue-builds"))
207 (coordinator guix-build-coordinator-queue-builds-coordinator
208 (default "http://localhost:8746"))
209 (systems guix-build-coordinator-queue-builds-configuration-systems
212 guix-build-coordinator-queue-builds-configuration-system-and-targets
215 guix-build-coordinator-queue-builds-configuration-guix-data-service
216 (default "https://data.guix.gnu.org"))
217 (processed-commits-file
218 guix-build-coordinator-queue-builds-configuration-processed-commits-file
219 (default "/var/cache/guix-build-coordinator-queue-builds/processed-commits")))
221 (define* (make-guix-build-coordinator-start-script database-uri-string
224 guix-build-coordinator-package
226 agent-communication-uri-string
227 client-communication-uri-string
231 "start-guix-build-coordinator"
232 (with-extensions (cons guix-build-coordinator-package
233 ;; This is a poorly constructed Guile load path,
234 ;; since it contains things that aren't Guile
235 ;; libraries, but it means that the Guile libraries
236 ;; needed for the Guix Build Coordinator don't need
237 ;; to be individually specified here.
239 (map second (package-inputs
240 guix-build-coordinator-package))
241 (map second (package-propagated-inputs
242 guix-build-coordinator-package))))
244 (use-modules (srfi srfi-1)
248 (guix-build-coordinator hooks)
249 (guix-build-coordinator datastore)
250 (guix-build-coordinator build-allocator)
251 (guix-build-coordinator coordinator))
253 (setvbuf (current-output-port) 'line)
254 (setvbuf (current-error-port) 'line)
256 (simple-format #t "starting the guix-build-coordinator:\n ~A\n"
258 (let* ((metrics-registry (make-metrics-registry
260 "guixbuildcoordinator"))
261 (datastore (database-uri->datastore
262 #$database-uri-string
263 #:metrics-registry metrics-registry))
265 (list #$@(map (match-lambda
267 #~(cons '#$name #$hook-gexp)))
271 ,@(remove (match-lambda
272 ((name . _) (assq-ref hooks name)))
274 (build-coordinator (make-build-coordinator
275 #:datastore datastore
276 #:hooks hooks-with-defaults
277 #:metrics-registry metrics-registry
278 #:allocation-strategy #$allocation-strategy)))
280 (run-coordinator-service
282 #:update-datastore? #t
283 #:pid-file #$pid-file
284 #:agent-communication-uri (string->uri
285 #$agent-communication-uri-string)
286 #:client-communication-uri (string->uri
287 #$client-communication-uri-string)))))
290 (define (guix-build-coordinator-shepherd-services config)
291 (match-record config <guix-build-coordinator-configuration>
292 (package user group database-uri-string
293 agent-communication-uri-string
294 client-communication-uri-string
300 (documentation "Guix Build Coordinator")
301 (provision '(guix-build-coordinator))
302 (requirement '(networking))
303 (start #~(make-forkexec-constructor
304 (list #$(make-guix-build-coordinator-start-script
307 "/var/run/guix-build-coordinator/pid"
309 #:agent-communication-uri-string
310 agent-communication-uri-string
311 #:client-communication-uri-string
312 client-communication-uri-string
317 #:pid-file "/var/run/guix-build-coordinator/pid"
318 ;; Allow time for migrations to run
319 #:pid-file-timeout 60
320 #:environment-variables
322 "GUIX_LOCPATH=" #$glibc-utf8-locales "/lib/locale")
324 "PATH=/run/current-system/profile/bin") ; for hooks
325 #:log-file "/var/log/guix-build-coordinator/coordinator.log"))
326 (stop #~(make-kill-destructor))))))
328 (define (guix-build-coordinator-activation config)
330 (use-modules (guix build utils))
333 (getpw #$(guix-build-coordinator-configuration-user
336 (chmod "/var/lib/guix-build-coordinator" #o755)
338 (mkdir-p "/var/log/guix-build-coordinator")
340 ;; Allow writing the PID file
341 (mkdir-p "/var/run/guix-build-coordinator")
342 (chown "/var/run/guix-build-coordinator"
344 (passwd:gid %user))))
346 (define (guix-build-coordinator-account config)
347 (match-record config <guix-build-coordinator-configuration>
356 (comment "Guix Build Coordinator user")
357 (home-directory "/var/lib/guix-build-coordinator")
358 (shell (file-append shadow "/sbin/nologin"))))))
360 (define guix-build-coordinator-service-type
362 (name 'guix-build-coordinator)
365 (service-extension shepherd-root-service-type
366 guix-build-coordinator-shepherd-services)
367 (service-extension activation-service-type
368 guix-build-coordinator-activation)
369 (service-extension account-service-type
370 guix-build-coordinator-account)))
372 (guix-build-coordinator-configuration))
374 "Run an instance of the Guix Build Coordinator.")))
376 (define (guix-build-coordinator-agent-shepherd-services config)
377 (match-record config <guix-build-coordinator-agent-configuration>
378 (package user coordinator authentication max-parallel-builds
379 max-1min-load-average
380 derivation-substitute-urls non-derivation-substitute-urls
384 (documentation "Guix Build Coordinator Agent")
385 (provision '(guix-build-coordinator-agent))
386 (requirement '(networking))
387 (start #~(make-forkexec-constructor
388 (list #$(file-append package "/bin/guix-build-coordinator-agent")
389 #$(string-append "--coordinator=" coordinator)
390 #$@(match authentication
391 (($ <guix-build-coordinator-agent-password-auth>
393 #~(#$(string-append "--uuid=" uuid)
394 #$(string-append "--password=" password)))
395 (($ <guix-build-coordinator-agent-password-file-auth>
397 #~(#$(string-append "--uuid=" uuid)
398 #$(string-append "--password-file="
400 (($ <guix-build-coordinator-agent-dynamic-auth>
402 #~(#$(string-append "--name=" agent-name)
403 #$(string-append "--dynamic-auth-token=" token)))
405 <guix-build-coordinator-agent-dynamic-auth-with-file>
406 agent-name token-file)
407 #~(#$(string-append "--name=" agent-name)
408 #$(string-append "--dynamic-auth-token-file="
410 #$(simple-format #f "--max-parallel-builds=~A"
412 #$@(if max-1min-load-average
413 #~(#$(simple-format #f "--max-1min-load-average=~A"
414 max-1min-load-average))
416 #$@(if derivation-substitute-urls
418 "--derivation-substitute-urls="
419 (string-join derivation-substitute-urls " ")))
421 #$@(if non-derivation-substitute-urls
423 "--non-derivation-substitute-urls="
424 (string-join non-derivation-substitute-urls " ")))
426 #$@(map (lambda (system)
427 (string-append "--system=" system))
430 #:environment-variables
432 "GUIX_LOCPATH=" #$glibc-utf8-locales "/lib/locale")
433 ;; XDG_CACHE_HOME is used by Guix when caching narinfo files
434 "XDG_CACHE_HOME=/var/cache/guix-build-coordinator-agent"
436 #:log-file "/var/log/guix-build-coordinator/agent.log"))
437 (stop #~(make-kill-destructor))))))
439 (define (guix-build-coordinator-agent-activation config)
441 (use-modules (guix build utils))
444 (getpw #$(guix-build-coordinator-agent-configuration-user
447 (mkdir-p "/var/log/guix-build-coordinator")
449 ;; Create a cache directory for storing narinfo files if downloaded
450 (mkdir-p "/var/cache/guix-build-coordinator-agent")
451 (chown "/var/cache/guix-build-coordinator-agent"
453 (passwd:gid %user))))
455 (define (guix-build-coordinator-agent-account config)
457 (name (guix-build-coordinator-agent-configuration-user config))
460 (comment "Guix Build Coordinator agent user")
461 (home-directory "/var/empty")
462 (shell (file-append shadow "/sbin/nologin")))))
464 (define guix-build-coordinator-agent-service-type
466 (name 'guix-build-coordinator-agent)
469 (service-extension shepherd-root-service-type
470 guix-build-coordinator-agent-shepherd-services)
471 (service-extension activation-service-type
472 guix-build-coordinator-agent-activation)
473 (service-extension account-service-type
474 guix-build-coordinator-agent-account)))
476 "Run a Guix Build Coordinator agent.")))
478 (define (guix-build-coordinator-queue-builds-shepherd-services config)
479 (match-record config <guix-build-coordinator-queue-builds-configuration>
480 (package user coordinator systems systems-and-targets
481 guix-data-service processed-commits-file)
484 (documentation "Guix Build Coordinator queue builds from Guix Data Service")
485 (provision '(guix-build-coordinator-queue-builds))
486 (requirement '(networking))
488 #~(make-forkexec-constructor
492 "/bin/guix-build-coordinator-queue-builds-from-guix-data-service")
493 #$(string-append "--coordinator=" coordinator)
494 #$@(map (lambda (system)
495 (string-append "--system=" system))
497 #$@(map (match-lambda
499 (string-append "--system-and-target=" system "=" target)))
500 (or systems-and-targets '()))
501 #$@(if guix-data-service
502 #~(#$(string-append "--guix-data-service=" guix-data-service))
504 #$@(if processed-commits-file
505 #~(#$(string-append "--processed-commits-file="
506 processed-commits-file))
509 #:environment-variables
511 "GUIX_LOCPATH=" #$glibc-utf8-locales "/lib/locale")
513 #:log-file "/var/log/guix-build-coordinator/queue-builds.log"))
514 (stop #~(make-kill-destructor))))))
516 (define (guix-build-coordinator-queue-builds-activation config)
518 (use-modules (guix build utils))
521 (getpw #$(guix-build-coordinator-queue-builds-configuration-user
524 (mkdir-p "/var/log/guix-build-coordinator")
526 ;; Allow writing the processed commits file
527 (mkdir-p "/var/cache/guix-build-coordinator-queue-builds")
528 (chown "/var/cache/guix-build-coordinator-queue-builds"
530 (passwd:gid %user))))
532 (define (guix-build-coordinator-queue-builds-account config)
534 (name (guix-build-coordinator-queue-builds-configuration-user config))
537 (comment "Guix Build Coordinator queue-builds user")
538 (home-directory "/var/empty")
539 (shell (file-append shadow "/sbin/nologin")))))
541 (define guix-build-coordinator-queue-builds-service-type
543 (name 'guix-build-coordinator-queue-builds)
546 (service-extension shepherd-root-service-type
547 guix-build-coordinator-queue-builds-shepherd-services)
548 (service-extension activation-service-type
549 guix-build-coordinator-queue-builds-activation)
550 (service-extension account-service-type
551 guix-build-coordinator-queue-builds-account)))
553 "Run the guix-build-coordinator-queue-builds-from-guix-data-service
556 This is a script to assist in having the Guix Build Coordinator build
557 derivations stored in an instance of the Guix Data Service.")))
561 ;;; Guix Data Service
564 (define-record-type* <guix-data-service-configuration>
565 guix-data-service-configuration make-guix-data-service-configuration
566 guix-data-service-configuration?
567 (package guix-data-service-package
568 (default guix-data-service))
569 (user guix-data-service-configuration-user
570 (default "guix-data-service"))
571 (group guix-data-service-configuration-group
572 (default "guix-data-service"))
573 (port guix-data-service-port
575 (host guix-data-service-host
576 (default "127.0.0.1"))
577 (getmail-idle-mailboxes
578 guix-data-service-getmail-idle-mailboxes
580 (commits-getmail-retriever-configuration
581 guix-data-service-commits-getmail-retriever-configuration
583 (extra-options guix-data-service-extra-options
585 (extra-process-jobs-options
586 guix-data-service-extra-process-jobs-options
589 (define (guix-data-service-profile-packages config)
590 "Return the guix-data-service package, this will populate the
591 ca-certificates.crt file in the system profile."
593 (guix-data-service-package config)))
595 (define (guix-data-service-shepherd-services config)
596 (match-record config <guix-data-service-configuration>
597 (package user group port host extra-options extra-process-jobs-options)
600 (documentation "Guix Data Service web server")
601 (provision '(guix-data-service))
602 (requirement '(postgres networking))
603 (start #~(make-forkexec-constructor
604 (list #$(file-append package
605 "/bin/guix-data-service")
606 "--pid-file=/var/run/guix-data-service/pid"
607 #$(string-append "--port=" (number->string port))
608 #$(string-append "--host=" host)
609 ;; Perform any database migrations when the
610 ;; service is started
616 #:pid-file "/var/run/guix-data-service/pid"
617 ;; Allow time for migrations to run
618 #:pid-file-timeout 60
619 #:environment-variables
621 "GUIX_LOCPATH=" #$glibc-utf8-locales "/lib/locale")
622 "LC_ALL=en_US.UTF-8")
623 #:log-file "/var/log/guix-data-service/web.log"))
624 (stop #~(make-kill-destructor)))
627 (documentation "Guix Data Service process jobs")
628 (provision '(guix-data-service-process-jobs))
629 (requirement '(postgres
631 ;; Require guix-data-service, as that the database
632 ;; migrations are handled through this service
634 (start #~(make-forkexec-constructor
636 #$(file-append package
637 "/bin/guix-data-service-process-jobs")
638 #$@extra-process-jobs-options)
641 #:environment-variables
642 `("HOME=/var/lib/guix-data-service"
643 "GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt"
645 "GUIX_LOCPATH=" #$glibc-utf8-locales "/lib/locale")
646 "LC_ALL=en_US.UTF-8")
647 #:log-file "/var/log/guix-data-service/process-jobs.log"))
648 (stop #~(make-kill-destructor))))))
650 (define (guix-data-service-activation config)
652 (use-modules (guix build utils))
654 (define %user (getpw "guix-data-service"))
656 (chmod "/var/lib/guix-data-service" #o755)
658 (mkdir-p "/var/log/guix-data-service")
660 ;; Allow writing the PID file
661 (mkdir-p "/var/run/guix-data-service")
662 (chown "/var/run/guix-data-service"
664 (passwd:gid %user))))
666 (define (guix-data-service-account config)
667 (match-record config <guix-data-service-configuration>
676 (comment "Guix Data Service user")
677 (home-directory "/var/lib/guix-data-service")
678 (shell (file-append shadow "/sbin/nologin"))))))
680 (define (guix-data-service-getmail-configuration config)
682 (($ <guix-data-service-configuration> package user group
686 (($ <guix-data-service-configuration> package user group
688 getmail-idle-mailboxes
689 commits-getmail-retriever-configuration)
691 (getmail-configuration
692 (name 'guix-data-service)
695 (directory "/var/lib/getmail/guix-data-service")
697 (getmail-configuration-file
698 (retriever commits-getmail-retriever-configuration)
700 (getmail-destination-configuration
701 (type "MDA_external")
704 "/bin/guix-data-service-process-branch-updated-email"))))
706 (getmail-options-configuration
710 (idle getmail-idle-mailboxes))))))
712 (define guix-data-service-type
714 (name 'guix-data-service)
717 (service-extension profile-service-type
718 guix-data-service-profile-packages)
719 (service-extension shepherd-root-service-type
720 guix-data-service-shepherd-services)
721 (service-extension activation-service-type
722 guix-data-service-activation)
723 (service-extension account-service-type
724 guix-data-service-account)
725 (service-extension getmail-service-type
726 guix-data-service-getmail-configuration)))
728 (guix-data-service-configuration))
730 "Run an instance of the Guix Data Service.")))