projects/guix·blob python-team · refs

1316 lines · 54.7 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2019, 2020, 2021, 2022 Christopher Baines <[email protected]>
3;;; Copyright © 2024 Andrew Tropin <[email protected]>
4;;; Copyright © 2025 Edouard Klein <[email protected]>
5;;; Copyright © 2025 Rutherther <[email protected]>
6;;;
7;;; This file is part of GNU Guix.
8;;;
9;;; GNU Guix is free software; you can redistribute it and/or modify
10;;; it under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation, either version 3 of the License, or
12;;; (at your option) any later version.
13;;;
14;;; GNU Guix is distributed in the hope that it will be useful,
15;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
21
22;;;; Commentary:
23;;;
24;;; Services specifically related to GNU Guix.
25;;;
26;;;; Code:
27
28(define-module (gnu services guix)
29 #:use-module (srfi srfi-1)
30 #:use-module (ice-9 match)
31 #:use-module (guix gexp)
32 #:use-module (guix records)
33 #:use-module (guix packages)
34 #:use-module ((gnu packages base)
35 #:select (libc-utf8-locales-for-target))
36 #:use-module (gnu packages admin)
37 #:use-module (gnu packages databases)
38 #:use-module (gnu packages web)
39 #:use-module (gnu packages guile)
40 #:use-module (gnu packages guile-xyz)
41 #:use-module (gnu packages package-management)
42 #:use-module (gnu packages file-systems)
43 #:use-module (gnu packages linux)
44 #:use-module (gnu services)
45 #:use-module (gnu services base)
46 #:use-module (gnu services admin)
47 #:use-module (gnu services configuration)
48 #:use-module (gnu services shepherd)
49 #:use-module (gnu services getmail)
50 #:use-module (gnu services linux)
51 #:use-module (gnu system shadow)
52 #:export (guix-build-coordinator-configuration
53 guix-build-coordinator-configuration?
54 guix-build-coordinator-configuration-package
55 guix-build-coordinator-configuration-user
56 guix-build-coordinator-configuration-group
57 guix-build-coordinator-configuration-datastore-uri-string
58 guix-build-coordinator-configuration-agent-communication-uri-string
59 guix-build-coordinator-configuration-client-communication-uri-string
60 guix-build-coordinator-configuration-allocation-strategy
61 guix-build-coordinator-configuration-hooks
62 guix-build-coordinator-configuration-parallel-hooks
63 guix-build-coordinator-configuration-listen-repl
64 guix-build-coordinator-configuration-guile
65 guix-build-coordinator-configuration-extra-environment-variables
66 guix-build-coordinator-configuration-extra-build-coordinator-arguments
67
68 guix-build-coordinator-service-type
69
70 guix-build-coordinator-agent-configuration
71 guix-build-coordinator-agent-configuration?
72 guix-build-coordinator-agent-configuration-package
73 guix-build-coordinator-agent-configuration-user
74 guix-build-coordinator-agent-configuration-coordinator
75 guix-build-coordinator-agent-configuration-authentication
76 guix-build-coordinator-agent-configuration-systems
77 guix-build-coordinator-agent-configuration-max-parallel-builds
78 guix-build-coordinator-agent-configuration-max-parallel-uploads
79 guix-build-coordinator-agent-configuration-max-allocated-builds
80 guix-build-coordinator-agent-configuration-max-1min-load-average
81 guix-build-coordinator-agent-configuration-derivation-substitute-urls
82 guix-build-coordinator-agent-configuration-non-derivation-substitute-urls
83 guix-build-coordinator-agent-configuration-extra-options
84
85 guix-build-coordinator-agent-password-auth
86 guix-build-coordinator-agent-password-auth?
87 guix-build-coordinator-agent-password-auth-uuid
88 guix-build-coordinator-agent-password-auth-password
89
90 guix-build-coordinator-agent-password-file-auth
91 guix-build-coordinator-agent-password-file-auth?
92 guix-build-coordinator-agent-password-file-auth-uuid
93 guix-build-coordinator-agent-password-file-auth-password-file
94
95 guix-build-coordinator-agent-dynamic-auth
96 guix-build-coordinator-agent-dynamic-auth?
97 guix-build-coordinator-agent-dynamic-auth-agent-name
98 guix-build-coordinator-agent-dynamic-auth-token
99
100 guix-build-coordinator-agent-dynamic-auth-with-file
101 guix-build-coordinator-agent-dynamic-auth-with-file?
102 guix-build-coordinator-agent-dynamic-auth-with-file-agent-name
103 guix-build-coordinator-agent-dynamic-auth-with-file-token-file
104
105 guix-build-coordinator-agent-service-type
106
107 <guix-data-service-configuration>
108 guix-data-service-configuration
109 guix-data-service-configuration?
110 guix-data-service-package
111 guix-data-service-user
112 guix-data-service-group
113 guix-data-service-port
114 guix-data-service-host
115 guix-data-service-getmail-idle-mailboxes
116 guix-data-service-commits-getmail-retriever-configuration
117 guix-data-service-extra-options
118 guix-data-service-extra-process-jobs-options
119 guix-data-service-extra-environment-variables
120 guix-data-service-extra-process-jobs-environment-variables
121 guix-data-service-configuration-git-repositories
122 guix-data-service-configuration-build-servers
123
124 guix-data-service-type
125
126 guix-home-service-type
127
128 nar-herder-service-type
129 nar-herder-configuration
130 nar-herder-configuration?
131 nar-herder-configuration-package
132 nar-herder-configuration-user
133 nar-herder-configuration-group
134 nar-herder-configuration-mirror
135 nar-herder-configuration-database
136 nar-herder-configuration-database-dump
137 nar-herder-configuration-host
138 nar-herder-configuration-port
139 nar-herder-configuration-control-host
140 nar-herder-configuration-control-port
141 nar-herder-configuration-storage
142 nar-herder-configuration-storage-limit
143 nar-herder-configuration-storage-minimum-free-space
144 nar-herder-configuration-storage-nar-removal-criteria
145 nar-herder-configuration-log-level
146 nar-herder-configuration-cached-compressions
147 nar-herder-configuration-cached-compression-min-uses
148 nar-herder-configuration-cached-compression-workers
149 nar-herder-configuration-cached-compression-nar-source
150 nar-herder-configuration-extra-options
151 nar-herder-configuration-extra-environment-variables
152
153 nar-herder-cached-compression-configuration
154 nar-herder-cached-compression-configuration?
155 nar-herder-cached-compression-configuration-type
156 nar-herder-cached-compression-configuration-level
157 nar-herder-cached-compression-configuration-directory
158 nar-herder-cached-compression-configuration-directory-max-size
159
160 bffe-configuration
161 bffe-configuration?
162 bffe-configuration-package
163 bffe-configuration-user
164 bffe-configuration-group
165 bffe-configuration-arguments
166 bffe-configuration-extra-environment-variables
167
168 bffe-service-type
169
170 shared-cache-service-type
171 shared-cache-configuration
172 user-cache))
173
174(define-record-type* <guix-build-coordinator-configuration>
175 guix-build-coordinator-configuration make-guix-build-coordinator-configuration
176 guix-build-coordinator-configuration?
177 (package guix-build-coordinator-configuration-package
178 (default guix-build-coordinator))
179 (user guix-build-coordinator-configuration-user
180 (default "guix-build-coordinator"))
181 (group guix-build-coordinator-configuration-group
182 (default "guix-build-coordinator"))
183 (database-uri-string
184 guix-build-coordinator-configuration-datastore-uri-string
185 (default "sqlite:///var/lib/guix-build-coordinator/guix_build_coordinator.db"))
186 (agent-communication-uri-string
187 guix-build-coordinator-configuration-agent-communication-uri-string
188 (default "http://0.0.0.0:8745"))
189 (client-communication-uri-string
190 guix-build-coordinator-configuration-client-communication-uri-string
191 (default "http://127.0.0.1:8746"))
192 (allocation-strategy
193 guix-build-coordinator-configuration-allocation-strategy
194 (default #~basic-build-allocation-strategy))
195 (hooks guix-build-coordinator-configuration-hooks
196 (default '()))
197 (parallel-hooks guix-build-coordinator-configuration-parallel-hooks
198 (default '()))
199 (listen-repl guix-build-coordinator-configuration-listen-repl
200 (default #f))
201 (guile guix-build-coordinator-configuration-guile
202 (default guile-3.0-latest))
203 (extra-environment-variables
204 guix-build-coordinator-configuration-extra-environment-variables
205 (default '()))
206 (extra-build-coordinator-arguments
207 guix-build-coordinator-configuration-extra-build-coordinator-arguments
208 (default '())))
209
210(define-record-type* <guix-build-coordinator-agent-configuration>
211 guix-build-coordinator-agent-configuration
212 make-guix-build-coordinator-agent-configuration
213 guix-build-coordinator-agent-configuration?
214 (package guix-build-coordinator-agent-configuration-package
215 (default guix-build-coordinator/agent-only))
216 (user guix-build-coordinator-agent-configuration-user
217 (default "guix-build-coordinator-agent"))
218 (coordinator guix-build-coordinator-agent-configuration-coordinator
219 (default "http://localhost:8745"))
220 (authentication guix-build-coordinator-agent-configuration-authentication)
221 (systems guix-build-coordinator-agent-configuration-systems
222 (default #f))
223 (max-parallel-builds
224 guix-build-coordinator-agent-configuration-max-parallel-builds
225 (default #f))
226 (max-parallel-uploads
227 guix-build-coordinator-agent-configuration-max-parallel-uploads
228 (default #f))
229 (max-allocated-builds
230 guix-build-coordinator-agent-configuration-max-allocated-builds
231 (default #f))
232 (max-1min-load-average
233 guix-build-coordinator-agent-configuration-max-1min-load-average
234 (default #f))
235 (derivation-substitute-urls
236 guix-build-coordinator-agent-configuration-derivation-substitute-urls
237 (default #f))
238 (non-derivation-substitute-urls
239 guix-build-coordinator-agent-configuration-non-derivation-substitute-urls
240 (default #f))
241 (extra-options
242 guix-build-coordinator-agent-configuration-extra-options
243 (default '())))
244
245(define-record-type* <guix-build-coordinator-agent-password-auth>
246 guix-build-coordinator-agent-password-auth
247 make-guix-build-coordinator-agent-password-auth
248 guix-build-coordinator-agent-password-auth?
249 (uuid guix-build-coordinator-agent-password-auth-uuid)
250 (password guix-build-coordinator-agent-password-auth-password))
251
252(define-record-type* <guix-build-coordinator-agent-password-file-auth>
253 guix-build-coordinator-agent-password-file-auth
254 make-guix-build-coordinator-agent-password-file-auth
255 guix-build-coordinator-agent-password-file-auth?
256 (uuid guix-build-coordinator-agent-password-file-auth-uuid)
257 (password-file
258 guix-build-coordinator-agent-password-file-auth-password-file))
259
260(define-record-type* <guix-build-coordinator-agent-dynamic-auth>
261 guix-build-coordinator-agent-dynamic-auth
262 make-guix-build-coordinator-agent-dynamic-auth
263 guix-build-coordinator-agent-dynamic-auth?
264 (agent-name guix-build-coordinator-agent-dynamic-auth-agent-name)
265 (token guix-build-coordinator-agent-dynamic-auth-token))
266
267(define-record-type* <guix-build-coordinator-agent-dynamic-auth-with-file>
268 guix-build-coordinator-agent-dynamic-auth-with-file
269 make-guix-build-coordinator-agent-dynamic-auth-with-file
270 guix-build-coordinator-agent-dynamic-auth-with-file?
271 (agent-name guix-build-coordinator-agent-dynamic-auth-with-file-agent-name)
272 (token-file guix-build-coordinator-agent-dynamic-auth-with-file-token-file))
273
274(define* (make-guix-build-coordinator-start-script database-uri-string
275 allocation-strategy
276 pid-file
277 guix-build-coordinator-package
278 #:key
279 agent-communication-uri-string
280 client-communication-uri-string
281 (hooks '())
282 (parallel-hooks '())
283 (guile guile-3.0-latest)
284 listen-repl
285 (extra-build-coordinator-arguments
286 '()))
287 (program-file
288 "start-guix-build-coordinator"
289 (with-extensions (cons guix-build-coordinator-package
290 ;; This is a poorly constructed Guile load path,
291 ;; since it contains things that aren't Guile
292 ;; libraries, but it means that the Guile libraries
293 ;; needed for the Guix Build Coordinator don't need
294 ;; to be individually specified here.
295 (append
296 (map second (package-inputs
297 guix-build-coordinator-package))
298 (map second (package-propagated-inputs
299 guix-build-coordinator-package))))
300 #~(begin
301 (use-modules (srfi srfi-1)
302 (ice-9 match)
303 (web uri)
304 (prometheus)
305 (guix-build-coordinator hooks)
306 (guix-build-coordinator datastore)
307 (guix-build-coordinator build-allocator)
308 (guix-build-coordinator coordinator))
309
310 (simple-format #t "starting the guix-build-coordinator:\n ~A\n"
311 (current-filename))
312 (let* ((hooks
313 (list #$@(map (match-lambda
314 ((name . hook-gexp)
315 #~(cons '#$name #$hook-gexp)))
316 hooks)))
317 (hooks-with-defaults
318 `(,@hooks
319 ,@(remove (match-lambda
320 ((name . _) (assq-ref hooks name)))
321 %default-hooks)))
322 (build-coordinator (make-build-coordinator
323 #:database-uri-string #$database-uri-string
324 #:hooks hooks-with-defaults
325 #:allocation-strategy #$allocation-strategy
326 #:timestamp-log-output? #f
327 #$@extra-build-coordinator-arguments)))
328
329 (run-coordinator-service
330 build-coordinator
331 #:update-datastore? #t
332 #:pid-file #$pid-file
333 #:agent-communication-uri (string->uri
334 #$agent-communication-uri-string)
335 #:client-communication-uri (string->uri
336 #$client-communication-uri-string)
337 #:parallel-hooks (list #$@(map (match-lambda
338 ((name . val)
339 #~(cons '#$name #$val)))
340 parallel-hooks))
341 #:listen-repl #$listen-repl))))
342 #:guile guile))
343
344(define (guix-build-coordinator-shepherd-services config)
345 (match-record config <guix-build-coordinator-configuration>
346 (package user group database-uri-string
347 agent-communication-uri-string
348 client-communication-uri-string
349 allocation-strategy
350 hooks
351 parallel-hooks
352 listen-repl
353 guile
354 extra-environment-variables
355 extra-build-coordinator-arguments)
356 (list
357 (shepherd-service
358 (documentation "Guix Build Coordinator")
359 (provision '(guix-build-coordinator))
360 (requirement '(user-processes networking))
361 (start #~(lambda args
362 (parameterize ((%current-logfile-date-format ""))
363 (apply
364 (make-forkexec-constructor
365 (list #$(make-guix-build-coordinator-start-script
366 database-uri-string
367 allocation-strategy
368 "/var/run/guix-build-coordinator/pid"
369 package
370 #:agent-communication-uri-string
371 agent-communication-uri-string
372 #:client-communication-uri-string
373 client-communication-uri-string
374 #:hooks hooks
375 #:parallel-hooks parallel-hooks
376 #:listen-repl listen-repl
377 #:guile guile
378 #:extra-build-coordinator-arguments
379 extra-build-coordinator-arguments))
380 #:user #$user
381 #:group #$group
382 #:directory "/var/lib/guix-build-coordinator"
383 #:pid-file "/var/run/guix-build-coordinator/pid"
384 ;; Allow time for migrations to run
385 #:pid-file-timeout 240
386 #:environment-variables
387 `("LC_ALL=en_US.utf8"
388 "PATH=/run/current-system/profile/bin" ; for hooks
389 #$@extra-environment-variables)
390 #:log-file "/var/log/guix-build-coordinator/coordinator.log")
391 args))))
392 (stop #~(make-kill-destructor))
393 (modules
394 `((shepherd comm)
395 ,@%default-modules))))))
396
397(define (guix-build-coordinator-activation config)
398 #~(begin
399 (use-modules (guix build utils))
400
401 (define %user
402 (getpw #$(guix-build-coordinator-configuration-user
403 config)))
404
405 (chmod "/var/lib/guix-build-coordinator" #o755)
406
407 (mkdir-p "/var/log/guix-build-coordinator")
408
409 ;; Allow writing the PID file
410 (mkdir-p "/var/run/guix-build-coordinator")
411 (chown "/var/run/guix-build-coordinator"
412 (passwd:uid %user)
413 (passwd:gid %user))))
414
415(define (guix-build-coordinator-account config)
416 (match-record config <guix-build-coordinator-configuration>
417 (user group)
418 (list (user-group
419 (name group)
420 (system? #t))
421 (user-account
422 (name user)
423 (group group)
424 (system? #t)
425 (comment "Guix Build Coordinator user")
426 (home-directory "/var/lib/guix-build-coordinator")
427 (shell (file-append shadow "/sbin/nologin"))))))
428
429(define guix-build-coordinator-service-type
430 (service-type
431 (name 'guix-build-coordinator)
432 (extensions
433 (list
434 (service-extension shepherd-root-service-type
435 guix-build-coordinator-shepherd-services)
436 (service-extension activation-service-type
437 guix-build-coordinator-activation)
438 (service-extension account-service-type
439 guix-build-coordinator-account)))
440 (default-value
441 (guix-build-coordinator-configuration))
442 (description
443 "Run an instance of the Guix Build Coordinator.")))
444
445(define (guix-build-coordinator-agent-shepherd-services config)
446 (match-record config <guix-build-coordinator-agent-configuration>
447 (package user coordinator authentication
448 max-parallel-builds max-parallel-uploads
449 max-allocated-builds max-1min-load-average
450 derivation-substitute-urls non-derivation-substitute-urls
451 extra-options
452 systems)
453 (list
454 (shepherd-service
455 (documentation "Guix Build Coordinator Agent")
456 (provision '(guix-build-coordinator-agent))
457 (requirement '(networking user-processes))
458 (start
459 #~(lambda _
460 (parameterize ((%current-logfile-date-format ""))
461 (fork+exec-command
462 (list #$(file-append package "/bin/guix-build-coordinator-agent")
463 #$(string-append "--coordinator=" coordinator)
464 "--timestamp-log-output=false"
465 #$@(match authentication
466 (($ <guix-build-coordinator-agent-password-auth>
467 uuid password)
468 #~(#$(string-append "--uuid=" uuid)
469 #$(string-append "--password=" password)))
470 (($ <guix-build-coordinator-agent-password-file-auth>
471 uuid password-file)
472 #~(#$(string-append "--uuid=" uuid)
473 #$(string-append "--password-file="
474 password-file)))
475 (($ <guix-build-coordinator-agent-dynamic-auth>
476 agent-name token)
477 #~(#$(string-append "--name=" agent-name)
478 #$(string-append "--dynamic-auth-token=" token)))
479 (($
480 <guix-build-coordinator-agent-dynamic-auth-with-file>
481 agent-name token-file)
482 #~(#$(string-append "--name=" agent-name)
483 #$(string-append "--dynamic-auth-token-file="
484 token-file))))
485 #$@(if max-parallel-builds
486 #~(#$(simple-format #f "--max-parallel-builds=~A"
487 max-parallel-builds))
488 #~())
489 #$@(if max-parallel-uploads
490 #~(#$(simple-format #f "--max-parallel-uploads=~A"
491 max-parallel-uploads))
492 #~())
493 #$@(if max-allocated-builds
494 #~(#$(simple-format #f "--max-allocated-builds=~A"
495 max-allocated-builds))
496 #~())
497 #$@(if max-1min-load-average
498 #~(#$(simple-format #f "--max-1min-load-average=~A"
499 max-1min-load-average))
500 #~())
501 #$@(if derivation-substitute-urls
502 #~(#$(string-append
503 "--derivation-substitute-urls="
504 (string-join derivation-substitute-urls " ")))
505 #~())
506 #$@(if non-derivation-substitute-urls
507 #~(#$(string-append
508 "--non-derivation-substitute-urls="
509 (string-join non-derivation-substitute-urls " ")))
510 #~())
511 #$@extra-options
512 #$@(map (lambda (system)
513 (string-append "--system=" system))
514 (or systems '())))
515 #:user #$user
516 #:environment-variables
517 `(;; XDG_CACHE_HOME is used by Guix when caching narinfo files
518 "XDG_CACHE_HOME=/var/cache/guix-build-coordinator-agent"
519 "LC_ALL=en_US.utf8")
520 #:directory "/var/lib/guix-build-coordinator-agent"
521 #:log-file "/var/log/guix-build-coordinator/agent.log"))))
522 (stop #~(make-kill-destructor))
523 (modules
524 `((shepherd comm)
525 ,@%default-modules))))))
526
527(define (guix-build-coordinator-agent-activation config)
528 #~(begin
529 (use-modules (guix build utils))
530
531 (define %user
532 (getpw #$(guix-build-coordinator-agent-configuration-user
533 config)))
534
535 (mkdir-p "/var/log/guix-build-coordinator")
536
537 ;; Create the home directory
538 (mkdir-p "/var/lib/guix-build-coordinator-agent")
539 (chown "/var/lib/guix-build-coordinator-agent"
540 (passwd:uid %user)
541 (passwd:gid %user))
542
543 ;; Create a cache directory for storing narinfo files if downloaded
544 (mkdir-p "/var/cache/guix-build-coordinator-agent")
545 (chown "/var/cache/guix-build-coordinator-agent"
546 (passwd:uid %user)
547 (passwd:gid %user))))
548
549(define (guix-build-coordinator-agent-account config)
550 (list (user-account
551 (name (guix-build-coordinator-agent-configuration-user config))
552 (group "nogroup")
553 (system? #t)
554 (comment "Guix Build Coordinator agent user")
555 (home-directory "/var/lib/guix-build-coordinator-agent")
556 (shell (file-append shadow "/sbin/nologin")))))
557
558(define guix-build-coordinator-agent-service-type
559 (service-type
560 (name 'guix-build-coordinator-agent)
561 (extensions
562 (list
563 (service-extension shepherd-root-service-type
564 guix-build-coordinator-agent-shepherd-services)
565 (service-extension activation-service-type
566 guix-build-coordinator-agent-activation)
567 (service-extension account-service-type
568 guix-build-coordinator-agent-account)))
569 (description
570 "Run a Guix Build Coordinator agent.")))
571
572
573;;;
574;;; Guix Data Service
575;;;
576
577(define-record-type* <guix-data-service-configuration>
578 guix-data-service-configuration make-guix-data-service-configuration
579 guix-data-service-configuration?
580 (package guix-data-service-package
581 (default guix-data-service))
582 (user guix-data-service-configuration-user
583 (default "guix-data-service"))
584 (group guix-data-service-configuration-group
585 (default "guix-data-service"))
586 (port guix-data-service-port
587 (default 8765))
588 (host guix-data-service-host
589 (default "127.0.0.1"))
590 (getmail-idle-mailboxes
591 guix-data-service-getmail-idle-mailboxes
592 (default #f))
593 (commits-getmail-retriever-configuration
594 guix-data-service-commits-getmail-retriever-configuration
595 (default #f))
596 (extra-options guix-data-service-extra-options
597 (default '()))
598 (extra-process-jobs-options
599 guix-data-service-extra-process-jobs-options
600 (default '()))
601 (extra-environment-variables
602 guix-data-service-extra-environment-variables
603 (default '()))
604 (extra-process-jobs-environment-variables
605 guix-data-service-extra-process-jobs-environment-variables
606 (default '()))
607 (git-repositories guix-data-service-configuration-git-repositories
608 (default #f))
609 (build-servers guix-data-service-configuration-build-servers
610 (default #f)))
611
612(define (guix-data-service-profile-packages config)
613 "Return the guix-data-service package, this will populate the
614ca-certificates.crt file in the system profile."
615 (list
616 (guix-data-service-package config)))
617
618(define (guix-data-service-shepherd-services config)
619 (match-record config <guix-data-service-configuration>
620 (package user group port host extra-options extra-process-jobs-options
621 extra-environment-variables
622 extra-process-jobs-environment-variables
623 git-repositories build-servers)
624 (list
625 (shepherd-service
626 (documentation "Guix Data Service web server")
627 (provision '(guix-data-service))
628 (requirement '(user-processes postgres networking))
629 (start #~(make-forkexec-constructor
630 (list #$(file-append package
631 "/bin/guix-data-service")
632 "--pid-file=/var/run/guix-data-service/pid"
633 #$(string-append "--port=" (number->string port))
634 #$(string-append "--host=" host)
635 ;; Perform any database migrations when the
636 ;; service is started
637 "--update-database"
638 #$@extra-options)
639
640 #:user #$user
641 #:group #$group
642 #:directory "/var/lib/guix-data-service"
643 #:pid-file "/var/run/guix-data-service/pid"
644 #:environment-variables
645 `(,(string-append
646 "GUIX_LOCPATH="
647 #$(libc-utf8-locales-for-target) "/lib/locale")
648 "LC_ALL=en_US.UTF-8"
649 #$@extra-environment-variables)
650 #:log-file "/var/log/guix-data-service/web.log"))
651 (stop #~(make-kill-destructor)))
652
653 (shepherd-service
654 (documentation "Guix Data Service setup database")
655 (provision '(guix-data-service-setup-database))
656 (requirement '(user-processes postgres))
657 (one-shot? #t)
658 (start
659 #~(make-forkexec-constructor
660 (list
661 #$(program-file
662 "data-service-setup-database"
663 (with-extensions
664 (cons package
665 ;; This is a poorly constructed Guile load path, since
666 ;; it contains things that aren't Guile libraries, but
667 ;; it means that the Guile libraries needed for the
668 ;; Guix Data Service don't need to be individually
669 ;; specified here.
670 (append
671 (map second (package-inputs package))
672 (map second (package-propagated-inputs package))))
673 #~(begin
674 (use-modules (guix-data-service database)
675 (guix-data-service model git-repository)
676 (guix-data-service model build-server))
677
678 (simple-format #t "data-service-setup-database: ~A\n"
679 (current-filename))
680 (begin
681 ((@ (guix-data-service database) run-sqitch))
682
683 #$@(if git-repositories
684 #~(((@ (guix-data-service model git-repository)
685 specify-git-repositories)
686 '(#$@git-repositories)))
687 '())
688 #$@(if build-servers
689 #~(((@ (guix-data-service model build-server)
690 specify-build-servers)
691 '(#$@build-servers)))
692 '()))))
693 #:guile (lookup-package-input package "guile")))
694 #:user #$user
695 #:group #$group
696 #:directory "/var/lib/guix-data-service"
697 #:environment-variables
698 `(,(string-append
699 "GUIX_LOCPATH="
700 #$(libc-utf8-locales-for-target) "/lib/locale")
701 "LC_ALL=en_US.utf8"
702 #$@extra-environment-variables)
703 #:log-file "/var/log/guix-data-service/setup-database.log"))
704 (auto-start? #t))
705
706 (shepherd-service
707 (documentation "Guix Data Service process jobs")
708 (provision '(guix-data-service-process-jobs))
709 (requirement '(user-processes postgres networking))
710 (start #~(make-forkexec-constructor
711 (list
712 #$(file-append package
713 "/bin/guix-data-service-process-jobs")
714 #$@extra-process-jobs-options)
715 #:user #$user
716 #:group #$group
717 #:directory "/var/lib/guix-data-service"
718 #:environment-variables
719 `("HOME=/var/lib/guix-data-service"
720 "GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt"
721 ,(string-append
722 "GUIX_LOCPATH="
723 #$(libc-utf8-locales-for-target) "/lib/locale")
724 "LC_ALL=en_US.UTF-8"
725 #$@extra-process-jobs-environment-variables)
726 #:log-file "/var/log/guix-data-service/process-jobs.log"))
727 (stop #~(make-kill-destructor))))))
728
729(define (guix-data-service-activation config)
730 #~(begin
731 (use-modules (guix build utils))
732
733 (define %user (getpw "guix-data-service"))
734
735 (chmod "/var/lib/guix-data-service" #o755)
736
737 (mkdir-p "/var/log/guix-data-service")
738
739 ;; Allow writing the PID file
740 (mkdir-p "/var/run/guix-data-service")
741 (chown "/var/run/guix-data-service"
742 (passwd:uid %user)
743 (passwd:gid %user))))
744
745(define (guix-data-service-account config)
746 (match-record config <guix-data-service-configuration>
747 (user group)
748 (list (user-group
749 (name group)
750 (system? #t))
751 (user-account
752 (name user)
753 (group group)
754 (system? #t)
755 (comment "Guix Data Service user")
756 (home-directory "/var/lib/guix-data-service")
757 (shell (file-append shadow "/sbin/nologin"))))))
758
759(define (guix-data-service-getmail-configuration config)
760 (match config
761 (($ <guix-data-service-configuration> package user group
762 port host
763 #f #f)
764 '())
765 (($ <guix-data-service-configuration> package user group
766 port host
767 getmail-idle-mailboxes
768 commits-getmail-retriever-configuration)
769 (list
770 (getmail-configuration
771 (name 'guix-data-service)
772 (user user)
773 (group group)
774 (directory "/var/lib/getmail/guix-data-service")
775 (rcfile
776 (getmail-configuration-file
777 (retriever commits-getmail-retriever-configuration)
778 (destination
779 (getmail-destination-configuration
780 (type "MDA_external")
781 (path (file-append
782 package
783 "/bin/guix-data-service-process-branch-updated-email"))))
784 (options
785 (getmail-options-configuration
786 (read-all #f)
787 (delivered-to #f)
788 (received #f)))))
789 (idle getmail-idle-mailboxes))))))
790
791(define guix-data-service-type
792 (service-type
793 (name 'guix-data-service)
794 (extensions
795 (list
796 (service-extension profile-service-type
797 guix-data-service-profile-packages)
798 (service-extension shepherd-root-service-type
799 guix-data-service-shepherd-services)
800 (service-extension activation-service-type
801 guix-data-service-activation)
802 (service-extension account-service-type
803 guix-data-service-account)
804 (service-extension getmail-service-type
805 guix-data-service-getmail-configuration)))
806 (default-value
807 (guix-data-service-configuration))
808 (description
809 "Run an instance of the Guix Data Service.")))
810
811
812;;;
813;;; Guix Home Service
814;;;
815
816(define (guix-home-shepherd-service config)
817 (map (match-lambda
818 ((user he)
819 (shepherd-service
820 (documentation "Activate Guix Home.")
821 (requirement '(user-processes))
822 (provision (list (symbol-append 'guix-home- (string->symbol user))))
823 (one-shot? #t)
824 (auto-start? #t)
825 (start #~(make-forkexec-constructor
826 '(#$(file-append he "/activate"))
827 #:user #$user
828 ;; FIXME: In 1.0, omitting #:group meant "keep GID
829 ;; unchanged", effectively using GID 0. In 1.1, the
830 ;; group corresponding to USER is picked. When doing a
831 ;; dry run in the build environment, 'getpw' always
832 ;; fails, hence this trick.
833 #:group (and=> (false-if-exception (getpw #$user))
834 (compose group:name getgrgid passwd:gid))
835 #:environment-variables
836 (list "GUIX_SYSTEM_IS_RUNNING_HOME_ACTIVATE=t")))
837 (stop #~(make-kill-destructor)))))
838 config))
839
840(define guix-home-service-type
841 (service-type
842 (name 'guix-home)
843 (description "Sets up Guix Home for the specified user accounts.")
844 (extensions (list (service-extension
845 shepherd-root-service-type
846 guix-home-shepherd-service)))
847 (compose concatenate)
848 (extend append)
849 (default-value '())))
850
851
852;;;
853;;; Nar Herder
854;;;
855
856(define-record-type* <nar-herder-configuration>
857 nar-herder-configuration make-nar-herder-configuration
858 nar-herder-configuration?
859 (package nar-herder-configuration-package
860 (default nar-herder))
861 (user nar-herder-configuration-user
862 (default "nar-herder"))
863 (group nar-herder-configuration-group
864 (default "nar-herder"))
865 (mirror nar-herder-configuration-mirror
866 (default #f))
867 (database nar-herder-configuration-database
868 (default "/var/lib/nar-herder/nar_herder.db"))
869 (database-dump nar-herder-configuration-database-dump
870 (default "/var/lib/nar-herder/nar_herder_dump.db"))
871 (host nar-herder-configuration-host
872 (default "127.0.0.1"))
873 (port nar-herder-configuration-port
874 (default 8734))
875 (control-host nar-herder-configuration-control-host
876 (default "127.0.0.1"))
877 (control-port nar-herder-configuration-control-port
878 (default 8735))
879 (storage nar-herder-configuration-storage
880 (default #f))
881 (storage-limit nar-herder-configuration-storage-limit
882 (default "none"))
883 (storage-minimum-free-space
884 nar-herder-configuration-storage-minimum-free-space
885 (default "none"))
886 (storage-nar-removal-criteria
887 nar-herder-configuration-storage-nar-removal-criteria
888 (default '()))
889 (ttl nar-herder-configuration-ttl
890 (default #f))
891 (new-ttl nar-herder-configuration-new-ttl
892 (default #f))
893 (negative-ttl nar-herder-configuration-negative-ttl
894 (default #f))
895 (log-level nar-herder-configuration-log-level
896 (default 'DEBUG))
897 (cached-compressions
898 nar-herder-configuration-cached-compressions
899 (default '()))
900 (cached-compression-min-uses
901 nar-herder-configuration-cached-compression-min-uses
902 (default 3))
903 (cached-compression-workers
904 nar-herder-configuration-cached-compression-workers
905 (default 2))
906 (cached-compression-nar-source
907 nar-herder-configuration-cached-compression-nar-source
908 (default #f))
909 (extra-options
910 nar-herder-configuration-extra-options
911 (default '()))
912 (extra-environment-variables
913 nar-herder-configuration-extra-environment-variables
914 (default '())))
915
916(define-record-type* <nar-herder-cached-compression-configuration>
917 nar-herder-cached-compression-configuration
918 make-nar-herder-cached-compression-configuration
919 nar-herder-cached-compression-configuration?
920 (type nar-herder-cached-compression-configuration-type)
921 (level nar-herder-cached-compression-configuration-level
922 (default #f))
923 (directory nar-herder-cached-compression-configuration-directory
924 (default #f))
925 (directory-max-size
926 nar-herder-cached-compression-configuration-directory-max-size
927 (default #f))
928 (unused-removal-duration
929 nar-herder-cached-compression-configuration-unused-removal-duration
930 (default #f))
931 (ttl nar-herder-cached-compression-configuration-ttl
932 (default #f))
933 (new-ttl nar-herder-cached-compression-configuration-new-ttl
934 (default #f)))
935
936(define (nar-herder-shepherd-services config)
937 (define (cached-compression-configuration->options cached-compression)
938 (match-record
939 cached-compression
940 <nar-herder-cached-compression-configuration>
941 (type level directory directory-max-size
942 unused-removal-duration ttl new-ttl)
943
944 `(,(simple-format #f "--enable-cached-compression=~A~A"
945 type
946 (if level
947 (simple-format #f ":~A" level)
948 ""))
949 ,@(if directory
950 (list
951 (simple-format #f "--cached-compression-directory=~A=~A"
952 type
953 directory))
954 '())
955 ,@(if directory-max-size
956 (list
957 (simple-format #f "--cached-compression-directory-max-size=~A=~A"
958 type
959 directory-max-size))
960 '())
961 ,@(if unused-removal-duration
962 (list
963 (simple-format
964 #f "--cached-compression-unused-removal-duration=~A=~A"
965 type
966 unused-removal-duration))
967 '())
968 ,@(if ttl
969 (list
970 (simple-format
971 #f "--cached-compression-ttl=~A=~A"
972 type
973 ttl))
974 '())
975 ,@(if new-ttl
976 (list
977 (simple-format
978 #f "--cached-compression-new-ttl=~A=~A"
979 type
980 new-ttl))
981 '()))))
982
983 (match-record config <nar-herder-configuration>
984 (package user group
985 mirror
986 database database-dump
987 host port
988 control-host control-port
989 storage storage-limit storage-minimum-free-space
990 storage-nar-removal-criteria
991 ttl new-ttl negative-ttl log-level
992 cached-compressions cached-compression-min-uses
993 cached-compression-workers cached-compression-nar-source
994 extra-options
995 extra-environment-variables)
996
997 (unless (or mirror storage)
998 (error "nar-herder: mirror or storage must be set"))
999
1000 (list
1001 (shepherd-service
1002 (documentation "Nar Herder")
1003 (provision '(nar-herder))
1004 (requirement '(user-processes networking))
1005 (start #~(make-forkexec-constructor
1006 (list #$(file-append package
1007 "/bin/nar-herder")
1008 "run-server"
1009 "--pid-file=/var/run/nar-herder/pid"
1010 #$(string-append "--port=" (number->string port))
1011 #$(string-append "--host=" host)
1012 #$(string-append "--control-port="
1013 (number->string control-port))
1014 #$(string-append "--control-host="
1015 control-host)
1016 #$@(if mirror
1017 (list (string-append "--mirror=" mirror))
1018 '())
1019 #$(string-append "--database=" database)
1020 #$(string-append "--database-dump=" database-dump)
1021 #$@(if storage
1022 (list (string-append "--storage=" storage))
1023 '())
1024 #$(string-append "--storage-limit="
1025 (if (number? storage-limit)
1026 (number->string storage-limit)
1027 storage-limit))
1028 #$(string-append
1029 "--storage-minimum-free-space="
1030 (if (number? storage-minimum-free-space)
1031 (number->string storage-minimum-free-space)
1032 storage-minimum-free-space))
1033 #$@(map (lambda (criteria)
1034 (string-append
1035 "--storage-nar-removal-criteria="
1036 (match criteria
1037 ((k . v) (simple-format #f "~A=~A" k v))
1038 (str str))))
1039 storage-nar-removal-criteria)
1040 #$@(if ttl
1041 (list (string-append "--ttl=" ttl))
1042 '())
1043 #$@(if new-ttl
1044 (list (string-append "--new-ttl=" new-ttl))
1045 '())
1046 #$@(if negative-ttl
1047 (list (string-append "--negative-ttl=" negative-ttl))
1048 '())
1049 #$@(if log-level
1050 (list (simple-format #f "--log-level=~A" log-level))
1051 '())
1052 #$@(append-map
1053 cached-compression-configuration->options
1054 cached-compressions)
1055 #$@(if cached-compression-min-uses
1056 (list (simple-format
1057 #f "--cached-compression-min-uses=~A"
1058 cached-compression-min-uses))
1059 '())
1060 #$@(if cached-compression-workers
1061 (list (simple-format
1062 #f "--cached-compression-workers=~A"
1063 cached-compression-workers))
1064 '())
1065 #$@(if cached-compression-nar-source
1066 (list (simple-format
1067 #f "--cached-compression-nar-source=~A"
1068 cached-compression-nar-source))
1069 '())
1070 #$@extra-options)
1071 #:user #$user
1072 #:group #$group
1073 #:directory "/var/lib/nar-herder"
1074 #:pid-file "/var/run/nar-herder/pid"
1075 #:environment-variables
1076 `(,(string-append
1077 "GUIX_LOCPATH="
1078 #$(libc-utf8-locales-for-target) "/lib/locale")
1079 "LC_ALL=en_US.utf8"
1080 #$@extra-environment-variables)
1081 #:log-file "/var/log/nar-herder/server.log"))
1082 (stop #~(make-kill-destructor))))))
1083
1084(define (nar-herder-activation config)
1085 #~(begin
1086 (use-modules (guix build utils))
1087
1088 (define %user
1089 (getpw #$(nar-herder-configuration-user
1090 config)))
1091
1092 (chmod "/var/lib/nar-herder" #o755)
1093
1094 (mkdir-p "/var/log/nar-herder")
1095
1096 ;; Allow writing the PID file
1097 (mkdir-p "/var/run/nar-herder")
1098 (chown "/var/run/nar-herder"
1099 (passwd:uid %user)
1100 (passwd:gid %user))))
1101
1102(define (nar-herder-account config)
1103 (match-record config <nar-herder-configuration>
1104 (user group)
1105 (list (user-group
1106 (name group)
1107 (system? #t))
1108 (user-account
1109 (name user)
1110 (group group)
1111 (system? #t)
1112 (comment "Nar Herder user")
1113 (home-directory "/var/lib/nar-herder")
1114 (shell (file-append shadow "/sbin/nologin"))))))
1115
1116(define nar-herder-service-type
1117 (service-type
1118 (name 'nar-herder)
1119 (extensions
1120 (list
1121 (service-extension shepherd-root-service-type
1122 nar-herder-shepherd-services)
1123 (service-extension activation-service-type
1124 nar-herder-activation)
1125 (service-extension account-service-type
1126 nar-herder-account)))
1127 (description
1128 "Run a Nar Herder server.")))
1129
1130
1131;;;
1132;;; Build Farm Front-end (BFFE)
1133;;;
1134
1135(define-record-type* <bffe-configuration>
1136 bffe-configuration make-bffe-configuration
1137 bffe-configuration?
1138 (package bffe-configuration-package
1139 (default bffe))
1140 (user bffe-configuration-user
1141 (default "bffe"))
1142 (group bffe-configuration-group
1143 (default "bffe"))
1144 (arguments bffe-configuration-arguments)
1145 (extra-environment-variables
1146 bffe-configuration-extra-environment-variables
1147 (default '())))
1148
1149(define (bffe-shepherd-services config)
1150 (define bffe-package
1151 (bffe-configuration-package config))
1152
1153 (define start-script
1154 (program-file
1155 "run-bffe"
1156 (with-extensions (cons
1157 bffe-package
1158 ;; This is a poorly constructed Guile load path,
1159 ;; since it contains things that aren't Guile
1160 ;; libraries, but it means that the Guile
1161 ;; libraries needed for BFFE don't need to be
1162 ;; individually specified here.
1163 (map second (package-transitive-propagated-inputs
1164 bffe-package)))
1165 #~(begin
1166 (use-modules (bffe)
1167 (bffe manage-builds))
1168
1169 (simple-format #t "starting the bffe:\n ~A\n"
1170 (current-filename))
1171
1172 (apply run-bffe-service
1173 (append
1174 (list #:pid-file "/var/run/bffe/pid")
1175 #$(bffe-configuration-arguments config)))))
1176 #:guile (lookup-package-native-input bffe-package "guile")))
1177
1178 (match-record config <bffe-configuration>
1179 (package user group arguments extra-environment-variables)
1180
1181 (list
1182 (shepherd-service
1183 (documentation "Build Farm Front-end")
1184 (provision '(bffe))
1185 (requirement '(user-processes networking))
1186 (start #~(make-forkexec-constructor
1187 (list #$start-script)
1188 #:user #$user
1189 #:group #$group
1190 #:pid-file "/var/run/bffe/pid"
1191 #:directory "/var/lib/bffe"
1192 #:environment-variables
1193 `(,(string-append
1194 "GUIX_LOCPATH="
1195 #$(libc-utf8-locales-for-target) "/lib/locale")
1196 "LC_ALL=en_US.utf8"
1197 #$@extra-environment-variables)
1198 #:log-file "/var/log/bffe/server.log"))
1199 (stop #~(make-kill-destructor))))))
1200
1201(define (bffe-activation config)
1202 #~(begin
1203 (use-modules (guix build utils))
1204
1205 (define %user
1206 (getpw #$(bffe-configuration-user config)))
1207
1208 (chmod "/var/lib/bffe" #o755)
1209
1210 (mkdir-p "/var/log/bffe")
1211
1212 ;; Allow writing the PID file
1213 (mkdir-p "/var/run/bffe")
1214 (chown "/var/run/bffe" (passwd:uid %user) (passwd:gid %user))))
1215
1216(define (bffe-account config)
1217 (match-record config <bffe-configuration>
1218 (user group)
1219 (list (user-group
1220 (name group)
1221 (system? #t))
1222 (user-account
1223 (name user)
1224 (group group)
1225 (system? #t)
1226 (comment "BFFE user")
1227 (home-directory "/var/lib/bffe")
1228 (shell (file-append shadow "/sbin/nologin"))))))
1229
1230(define bffe-service-type
1231 (service-type
1232 (name 'bffe)
1233 (extensions
1234 (list (service-extension shepherd-root-service-type
1235 bffe-shepherd-services)
1236 (service-extension activation-service-type
1237 bffe-activation)
1238 (service-extension account-service-type
1239 bffe-account)))
1240 (description
1241 "Run the Build Farm Front-end.")))
1242
1243;;;
1244;;; Share .cache/ content between users
1245;;;
1246;;; On a system with multiple users, each $HOME/.cache/guix is
1247;;; ~700MB of data that is mostly the same between users. This service allows
1248;;; one to either:
1249;;
1250;;; - share this cache between users, with updates shared between users, which
1251;;; is suitable for a high trust environment, typically a single human user
1252;;; with multiple accounts on the same computer
1253;;;
1254;;; - or expose a single user's cache, read-only with a write overlay, to the
1255;;; other users, typically used in low-trust environments such as a public
1256;;; access guix system.
1257
1258(define-record-type* <user-cache>
1259 user-cache make-user-cache
1260 user-cache?
1261 (user user-cache-user)
1262 (location user-cache-location (default (string-append "/home/" (user-cache-user this-record) "/.cache")) (thunked))
1263 (group user-cache-group (default "users"))
1264 (directories user-cache-directories (default '("guix/checkouts"))))
1265
1266(define list-of-user-cache? (list-of user-cache?))
1267
1268(define (mount-type? x)
1269 (and (symbol? x)
1270 (or (eq? x 'share)
1271 (eq? x 'expose))))
1272
1273(define-configuration/no-serialization shared-cache-configuration
1274 (mode (mount-type 'expose) "Either 'share (read-write, dangerous) or 'expose (read-only, the default) the cache directory.")
1275 (shared-directory (string "/root/.cache") "The sharing user's cache directory (i.e. the source).")
1276 (users (list-of-user-cache '()) "The users that benefit from the shared directory. This is a list of user-cache records (i.e. the destinations)."))
1277
1278(define shared-cache-vfs-mappings
1279 (match-record-lambda <shared-cache-configuration>
1280 (mode shared-directory users)
1281 (apply
1282 append
1283 (map
1284 (match-record-lambda <user-cache>
1285 (location user group directories)
1286 (map
1287 (lambda (subdir)
1288 (vfs-mapping
1289 ;; Each subdir has its own service
1290 (name (string-append "shared-cache-" subdir "-" user))
1291 ;; Make sure the homes are already present
1292 (requirement '(file-systems user-file-systems user-homes))
1293 ;; Mount each shared dir over the target dir in the users' .cache/
1294 (source (string-append shared-directory "/" subdir))
1295 (destination (string-append location "/" subdir))
1296 (policy (match mode
1297 ('expose 'overlay)
1298 ('share 'translate)))
1299 (user user)
1300 (group group)))
1301 directories))
1302 users))))
1303
1304(define shared-cache-service-type
1305 (service-type
1306 (name 'shared-cache)
1307 (extensions (list
1308 (service-extension vfs-mapping-service-type
1309 shared-cache-vfs-mappings)))
1310 (compose concatenate)
1311 (extend (lambda (original extensions)
1312 (shared-cache-configuration
1313 (inherit original)
1314 (users (append (shared-cache-configuration-users original) extensions)))))
1315 (default-value (shared-cache-configuration))
1316 (description "Share or expose ~/.cache/ sub directories between multiple users.")))