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-uuid
59 guix-build-coordinator-agent-configuration-password
60 guix-build-coordinator-agent-configuration-password-file
61 guix-build-coordinator-agent-configuration-systems
62 guix-build-coordinator-agent-configuration-max-parallel-builds
63 guix-build-coordinator-agent-configuration-derivation-substitute-urls
64 guix-build-coordinator-agent-configuration-non-derivation-substitute-urls
66 guix-build-coordinator-agent-service-type
68 guix-build-coordinator-queue-builds-configuration
69 guix-build-coordinator-queue-builds-configuration?
70 guix-build-coordinator-queue-builds-configuration-package
71 guix-build-coordinator-queue-builds-configuration-user
72 guix-build-coordinator-queue-builds-coordinator
73 guix-build-coordinator-queue-builds-configuration-systems
74 guix-build-coordinator-queue-builds-configuration-system-and-targets
75 guix-build-coordinator-queue-builds-configuration-guix-data-service
76 guix-build-coordinator-queue-builds-configuration-processed-commits-file
78 guix-build-coordinator-queue-builds-service-type
80 <guix-data-service-configuration>
81 guix-data-service-configuration
82 guix-data-service-configuration?
83 guix-data-service-package
84 guix-data-service-user
85 guix-data-service-group
86 guix-data-service-port
87 guix-data-service-host
88 guix-data-service-getmail-idle-mailboxes
89 guix-data-service-commits-getmail-retriever-configuration
91 guix-data-service-type))
95 ;;; Services specifically related to GNU Guix.
99 (define-record-type* <guix-build-coordinator-configuration>
100 guix-build-coordinator-configuration make-guix-build-coordinator-configuration
101 guix-build-coordinator-configuration?
102 (package guix-build-coordinator-configuration-package
103 (default guix-build-coordinator))
104 (user guix-build-coordinator-configuration-user
105 (default "guix-build-coordinator"))
106 (group guix-build-coordinator-configuration-group
107 (default "guix-build-coordinator"))
109 guix-build-coordinator-configuration-datastore-uri-string
110 (default "sqlite:///var/lib/guix-build-coordinator/guix_build_coordinator.db"))
111 (agent-communication-uri-string
112 guix-build-coordinator-configuration-agent-communication-uri-string
113 (default "http://0.0.0.0:8745"))
114 (client-communication-uri-string
115 guix-build-coordinator-configuration-client-communication-uri-string
116 (default "http://127.0.0.1:8746"))
118 guix-build-coordinator-configuration-allocation-strategy
119 (default #~basic-build-allocation-strategy))
120 (hooks guix-build-coordinator-configuration-hooks
122 (guile guix-build-coordinator-configuration-guile
123 (default guile-3.0-latest)))
125 (define-record-type* <guix-build-coordinator-agent-configuration>
126 guix-build-coordinator-agent-configuration
127 make-guix-build-coordinator-agent-configuration
128 guix-build-coordinator-agent-configuration?
129 (package guix-build-coordinator-agent-configuration-package
130 (default guix-build-coordinator))
131 (user guix-build-coordinator-agent-configuration-user
132 (default "guix-build-coordinator-agent"))
133 (coordinator guix-build-coordinator-agent-configuration-coordinator
134 (default "http://localhost:8745"))
135 (uuid guix-build-coordinator-agent-configuration-uuid)
136 (password guix-build-coordinator-agent-configuration-password
138 (password-file guix-build-coordinator-agent-configuration-password-file
140 (systems guix-build-coordinator-agent-configuration-systems
143 guix-build-coordinator-agent-configuration-max-parallel-builds
145 (derivation-substitute-urls
146 guix-build-coordinator-agent-configuration-derivation-substitute-urls
148 (non-derivation-substitute-urls
149 guix-build-coordinator-agent-configuration-non-derivation-substitute-urls
152 (define-record-type* <guix-build-coordinator-queue-builds-configuration>
153 guix-build-coordinator-queue-builds-configuration
154 make-guix-build-coordinator-queue-builds-configuration
155 guix-build-coordinator-queue-builds-configuration?
156 (package guix-build-coordinator-queue-builds-configuration-package
157 (default guix-build-coordinator))
158 (user guix-build-coordinator-queue-builds-configuration-user
159 (default "guix-build-coordinator-queue-builds"))
160 (coordinator guix-build-coordinator-queue-builds-coordinator
161 (default "http://localhost:8745"))
162 (systems guix-build-coordinator-queue-builds-configuration-systems
165 guix-build-coordinator-queue-builds-configuration-system-and-targets
168 guix-build-coordinator-queue-builds-configuration-guix-data-service
169 (default "https://data.guix.gnu.org"))
170 (processed-commits-file
171 guix-build-coordinator-queue-builds-configuration-processed-commits-file
172 (default "/var/cache/guix-build-coordinator-queue-builds/processed-commits")))
174 (define* (make-guix-build-coordinator-start-script database-uri-string
177 guix-build-coordinator-package
179 agent-communication-uri-string
180 client-communication-uri-string
184 "start-guix-build-coordinator"
185 (with-extensions (cons guix-build-coordinator-package
186 ;; This is a poorly constructed Guile load path,
187 ;; since it contains things that aren't Guile
188 ;; libraries, but it means that the Guile libraries
189 ;; needed for the Guix Build Coordinator don't need
190 ;; to be individually specified here.
192 (map second (package-inputs
193 guix-build-coordinator-package))
194 (map second (package-propagated-inputs
195 guix-build-coordinator-package))))
197 (use-modules (srfi srfi-1)
201 (guix-build-coordinator hooks)
202 (guix-build-coordinator datastore)
203 (guix-build-coordinator build-allocator)
204 (guix-build-coordinator coordinator))
206 (setvbuf (current-output-port) 'line)
207 (setvbuf (current-error-port) 'line)
209 (simple-format #t "starting the guix-build-coordinator:\n ~A\n"
211 (let* ((metrics-registry (make-metrics-registry
213 "guixbuildcoordinator"))
214 (datastore (database-uri->datastore
215 #$database-uri-string
216 #:metrics-registry metrics-registry))
218 (list #$@(map (match-lambda
220 #~(cons '#$name #$hook-gexp)))
224 ,@(remove (match-lambda
225 ((name . _) (assq-ref hooks name)))
227 (build-coordinator (make-build-coordinator
228 #:datastore datastore
229 #:hooks hooks-with-defaults
230 #:metrics-registry metrics-registry
231 #:allocation-strategy #$allocation-strategy)))
233 (run-coordinator-service
235 #:update-datastore? #t
236 #:pid-file #$pid-file
237 #:agent-communication-uri (string->uri
238 #$agent-communication-uri-string)
239 #:client-communication-uri (string->uri
240 #$client-communication-uri-string)))))
243 (define (guix-build-coordinator-shepherd-services config)
244 (match-record config <guix-build-coordinator-configuration>
245 (package user group database-uri-string
246 agent-communication-uri-string
247 client-communication-uri-string
253 (documentation "Guix Build Coordinator")
254 (provision '(guix-build-coordinator))
255 (requirement '(networking))
256 (start #~(make-forkexec-constructor
257 (list #$(make-guix-build-coordinator-start-script
260 "/var/run/guix-build-coordinator/pid"
262 #:agent-communication-uri-string
263 agent-communication-uri-string
264 #:client-communication-uri-string
265 client-communication-uri-string
270 #:pid-file "/var/run/guix-build-coordinator/pid"
271 ;; Allow time for migrations to run
272 #:pid-file-timeout 60
273 #:environment-variables
275 "GUIX_LOCPATH=" #$glibc-utf8-locales "/lib/locale")
277 "PATH=/run/current-system/profile/bin") ; for hooks
278 #:log-file "/var/log/guix-build-coordinator/coordinator.log"))
279 (stop #~(make-kill-destructor))))))
281 (define (guix-build-coordinator-activation config)
283 (use-modules (guix build utils))
285 (define %user (getpw "guix-build-coordinator"))
287 (chmod "/var/lib/guix-build-coordinator" #o755)
289 (mkdir-p "/var/log/guix-build-coordinator")
291 ;; Allow writing the PID file
292 (mkdir-p "/var/run/guix-build-coordinator")
293 (chown "/var/run/guix-build-coordinator"
295 (passwd:gid %user))))
297 (define (guix-build-coordinator-account config)
298 (match-record config <guix-build-coordinator-configuration>
307 (comment "Guix Build Coordinator user")
308 (home-directory "/var/lib/guix-build-coordinator")
309 (shell (file-append shadow "/sbin/nologin"))))))
311 (define guix-build-coordinator-service-type
313 (name 'guix-build-coordinator)
316 (service-extension shepherd-root-service-type
317 guix-build-coordinator-shepherd-services)
318 (service-extension activation-service-type
319 guix-build-coordinator-activation)
320 (service-extension account-service-type
321 guix-build-coordinator-account)))
323 (guix-build-coordinator-configuration))
325 "Run an instance of the Guix Build Coordinator.")))
327 (define (guix-build-coordinator-agent-shepherd-services config)
328 (match-record config <guix-build-coordinator-agent-configuration>
329 (package user coordinator uuid password password-file max-parallel-builds
330 derivation-substitute-urls non-derivation-substitute-urls
334 (documentation "Guix Build Coordinator Agent")
335 (provision '(guix-build-coordinator-agent))
336 (requirement '(networking))
337 (start #~(make-forkexec-constructor
338 (list #$(file-append package "/bin/guix-build-coordinator-agent")
339 #$(string-append "--coordinator=" coordinator)
340 #$(string-append "--uuid=" uuid)
342 #~(#$(string-append "--password=" password))
345 #~(#$(string-append "--password-file=" password-file))
347 #$(simple-format #f "--max-parallel-builds=~A"
349 #$@(if derivation-substitute-urls
351 "--derivation-substitute-urls="
352 (string-join derivation-substitute-urls " ")))
354 #$@(if non-derivation-substitute-urls
356 "--non-derivation-substitute-urls="
357 (string-join non-derivation-substitute-urls " ")))
359 #$@(map (lambda (system)
360 (string-append "--system=" system))
363 #:environment-variables
365 "GUIX_LOCPATH=" #$glibc-utf8-locales "/lib/locale")
366 ;; XDG_CACHE_HOME is used by Guix when caching narinfo files
367 "XDG_CACHE_HOME=/var/cache/guix-build-coordinator-agent"
369 #:log-file "/var/log/guix-build-coordinator/agent.log"))
370 (stop #~(make-kill-destructor))))))
372 (define (guix-build-coordinator-agent-activation config)
374 (use-modules (guix build utils))
376 (define %user (getpw "guix-build-coordinator-agent"))
378 (mkdir-p "/var/log/guix-build-coordinator")
380 ;; Create a cache directory for storing narinfo files if downloaded
381 (mkdir-p "/var/cache/guix-build-coordinator-agent")
382 (chown "/var/cache/guix-build-coordinator-agent"
384 (passwd:gid %user))))
386 (define (guix-build-coordinator-agent-account config)
388 (name (guix-build-coordinator-agent-configuration-user config))
391 (comment "Guix Build Coordinator agent user")
392 (home-directory "/var/empty")
393 (shell (file-append shadow "/sbin/nologin")))))
395 (define guix-build-coordinator-agent-service-type
397 (name 'guix-build-coordinator-agent)
400 (service-extension shepherd-root-service-type
401 guix-build-coordinator-agent-shepherd-services)
402 (service-extension activation-service-type
403 guix-build-coordinator-agent-activation)
404 (service-extension account-service-type
405 guix-build-coordinator-agent-account)))
407 "Run a Guix Build Coordinator agent.")))
409 (define (guix-build-coordinator-queue-builds-shepherd-services config)
410 (match-record config <guix-build-coordinator-queue-builds-configuration>
411 (package user coordinator systems systems-and-targets
412 guix-data-service processed-commits-file)
415 (documentation "Guix Build Coordinator queue builds from Guix Data Service")
416 (provision '(guix-build-coordinator-queue-builds))
417 (requirement '(networking))
419 #~(make-forkexec-constructor
423 "/bin/guix-build-coordinator-queue-builds-from-guix-data-service")
424 #$(string-append "--coordinator=" coordinator)
425 #$@(map (lambda (system)
426 (string-append "--system=" system))
428 #$@(map (match-lambda
430 (string-append "--system-and-target=" system "=" target)))
431 (or systems-and-targets '()))
432 #$@(if guix-data-service
433 #~(#$(string-append "--guix-data-service=" guix-data-service))
435 #$@(if processed-commits-file
436 #~(#$(string-append "--processed-commits-file="
437 processed-commits-file))
440 #:pid-file "/var/run/guix-build-coordinator-queue-builds/pid"
441 #:environment-variables
443 "GUIX_LOCPATH=" #$glibc-utf8-locales "/lib/locale")
445 #:log-file "/var/log/guix-build-coordinator/queue-builds.log"))
446 (stop #~(make-kill-destructor))))))
448 (define (guix-build-coordinator-queue-builds-activation config)
450 (use-modules (guix build utils))
452 (mkdir-p "/var/log/guix-build-coordinator")
454 ;; Allow writing the PID file
455 (mkdir-p "/var/run/guix-build-coordinator-queue-builds")
456 (chown "/var/run/guix-build-coordinator-queue-builds"
458 (passwd:gid %user))))
460 (define (guix-build-coordinator-queue-builds-account config)
462 (name (guix-build-coordinator-queue-builds-configuration-user config))
465 (comment "Guix Build Coordinator queue-builds user")
466 (home-directory "/var/empty")
467 (shell (file-append shadow "/sbin/nologin")))))
469 (define guix-build-coordinator-queue-builds-service-type
471 (name 'guix-build-coordinator-queue-builds)
474 (service-extension shepherd-root-service-type
475 guix-build-coordinator-queue-builds-shepherd-services)
476 (service-extension activation-service-type
477 guix-build-coordinator-queue-builds-activation)
478 (service-extension account-service-type
479 guix-build-coordinator-queue-builds-account)))
481 "Run the guix-build-coordinator-queue-builds-from-guix-data-service
484 This is a script to assist in having the Guix Build Coordinator build
485 derivations stored in an instance of the Guix Data Service.")))
489 ;;; Guix Data Service
492 (define-record-type* <guix-data-service-configuration>
493 guix-data-service-configuration make-guix-data-service-configuration
494 guix-data-service-configuration?
495 (package guix-data-service-package
496 (default guix-data-service))
497 (user guix-data-service-configuration-user
498 (default "guix-data-service"))
499 (group guix-data-service-configuration-group
500 (default "guix-data-service"))
501 (port guix-data-service-port
503 (host guix-data-service-host
504 (default "127.0.0.1"))
505 (getmail-idle-mailboxes
506 guix-data-service-getmail-idle-mailboxes
508 (commits-getmail-retriever-configuration
509 guix-data-service-commits-getmail-retriever-configuration
511 (extra-options guix-data-service-extra-options
513 (extra-process-jobs-options
514 guix-data-service-extra-process-jobs-options
517 (define (guix-data-service-profile-packages config)
518 "Return the guix-data-service package, this will populate the
519 ca-certificates.crt file in the system profile."
521 (guix-data-service-package config)))
523 (define (guix-data-service-shepherd-services config)
524 (match-record config <guix-data-service-configuration>
525 (package user group port host extra-options extra-process-jobs-options)
528 (documentation "Guix Data Service web server")
529 (provision '(guix-data-service))
530 (requirement '(postgres networking))
531 (start #~(make-forkexec-constructor
532 (list #$(file-append package
533 "/bin/guix-data-service")
534 "--pid-file=/var/run/guix-data-service/pid"
535 #$(string-append "--port=" (number->string port))
536 #$(string-append "--host=" host)
537 ;; Perform any database migrations when the
538 ;; service is started
544 #:pid-file "/var/run/guix-data-service/pid"
545 ;; Allow time for migrations to run
546 #:pid-file-timeout 60
547 #:environment-variables
549 "GUIX_LOCPATH=" #$glibc-utf8-locales "/lib/locale")
550 "LC_ALL=en_US.UTF-8")
551 #:log-file "/var/log/guix-data-service/web.log"))
552 (stop #~(make-kill-destructor)))
555 (documentation "Guix Data Service process jobs")
556 (provision '(guix-data-service-process-jobs))
557 (requirement '(postgres
559 ;; Require guix-data-service, as that the database
560 ;; migrations are handled through this service
562 (start #~(make-forkexec-constructor
564 #$(file-append package
565 "/bin/guix-data-service-process-jobs")
566 #$@extra-process-jobs-options)
569 #:environment-variables
570 `("HOME=/var/lib/guix-data-service"
571 "GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt"
573 "GUIX_LOCPATH=" #$glibc-utf8-locales "/lib/locale")
574 "LC_ALL=en_US.UTF-8")
575 #:log-file "/var/log/guix-data-service/process-jobs.log"))
576 (stop #~(make-kill-destructor))))))
578 (define (guix-data-service-activation config)
580 (use-modules (guix build utils))
582 (define %user (getpw "guix-data-service"))
584 (chmod "/var/lib/guix-data-service" #o755)
586 (mkdir-p "/var/log/guix-data-service")
588 ;; Allow writing the PID file
589 (mkdir-p "/var/run/guix-data-service")
590 (chown "/var/run/guix-data-service"
592 (passwd:gid %user))))
594 (define (guix-data-service-account config)
595 (match-record config <guix-data-service-configuration>
604 (comment "Guix Data Service user")
605 (home-directory "/var/lib/guix-data-service")
606 (shell (file-append shadow "/sbin/nologin"))))))
608 (define (guix-data-service-getmail-configuration config)
610 (($ <guix-data-service-configuration> package user group
614 (($ <guix-data-service-configuration> package user group
616 getmail-idle-mailboxes
617 commits-getmail-retriever-configuration)
619 (getmail-configuration
620 (name 'guix-data-service)
623 (directory "/var/lib/getmail/guix-data-service")
625 (getmail-configuration-file
626 (retriever commits-getmail-retriever-configuration)
628 (getmail-destination-configuration
629 (type "MDA_external")
632 "/bin/guix-data-service-process-branch-updated-email"))))
634 (getmail-options-configuration
638 (idle getmail-idle-mailboxes))))))
640 (define guix-data-service-type
642 (name 'guix-data-service)
645 (service-extension profile-service-type
646 guix-data-service-profile-packages)
647 (service-extension shepherd-root-service-type
648 guix-data-service-shepherd-services)
649 (service-extension activation-service-type
650 guix-data-service-activation)
651 (service-extension account-service-type
652 guix-data-service-account)
653 (service-extension getmail-service-type
654 guix-data-service-getmail-configuration)))
656 (guix-data-service-configuration))
658 "Run an instance of the Guix Data Service.")))