maintenance/hydra/bayfront.scm

1468 lines
56 KiB
Scheme
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;; OS configuration for bayfront
;; Copyright © 2016-2023 Ludovic Courtès <ludo@gnu.org>
;; Copyright © 2016, 2017, 2018, 2019, 2020, 2023 Andreas Enge <andreas@enge.fr>
;; Copyright © 2017, 2019 Ricardo Wurmus <rekado@elephly.net>
;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu>
;; Copyright © 2020, 2021 Christopher Baines <mail@cbaines.net>
;; Copyright © 2020, 2021 Tobias Geerinckx-Rice <me@tobias.gr>
;; Copyright © 2021 Mathieu Othacehe <othacehe@gnu.org>
;; Released under the GNU GPLv3 or any later version.
(use-modules (gnu) (guix) (guix packages) (guix git)
(guix modules)
(sysadmin people) (sysadmin services)
(sysadmin dns) (sysadmin web) (sysadmin nginx))
(use-service-modules admin avahi base certbot databases dns linux
monitoring networking shepherd ssh vpn web mcron guix)
(use-package-modules admin certs ci databases linux ssh tls vim
package-management rsync web wget)
(include "website.scm")
(define %sysadmins
;; The sysadmins.
(list (sysadmin (name "andreas")
(full-name "Andreas Enge")
(ssh-public-key (local-file "keys/ssh/andreas.pub")))
(sysadmin (name "cbaines")
(full-name "Christopher Baines")
(ssh-public-key (local-file "keys/ssh/cbaines.pub")))
(sysadmin (name "ludo")
(full-name "Ludovic Courtès")
(ssh-public-key (local-file "keys/ssh/ludo.pub")))
(sysadmin (name "rekado")
(full-name "Ricardo Wurmus")
(ssh-public-key (local-file "keys/ssh/rekado.pub")))
(sysadmin (name "mathieu")
(full-name "Mathieu Othacehe")
(ssh-public-key (local-file "keys/ssh/mathieu.pub")))
(sysadmin (name "nckx")
(full-name "Tobias Geerinckx-Rice")
(ssh-public-key (local-file "keys/ssh/nckx.pub")))))
(define %nginx-deploy-hook
;; Hook that restarts nginx when a new certificate is deployed.
(program-file "nginx-deploy-hook"
#~(let ((pid (call-with-input-file "/var/run/nginx/pid"
read)))
(kill pid SIGHUP))))
(define %certbot-configuration
(certbot-configuration
(webroot "/var/www")
(email "ludovic.courtes@inria.fr")
(certificates
(list (certificate-configuration
(domains '("bayfront.guix.gnu.org"
"logs.guix.gnu.org"
"bayfront.guix.info"
"hpc.guix.info"
"guix-hpc.bordeaux.inria.fr"
"coordinator.bayfront.guix.gnu.org"))
(deploy-hook %nginx-deploy-hook))
(certificate-configuration
(domains '("packages.guix.gnu.org"))
(deploy-hook %nginx-deploy-hook))
(certificate-configuration
(domains '("qa.guix.gnu.org"))
(deploy-hook %nginx-deploy-hook))
(certificate-configuration
(domains '("bordeaux.guix.gnu.org"))
(deploy-hook %nginx-deploy-hook))))))
(define guix-hpc-web-site
(static-web-site-configuration
(git-url "https://gitlab.inria.fr/guix-hpc/website.git")
(directory "/srv/guix-hpc-web")))
(define ten-years-of-guix-web-site
(static-web-site-configuration
(git-url "https://gitlab.com/zimoun/website-guix-10years")
(git-ref '(branch . "main"))
(directory "/srv/ten-years-of-guix")))
(define %motd
(plain-file "motd"
"\
░░░ ░░░
░░▒▒░░░░░░░░░ ░░░░░░░░░▒▒░░
░░▒▒▒▒▒░░░░░░░ ░░░░░░░▒▒▒▒▒░
░▒▒▒░░▒▒▒▒▒ ░░░░░░░▒▒░
░▒▒▒▒░ ░░░░░░
▒▒▒▒▒ ░░░░░░
▒▒▒▒▒ ░░░░░
░▒▒▒▒▒ ░░░░░ Welcome to bayfront!
▒▒▒▒▒ ░░░░░
▒▒▒▒▒ ░░░░░
░▒▒▒▒▒░░░░░
▒▒▒▒▒▒░░░
▒▒▒▒▒▒░
Best practices:
1. Store everything in guix-maintenance.git.
2. Use the Git checkouts of Guix and guix-maintenance in ~root.
3. Notify guix-sysadmin@gnu.org when reconfiguring.
4. Notify guix-sysadmin@gnu.org when something goes wrong.
Happy hacking!\n"))
(define gnu-ns1-ip4/old
;; Old IPv4 address of "ns1.gnu.org".
"198.27.68.225")
(define gnu-ns1-ip4/new
;; New IPv4 address of "ns1.gnu.org".
"192.99.37.66")
(define %build-node-keys
;; Signing keys of the build nodes.
(list (local-file "keys/guix/harbourfront.guix.info-export.pub")
(local-file "keys/guix/milano-guix-1.di.unimi.it-export.pub")))
(define %hpcguix-web-channels
;; Channels picked up and displayed by hpcguix-web.
#~(append %default-channels
(list (channel
(name 'guix-hpc)
(url "https://gitlab.inria.fr/guix-hpc/guix-hpc.git"))
(channel
(name 'guix-past)
(url "https://gitlab.inria.fr/guix-hpc/guix-past")
(introduction
(make-channel-introduction
"0c119db2ea86a389769f4d2b9c6f5c41c027e336"
(openpgp-fingerprint
"3CE4 6455 8A84 FDC6 9DB4 0CFB 090B 1199 3D9A EBB5"))))
(channel
(name 'guix-science)
(url "https://github.com/guix-science/guix-science.git")
(introduction
(make-channel-introduction
"b1fe5aaff3ab48e798a4cce02f0212bc91f423dc"
(openpgp-fingerprint
"CA4F 8CF4 37D7 478F DA05 5FD4 4213 7701 1A37 8446"))))
;; XXX: 'gn-bioinformatics' commented out because its
;; '.guix-channel' file requests an old Guix commit not
;; compatible with what 'guix-science' expects.
;;
;; (channel
;; (name 'gn-bioinformatics)
;; (url "https://git.genenetwork.org/guix-bioinformatics"))
(channel
(name 'guix-cran)
(url "https://github.com/guix-science/guix-cran.git")))))
(define %hpcguix-web-channel-descriptions
;; Channel metadata displayed by hpcguix-web.
#~(let ((%inria-key "\
(public-key
(ecc
(curve Ed25519)
(q #89FBA276A976A8DE2A69774771A92C8C879E0F24614AAAAE23119608707B3F06#)))")
(inria-cuirass-dashboard
(lambda (jobset)
(string-append
"https://guix.bordeaux.inria.fr/eval/latest/dashboard?spec="
jobset)))
(inria-cuirass-badge
(lambda (jobset)
(string-append
"https://guix.bordeaux.inria.fr/jobset/" jobset
"/badge.svg")))
(inria-package-cuirass-url
(lambda (jobset)
(lambda (package version)
(string-append
"https://guix.bordeaux.inria.fr/search?query=spec:" jobset
"%20" package "-" version)))))
(list %guix-channel-description
(channel-description
(name 'guix-hpc)
(home-page "https://gitlab.inria.fr/guix-hpc/guix-hpc")
(synopsis
"High-performance computing packages at @uref{https://www.inria.fr/en, Inria}")
(logo-url
"https://gitlab.inria.fr/uploads/-/system/project/avatar/2095/guix-hpc-square.jpg?width=64")
(ci-badge (inria-cuirass-badge "guix-hpc"))
(ci-url (inria-cuirass-dashboard "guix-hpc"))
(ci-package-url (inria-package-cuirass-url "guix-hpc"))
(substitutes `(("https://guix.bordeaux.inria.fr" . ,%inria-key))))
(channel-description
(name 'guix-past)
(home-page "https://gitlab.inria.fr/guix-hpc/guix-past")
(synopsis "Providing old package versions")
(logo-url
"https://gitlab.inria.fr/uploads/-/system/project/avatar/19816/guix-bw.png?width=64")
(ci-badge (inria-cuirass-badge "guix-past"))
(ci-url (inria-cuirass-dashboard "guix-past"))
(ci-package-url (inria-package-cuirass-url "guix-past"))
(substitutes `(("https://guix.bordeaux.inria.fr" . ,%inria-key))))
(channel-description
(name 'guix-science)
(home-page "https://github.com/guix-science/guix-science")
(synopsis "General scientific and statistics packages")
(ci-badge (inria-cuirass-badge "guix-science"))
(ci-url (inria-cuirass-dashboard "guix-science"))
(ci-package-url (inria-package-cuirass-url "guix-science"))
(substitutes `(("https://guix.bordeaux.inria.fr" . ,%inria-key))))
(channel-description
(name 'guix-cran)
(home-page "https://github.com/guix-science/guix-cran")
(synopsis
"Automated import of all the @uref{https://cran.r-project.org/, CRAN} packages")
(logo-url
"https://github.com/guix-science/guix-cran-scripts/raw/master/logo.png")
(ci-badge (inria-cuirass-badge "guix-cran"))
(ci-url (inria-cuirass-dashboard "guix-cran"))
(ci-package-url (inria-package-cuirass-url "guix-cran"))
(substitutes `(("https://guix.bordeaux.inria.fr" . ,%inria-key))))
(channel-description
(name 'gn-bioinformatics)
(home-page "https://git.genenetwork.org/guix-bioinformatics/")
(synopsis "Bioinformatics and HPC packages used by
@uref{https://genenetwork.org/environments/, Genenetwork} at the University
of Tennessee")))))
;;;
;;; Backups from berlin.
;;;
(define backup-mcron-jobs
(let* ((berlin-wg-ip "10.0.0.1") ;WireGuard VPN IP of berlin
(url (lambda (module)
(string-append "rsync://" berlin-wg-ip "/" module))))
(define (backup-job spec url target)
#~(job #$spec
(string-append #$rsync "/bin/rsync"
" -vur " #$url " " #$target)
#:user "static-web-site"))
;; Replicate (mostly) the "stateful" bits associated with the web site,
;; <https://guix.gnu.org>. See the list of rsync "modules" exported by
;; 'rsync-service-type' on berlin.guix.gnu.org.
(list (backup-job "00 4 * * *"
(url "disarchive") "/srv/disarchive")
(backup-job "10 4 * * *"
(url "web-pdf") "/srv/guix-pdfs")
(backup-job "20 4 * * *"
(url "web-video") "/srv/videos")
(backup-job "30 4 * * *"
(url "web-audio") "/srv/audio")
(backup-job "40 4 * * *"
(url "web-cuirass") "/srv/cuirass-releases")
(backup-job "50 4 * * *"
(url "web-cuirass-manual") "/srv/cuirass-manual"))))
(define backup-activation
(with-imported-modules (source-module-closure
'((gnu build activation)))
#~(begin
(use-modules (gnu build activation))
(for-each (lambda (directory)
(mkdir-p/perms directory
(getpw "static-web-site")
#o755))
'("/srv/disarchive"
"/srv/guix-pdfs"
"/srv/videos"
"/srv/audio"
"/srv/cuirass-releases")))))
(define backup-service-type
(service-type
(name 'backup)
(extensions
(list (service-extension mcron-service-type
(const backup-mcron-jobs))
(service-extension activation-service-type
(const backup-activation))))
(default-value #t)
(description "Backup data from berlin.guix.gnu.org.")))
;;;
;;; Nginx.
;;;
(define %bayfront-nginx-service-extra-config
(list (accept-languages)
"
sendfile on;
# Maximum chunk size to send. Partly this is a workaround
# for <http://bugs.gnu.org/19939>, but also the nginx docs
# mention that \"Without the limit, one fast connection may
# seize the worker process entirely.\"
# <http://nginx.org/en/docs/http/ngx_http_core_module#sendfile_max_chunk>
sendfile_max_chunk 1m;
keepalive_timeout 65;
# Use HTTP 1.1 to talk to the backend so we benefit from
# keep-alive connections and chunked transfer encoding. The
# latter allows us to make sure we do not cache partial downloads.
proxy_http_version 1.1;
# The 'inactive' parameter for caching is not very useful in our
# case: all that matters is that LRU sweeping happens when
# 'max_size' is hit.
# cache for nar files
proxy_cache_path /var/cache/nginx/nar
levels=2
inactive=8d # inactive keys removed after 8d
keys_zone=nar:4m # nar cache meta data: ~32K keys
max_size=10g; # total cache data size max
# cache for content-addressed files
proxy_cache_path /var/cache/nginx/cas
levels=2
inactive=180d # inactive keys removed after 180d
keys_zone=cas:8m # nar cache meta data: ~64K keys
max_size=50g; # total cache data size max
# cache for build logs
proxy_cache_path /var/cache/nginx/logs
levels=2
inactive=60d # inactive keys removed after 60d
keys_zone=logs:8m # narinfo meta data: ~64K keys
max_size=4g; # total cache data size max
# cache for static data
proxy_cache_path /var/cache/nginx/static
levels=1
inactive=10d # inactive keys removed after 10d
keys_zone=static:1m # nar cache meta data: ~8K keys
max_size=200m; # total cache data size max
proxy_cache_path /var/cache/nginx/bordeaux/nar
levels=2
inactive=28d # inactive keys removed after 28d
keys_zone=bordeaux-nar:64m
max_size=1024g; # total cache data size max
"))
(define %common-tls-options
;; TLS options used by nginx HTTPS server blocks.
"\
# Make sure SSL is disabled.
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
# Disable weak cipher suites.
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Use our own DH parameters created with:
# openssl dhparam -out dhparams.pem 2048
# as suggested at <https://weakdh.org/sysadmin.html>.
ssl_dhparam /etc/dhparams.pem;
# Tell clients to keep using HTTPS.
add_header Strict-Transport-Security max-age=15552000;
# Limit embedding in HTML frames.
add_header X-Frame-Options SAMEORIGIN;\n")
(define %disable-last-modified-header
;; TODO This works around NGinx using the epoch for the
;; Last-Modified date, as well as the etag.
;; See http://issues.guix.gnu.org/37207
'("add_header Last-Modified \"\";"
"if_modified_since off;"
"etag off;"))
(define %hpc.guix.info-nginx-servers
(let ((common-locations
(list
(nginx-location-configuration
(uri "/")
(body '("root /srv/guix-hpc-web;")))
;; For the package browsing interface
(nginx-named-location-configuration
(name "gnupackages")
(body '( "return 307 https://guix.gnu.org/en/packages/;")))
(nginx-location-configuration
(uri "/browse")
(body '("proxy_pass http://localhost:5000;
rewrite .* / break;
proxy_connect_timeout 3s;
proxy_read_timeout 2s;
error_page 500 502 503 504 = @gnupackages;")))
(nginx-location-configuration
(uri "/package")
(body '("proxy_pass http://localhost:5000;
proxy_connect_timeout 3s;
proxy_read_timeout 2s;
error_page 500 502 503 504 = @gnupackages;")))
(nginx-location-configuration
(uri "/channel/")
(body '("proxy_pass http://localhost:5000;")))
(nginx-location-configuration
(uri "= /channels")
(body '("proxy_pass http://localhost:5000;")))
(nginx-location-configuration
(uri "= /channels/") ;XXX: triggers 500 in hpcguix-web 0.4.0
(body '("return 301 $scheme://hpc.guix.info/channels;")))
;; JS for hpcguix-web
(nginx-location-configuration
(uri "~ /static/.*\\.js")
(body '("proxy_pass http://localhost:5000;")))
;; Licensing info for hpcguix-web JS code
(nginx-location-configuration
(uri "/javascript")
(body '("proxy_pass http://localhost:5000;")))
(nginx-location-configuration
(uri "~ /static/images/sort_.*\\.png")
(body '("proxy_pass http://localhost:5000;")))
;; Improve caching for CSS, images, etc.
(nginx-location-configuration
(uri "/static")
(body '("add_header Cache-Control max-age=21600;")))
(nginx-location-configuration ; Videos
(uri "/static/videos")
(body '("root /srv/guix-hpc-videos;"))))))
(list
(nginx-server-configuration
(server-name '("hpc.guix.info"))
(listen '("80" "[::]:80"))
(raw-content
`(,@%disable-last-modified-header
"
access_log /var/log/nginx/guix-hpc.access.log;
# Limit embedding in HTML frames.
add_header X-Frame-Options SAMEORIGIN;"))
(root "/srv/guix-hpc-web")
(locations
(append
common-locations
(list
(nginx-location-configuration ; For use by Certbot
(uri "/.well-known")
(body '("root /var/www;")))))))
(nginx-server-configuration
(server-name '("hpc.guix.info"))
(listen '("443 ssl" "[::]:443 ssl"))
(ssl-certificate "/etc/letsencrypt/live/hpc.guix.info/fullchain.pem")
(ssl-certificate-key "/etc/letsencrypt/live/hpc.guix.info/privkey.pem")
(root "/srv/guix-hpc-web")
(raw-content
(append %disable-last-modified-header
(list %common-tls-options
"access_log /var/log/nginx/guix-hpc.access.log;")))
(locations common-locations)))))
(define %guix-hpc.bordeaux.inria.fr-nginx-servers
(let ((common-locations
(list
(nginx-location-configuration
(uri "~ ^/nix-cache-info$")
(body
'("return 301 $scheme://guix.bordeaux.inria.fr/nix-cache-info;")))
(nginx-location-configuration
(uri "~ /(.*\\.narinfo)")
(body
'("return 301 $scheme://guix.bordeaux.inria.fr/$1;")))
(nginx-location-configuration
(uri "~ /nar/(.*)")
(body
'("return 301 $scheme://guix.bordeaux.inria.fr/nar/$1;")))
(nginx-location-configuration
(uri "~ /(.*)")
(body
'("return 301 $scheme://hpc.guix.info/$1;"))))))
(list
(nginx-server-configuration
(server-name '("guix-hpc.bordeaux.inria.fr"))
(listen '("80" "[::]:80"))
(raw-content
'("
access_log /var/log/nginx/guix-hpc.access.log;"))
(locations
(append
common-locations
(list
(nginx-location-configuration ; For use by Certbot
(uri "/.well-known")
(body '("root /var/www;")))))))
(nginx-server-configuration
(server-name '("guix-hpc.bordeaux.inria.fr"))
(listen '("443 ssl" "[::]:443 ssl"))
(ssl-certificate
"/etc/letsencrypt/live/guix-hpc.bordeaux.inria.fr/fullchain.pem")
(ssl-certificate-key
"/etc/letsencrypt/live/guix-hpc.bordeaux.inria.fr/privkey.pem")
(raw-content
(list %common-tls-options
"access_log /var/log/nginx/guix-hpc.access.log;"))
(locations common-locations)))))
(define %ten-years-of-guix-nginx-servers
(list (nginx-server-configuration
(server-name '("10years.guix.gnu.org"))
(listen '("80" "[::]:80"))
(raw-content
`(,@%disable-last-modified-header
"
access_log /var/log/nginx/ten-years.access.log;
# Limit embedding in HTML frames.
add_header X-Frame-Options SAMEORIGIN;"))
(root "/srv/ten-years-of-guix")
(locations
(list (nginx-location-configuration ;for use by Certbot
(uri "/.well-known")
(body '("root /var/www;")))
(nginx-location-configuration ;improve caching
(uri "/static")
(body '("add_header Cache-Control max-age=21600;"))))))
(nginx-server-configuration
(server-name '("10years.guix.gnu.org"))
(listen '("443 ssl" "[::]:443 ssl"))
(ssl-certificate "/etc/letsencrypt/live/10years.guix.gnu.org/fullchain.pem")
(ssl-certificate-key "/etc/letsencrypt/live/10years.guix.gnu.org/privkey.pem")
(root "/srv/ten-years-of-guix")
(locations
(list (nginx-location-configuration ;improve caching
(uri "/static")
(body '("add_header Cache-Control max-age=21600;")))))
(raw-content
(list (cons %common-tls-options
%disable-last-modified-header)
"access_log /var/log/nginx/ten-years.access.log;")))))
(define %logs.guix.gnu.org-nginx-servers
(let ((common-locations
(list
(nginx-location-configuration
(uri "/")
(body '("proxy_pass http://localhost:3333/;"))))))
(list
(nginx-server-configuration
(server-name '("logs.guix.gnu.org"))
(listen '("80" "[::]:80"))
(raw-content
'("
access_log /var/log/nginx/logs.access.log;"))
(locations
(append
common-locations
(list
(nginx-location-configuration ; For use by Certbot
(uri "/.well-known")
(body '("root /var/www;")))))))
(nginx-server-configuration
(server-name '("logs.guix.gnu.org"))
(listen '("443 ssl" "[::]:443 ssl"))
(ssl-certificate
"/etc/letsencrypt/live/logs.guix.gnu.org/fullchain.pem")
(ssl-certificate-key
"/etc/letsencrypt/live/logs.guix.gnu.org/privkey.pem")
(raw-content
(list %common-tls-options
"access_log /var/log/nginx/logs.access.log;"))
(locations common-locations)))))
(define %coordinator.bayfront.guix.gnu.org-nginx-servers
(list
(nginx-server-configuration
(server-name '("coordinator.bayfront.guix.gnu.org"))
(listen '("80" "[::]:80"))
(locations
(list
(nginx-location-configuration ; For use by Certbot
(uri "/.well-known")
(body '(("root /var/www;")))))))
(nginx-server-configuration
(server-name '("coordinator.bayfront.guix.gnu.org"))
(listen '("443 ssl" "[::]:443 ssl"))
(ssl-certificate
"/etc/letsencrypt/live/bayfront.guix.gnu.org/fullchain.pem")
(ssl-certificate-key
"/etc/letsencrypt/live/bayfront.guix.gnu.org/privkey.pem")
(raw-content
(list %common-tls-options
"\
client_max_body_size 0;
client_body_buffer_size 128K;
access_log /var/log/nginx/coordinator.access.log;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;"))
(locations
(list (nginx-location-configuration
(uri "/")
(body '("try_files $uri $uri/ @guix-build-coordinator;")))
(nginx-named-location-configuration
(name "guix-build-coordinator")
(body '("proxy_pass http://guix-build-coordinator-proxy;"
"proxy_http_version 1.1;"
"proxy_set_header Host $host;"
"proxy_set_header X-Forwarded-For $remote_addr;"
"proxy_request_buffering off;"
"gzip on;"
"gzip_types text/html application/json;"
"gzip_proxied any;"))))))))
(define %bayfront.guix.gnu.org-nginx-servers
(let ((common-locations
(list
(nginx-location-configuration
(uri "= /404")
(body '("return 404 '404';"
"add_header Content-Type text/plain;"))))))
(list
(nginx-server-configuration
(server-name '("bayfront.guix.gnu.org"))
(listen '("80" "[::]:80"))
(raw-content
'("
access_log /var/log/nginx/http.access.log;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;"))
(locations
(append
common-locations
(list
(nginx-location-configuration ; For use by Certbot
(uri "/.well-known")
(body '(("root /var/www;"))))))))
(nginx-server-configuration
(server-name '("bayfront.guix.gnu.org"))
(listen '("443 ssl" "[::]:443 ssl"))
(ssl-certificate
"/etc/letsencrypt/live/bayfront.guix.gnu.org/fullchain.pem")
(ssl-certificate-key
"/etc/letsencrypt/live/bayfront.guix.gnu.org/privkey.pem")
(raw-content
(list %common-tls-options
"\
access_log /var/log/nginx/https.access.log;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;"))
(locations common-locations)))))
(define %bordeaux.guix.gnu.org-nginx-servers
(let ((common-locations
(list
(nginx-location-configuration
(uri "= /nix-cache-info")
(body '("
return 200 'StoreDir: /gnu/store\nWantMassQuery: 0\nPriority: 100\n';
add_header Content-Type text/plain;")))
(nginx-location-configuration
(uri "= /404")
(body '("
return 404 '404';
add_header Content-Type text/plain;")))
(nginx-location-configuration
(uri "~ \\.narinfo$")
(body '("
proxy_pass http://nar-herder;
proxy_http_version 1.1;
proxy_set_header Connection \"\";
# For HTTP pipelining. This has a dramatic impact on performance.
client_body_buffer_size 128k;
# Narinfos requests are short, serve many of them on a connection.
keepalive_requests 20000;
")))
(nginx-location-configuration
(uri "~ \\.narinfo/info$")
(body '("proxy_pass http://nar-herder;"
"proxy_http_version 1.1;"
"proxy_set_header Connection \"\";")))
(nginx-location-configuration
(uri "/nar/")
(body '("proxy_pass http://nar-herder;"
"proxy_http_version 1.1;"
"proxy_set_header Connection \"\";")))
(nginx-location-configuration
(uri "/file/")
(body '("proxy_pass https://nar-storage;")))
(nginx-named-location-configuration
(name "nar-storage")
(body '("rewrite /internal/(.*) /$1 break;"
"proxy_pass https://nar-storage;"
"
set $via \"1.1 bayfront\";
if ($http_via) {
set $via \"$http_via, $via\";
}
proxy_set_header Via $via;"
"proxy_cache bordeaux-nar;"
"proxy_http_version 1.1;"
"proxy_set_header Connection \"\";"
"proxy_cache_valid 200 28d;"
"proxy_ignore_client_abort on;")))
(nginx-location-configuration
(uri "= /latest-database-dump")
(body '("proxy_pass http://nar-herder;"
"proxy_http_version 1.1;"
"proxy_set_header Connection \"\";")))
(nginx-location-configuration
(uri "= /recent-changes")
(body '("proxy_pass http://nar-herder;"
"proxy_http_version 1.1;"
"proxy_set_header Connection \"\";")))
(nginx-location-configuration
(uri "= /metrics")
(body '("proxy_pass http://nar-herder;"
"proxy_http_version 1.1;"
"proxy_set_header Connection \"\";")))
(nginx-location-configuration
(uri "~ ^/internal/database/(.*)$")
(body '("internal;"
"alias /var/lib/nar-herder/$1;")))
(nginx-location-configuration
(uri "~ ^/internal/nar/(.*)$")
(body '("
internal;
root /var/lib/nars;
try_files /nar/$1 @nar-storage;
error_page 404 /404;
client_body_buffer_size 256k;
# Nars are already compressed.
gzip off;
")))
(nginx-location-configuration
(uri "~ ^/internal/cached-nar/(.*)$")
(body '("
internal;
root /var/cache/nar-herder;
try_files /nar/$1 =404;
error_page 404 /404;
client_body_buffer_size 256k;
gzip off;
")))
(nginx-location-configuration
(uri "~ \"\\/build\\/([a-z0-9-]{36})/log$\"")
(body '("alias /var/lib/guix-build-coordinator/build-logs/$1/log;"
"add_header Content-Type 'text/plain; charset=UTF-8';"
"gzip_static always;"
"gunzip on;")))
(nginx-location-configuration
(uri "/")
(body '("proxy_pass http://bffe;"
"proxy_http_version 1.1;"
"proxy_set_header Connection \"\";")))
(nginx-location-configuration
(uri "/events")
(body '("proxy_pass http://bffe;"
"proxy_http_version 1.1;"
"proxy_buffering off;"
"proxy_set_header Connection \"\";"))))))
(list
(nginx-server-configuration
(server-name '("bordeaux.guix.gnu.org"))
(listen '("80 reuseport"
"[::]:80 reuseport"))
(root "/srv/bordeaux.guix.gnu.org")
(raw-content
'("access_log /var/log/nginx/bordeaux.access.log.gz combined gzip flush=1m;"))
(locations
(append
common-locations
(list
(nginx-location-configuration ; For use by Certbot
(uri "/.well-known")
(body '(("root /var/www;"))))))))
(nginx-server-configuration
(server-name '("bordeaux.guix.gnu.org"))
(listen '("443 ssl reuseport"
"[::]:443 ssl reuseport"))
(root "/srv/bordeaux.guix.gnu.org")
(ssl-certificate
"/etc/letsencrypt/live/bordeaux.guix.gnu.org/fullchain.pem")
(ssl-certificate-key
"/etc/letsencrypt/live/bordeaux.guix.gnu.org/privkey.pem")
(raw-content
(list
%common-tls-options
"access_log /var/log/nginx/bordeaux.access.log.gz combined gzip flush=1m;"))
(locations common-locations)))))
(define %qa.guix.gnu.org-nginx-servers
(list
(nginx-server-configuration
(server-name '("qa.guix.gnu.org"))
(listen '("80"
"[::]:80"))
(locations
(list
(nginx-location-configuration
(uri "/")
(body '(("return 301 https://$host$request_uri;"))))
(nginx-location-configuration ; For use by Certbot
(uri "/.well-known")
(body '(("root /var/www;")))))))
(nginx-server-configuration
(server-name '("qa.guix.gnu.org"))
(listen '("443 ssl"
"[::]:443 ssl"))
(ssl-certificate
"/etc/letsencrypt/live/qa.guix.gnu.org/fullchain.pem")
(ssl-certificate-key
"/etc/letsencrypt/live/qa.guix.gnu.org/privkey.pem")
(raw-content
(list
%common-tls-options
"access_log /var/log/nginx/qa.access.log;"))
(locations
(list
(nginx-location-configuration
(uri "/")
(body '("proxy_pass http://qa-frontpage;"
"proxy_http_version 1.1;"
"proxy_set_header Connection \"\";")))
(nginx-location-configuration
(uri "/reproducible.json")
(body '("alias /var/lib/qa-frontpage/reproducible.json;"
"add_header Content-Type 'text/plain; charset=UTF-8';"
"gzip_static always;"
"gunzip on;"))))))))
(define %packages.guix.gnu.org-nginx-servers
(list
(nginx-server-configuration
(server-name '("packages.guix.gnu.org"))
(listen '("80"
"[::]:80"))
(locations
(list
(nginx-location-configuration
(uri "/")
(body '(("return 301 https://$host$request_uri;"))))
(nginx-location-configuration ; For use by Certbot
(uri "/.well-known")
(body '(("root /var/www;")))))))
(nginx-server-configuration
(server-name '("packages.guix.gnu.org"))
(listen '("443 ssl"
"[::]:443 ssl"))
(ssl-certificate
"/etc/letsencrypt/live/packages.guix.gnu.org/fullchain.pem")
(ssl-certificate-key
"/etc/letsencrypt/live/packages.guix.gnu.org/privkey.pem")
(raw-content
(list
%common-tls-options
"access_log /var/log/nginx/packages.access.log;"))
(locations
(list
(nginx-location-configuration
(uri "/")
(body '("proxy_pass http://packages;"
"proxy_http_version 1.1;"
"proxy_set_header Connection \"\";"))))))))
(define %guix.gnu.org-http-nginx-servers
;; Redirect domains that don't explicitly support HTTP (below) to HTTPS.
(list (nginx-server-configuration
(listen '("80" "[::]:80"))
(server-name '("guix.gnu.org"))
(raw-content
(list "return 308 https://$host$request_uri;")))))
(define %guix-build-coordinator-configuration
(let* ((data.guix.gnu.org-build-event-destination
#~(string-append
"https://data.guix.gnu.org"
"/build-server/2/build-events?token="
(string-trim-right
(call-with-input-file
"/etc/guix-build-coordinator/data.guix.gnu.org-token"
get-string-all))))
(data.qa.guix.gnu.org-build-event-destination
#~(string-append
"https://data.qa.guix.gnu.org"
"/build-server/2/build-events?token="
(string-trim-right
(call-with-input-file
"/etc/guix-build-coordinator/data.qa.guix.gnu.org-token"
get-string-all))))
(publish-directory
"/var/lib/nars")
(recompress-log-file-hook
#~(apply ((@ (guix-build-coordinator hooks)
build-recompress-log-file-hook)
#:recompress-to 'gzip)
args)))
(define (send-guix-data-service-event event-hook)
#~(begin
(use-modules (ice-9 textual-ports))
(apply ((@ (guix-build-coordinator hooks)
#$event-hook)
#$data.guix.gnu.org-build-event-destination)
args)
(apply ((@ (guix-build-coordinator hooks)
#$event-hook)
#$data.qa.guix.gnu.org-build-event-destination)
args)))
(guix-build-coordinator-configuration
(agent-communication-uri-string
"http://127.0.0.1:8745") ; only listen locally
(allocation-strategy
#~derivation-ordered-build-allocation-strategy)
(parallel-hooks
'((build-submitted . 6)
(build-canceled . 6)
(build-started . 6)
(build-success . 24)))
(hooks
`((build-missing-inputs
;; Builds shouldn't be missing inputs, so disable this hook
. ,#~(const #t))
(build-submitted
. ,#~(lambda args
#$(send-guix-data-service-event
'build-submitted-send-event-to-guix-data-service-hook)))
(build-started
. ,#~(lambda args
#$(send-guix-data-service-event
'build-started-send-event-to-guix-data-service-hook)))
(build-success
. ,#~(lambda args
(use-modules (gcrypt pk-crypto) ; for read-file-sexp
(web uri)
(web client)
(web response))
#$recompress-log-file-hook
(apply ((@ (guix-build-coordinator hooks)
build-success-publish-hook)
#$publish-directory
;; These should be the same as
;; /etc/guix/... but are copied here so that
;; they can be read by the Guix Build
;; Coordinantor
#:public-key
(read-file-sexp
"/etc/guix-build-coordinator/signing-key.pub")
#:private-key
(read-file-sexp
"/etc/guix-build-coordinator/signing-key.sec")
#:skip-publishing-proc
(lambda (narinfo-filename _)
(eq? 200
((@ (web response) response-code)
(http-get
(string->uri
(string-append
"http://localhost:8734/"
narinfo-filename))))))
#:combined-post-publish-hook
(lambda (directory narinfos-and-nars)
(let* ((narinfos
(map
(lambda (narinfo-filename)
(string-append directory "/" narinfo-filename))
(map car narinfos-and-nars)))
(command
(cons* #$(file-append nar-herder "/bin/nar-herder")
"import"
"--tag=unknown-if-for-master=true"
;; "--ensure-references-exist"
"--database=/var/lib/nar-herder/nar_herder.db"
narinfos)))
(let ((exit-code
(status:exit-val
(apply system* command))))
(unless (zero? exit-code)
(error
(simple-format
#f
"error: command failed (~A): ~A\n"
exit-code
command))))
(for-each
(lambda (narinfo)
(simple-format (current-error-port)
"deleting ~A\n"
narinfo)
(delete-file narinfo))
narinfos)))
#:derivation-substitute-urls
'("https://data.guix.gnu.org" "https://data.qa.guix.gnu.org"))
args)
#$(send-guix-data-service-event
'build-success-send-event-to-guix-data-service-hook)
(apply (@ (guix-build-coordinator hooks)
default-build-success-hook)
args)))
(build-failure
. ,#~(lambda args
#$recompress-log-file-hook
(apply ((@ (guix-build-coordinator hooks)
build-failure-retry-hook))
args)
#$(send-guix-data-service-event
'build-failure-send-event-to-guix-data-service-hook)
(apply (@ (guix-build-coordinator hooks)
default-build-failure-hook)
args)))
(build-canceled
. ,#~(lambda args
#$(send-guix-data-service-event
'build-canceled-send-event-to-guix-data-service-hook)
(apply (@ (guix-build-coordinator hooks)
default-build-canceled-hook)
args)))
(build-submit-outputs
. ,#~(begin
(use-modules (srfi srfi-1)
(guix-build-coordinator coordinator)
(guix-build-coordinator datastore))
(lambda (build-coordinator uuid)
(any (lambda (output)
(let* ((output-hash
(string-take
(string-drop (assq-ref output 'output) 11)
32))
(narinfo
(string-append #$publish-directory "/"
output-hash ".narinfo")))
(not (file-exists? narinfo))))
(datastore-list-build-outputs
(build-coordinator-datastore build-coordinator) uuid)))))))
(extra-environment-variables
'("GC_RETRY_SIGNALS=0")))))
(define %bffe-configuration
(bffe-configuration
(arguments
#~(let ((priority-for-derivation
(lambda (type system target)
(cond
((eq? type 'channel-instance)
(cond
((or (string=? system "x86_64-linux")
(string=? system "aarch64-linux"))
1000)
((or
;; i686-linux builds are getting stuck due to memory
;; issues, so use a lower priority
(string=? system "i686-linux")
;; prioritise package builds over channel instances for
;; riscv64-linux aaand powerpc64le-linux
(string=? system "riscv64-linux"))
0)
;; Prioritise packages for powerpc64le-linux
((string=? system "powerpc64le-linux") 700)
(else 900)))
((eq? type 'package)
(cond
((string=? target "none")
(if (or (string=? system "x86_64-linux")
(string=? system "aarch64-linux"))
800
700))
((string=? target "i586-pc-gnu") 650)
(else
;; Use a low priority for general cross builds
0)))
(else
0)))))
(list
#:build
(list
(build-from-guix-data-service
(data-service-url "https://data.guix.gnu.org")
(build-coordinator-url "http://127.0.0.1:8746")
(branches '("master"))
(systems '("x86_64-linux" "i686-linux"
"aarch64-linux"
"armhf-linux"
"powerpc64le-linux"
"riscv64-linux"
"i586-gnu"))
(systems-and-targets
(map (lambda (target)
(cons "x86_64-linux" target))
'("mips64el-linux-gnu"
"arm-linux-gnueabihf"
"aarch64-linux-gnu"
"powerpc-linux-gnu"
"powerpc64le-linux-gnu"
"riscv64-linux-gnu"
"i586-pc-gnu"
"i686-w64-mingw32"
"x86_64-w64-mingw32")))
(submit-builds-for-channel-instances? #t)
(build-priority priority-for-derivation)
(data-service-build-server-id 2)))
#:web-server-args
'(#:controller-args
(#:title "bordeaux.guix.gnu.org"
#:template-directory #$(local-file "nginx/html/bordeaux"
#:recursive? #t))))))))
;;;
;;; Operating system.
;;;
(operating-system
(host-name "bayfront")
(timezone "Europe/Paris")
(locale "en_US.UTF-8")
(bootloader (bootloader-configuration
(bootloader grub-bootloader)
(targets '("/dev/sda"))
(terminal-outputs '(console))))
(mapped-devices (list (mapped-device
(source (list "/dev/sda2" "/dev/sdb2"))
(target "/dev/md0")
(type raid-device-mapping))))
(file-systems (cons* (file-system
(device "/dev/md0")
(mount-point "/")
(type "ext4")
(dependencies mapped-devices))
%base-file-systems))
(swap-devices
(list (swap-space
(target "/swap"))))
(kernel linux-libre-5.10)
;; Add a kernel module for RAID-10.
(initrd-modules (cons "raid10" %base-initrd-modules))
(packages (cons* certbot wget iptables jnettop
mdadm vim lm-sensors openssh
nss-certs guix-build-coordinator
%base-packages))
(services
(cons*
(service static-networking-service-type
(list
(static-networking
(addresses
(list
(network-address
(device "ens10")
(value "185.233.100.56/25"))
(network-address
(device "ens10")
(value "2a0c:e300::58/48"))
(network-address
(device "ens9")
(value "185.233.100.57/25"))))
(routes
(list
(network-route
(destination "default")
(gateway "185.233.100.126"))
(network-route
(destination "default")
(gateway "2a0c:e300::126"))))
(name-servers
'("185.233.100.100" "185.233.100.101")))))
;; Make SSH and HTTP/HTTPS available over Tor.
(simple-service 'tor-hidden-service
tor-service-type
(list (tor-onion-service-configuration
(name "http")
(mapping
'((22 "127.0.0.1:22")
(80 "127.0.0.1:80")
(443 "127.0.0.1:443"))))))
(service tor-service-type)
(service prometheus-node-exporter-service-type)
(service ntp-service-type)
(service backup-service-type)
(service earlyoom-service-type)
;; DNS
(service knot-service-type
(knot-configuration
(zones (list (knot-zone-configuration
(inherit guix.gnu.org-zone)
(zonefile-load 'difference-no-serial)
(journal-content ''all) ;XXX: needed for difference-no-serial
;; (dnssec-policy "default")
(acl '("transfer-allow"
"gnu-transfer-old"
"gnu-transfer-new"))
(notify '("gnu-master-old"
"gnu-master-new")))))
(acls (list (knot-acl-configuration
(id "transfer-allow")
(address (list berlin-ip4))
(action '(transfer)))
(knot-acl-configuration
(id "gnu-transfer-old")
(address (list gnu-ns1-ip4/old))
(action '(transfer)))
(knot-acl-configuration
(id "gnu-transfer-new")
(address (list gnu-ns1-ip4/new))
(action '(transfer)))))
(remotes (list (knot-remote-configuration
(id "gnu-master-old")
(address (list gnu-ns1-ip4/old)))
(knot-remote-configuration
(id "gnu-master-new")
(address (list gnu-ns1-ip4/new)))))))
;; Runnning hpc.guix.info.
(simple-service 'guix-hpc-web-site
static-web-site-service-type
(list guix-hpc-web-site))
;; Running 10years.guix.gnu.org.
(simple-service 'ten-years-of-guix-web-site
static-web-site-service-type
(list ten-years-of-guix-web-site))
;; hpcguix-web as it can be seen at
;; <https://hpc.guix.info/browse>.
(service hpcguix-web-service-type
(hpcguix-web-configuration
(specs
#~(begin
(use-modules (guix channels))
(hpcweb-configuration
(title-prefix "Guix-HPC — ")
(package-filter-proc (const #t))
(main-page "/browse")
(menu '(("/about" "ABOUT")
("/browse" "PACKAGES")
("/channels" "CHANNELS")
("/events" "EVENTS")
("/blog" "BLOG")))
(channels #$%hpcguix-web-channels)
(channel-descriptions
#$%hpcguix-web-channel-descriptions))))))
(service certbot-service-type %certbot-configuration)
(service goggles-service-type)
(service goggles-bot-service-type
(goggles-bot-configuration
(channels '("#guix" "#guix-hpc" "#guile"
"#guile-steel" "#hurd"
"#bootstrappable"
"#ocapn" "#spritely"))))
(service qa-frontpage-service-type
(qa-frontpage-configuration
(submit-builds? #t)
(manage-patch-branches? #t)))
(service guix-packages-website-service-type)
(service mcron-service-type
(mcron-configuration
(jobs
(let ((threshold (* 1600 GiB)))
(list #~(job '(next-hour-from (next-day (range 1 31 7)) '(2))
(string-append
#$guix "/bin/guix gc"))
#~(job '(next-hour '(1))
(string-append
#$guix "/bin/guix gc -F"
#$(number->string threshold))))))))
firewall-service
(service wireguard-service-type
(wireguard-configuration
(addresses '("10.0.0.11/32"))
(peers (list berlin-wireguard-peer))))
(service openssh-service-type
(openssh-configuration
(password-authentication? #f)))
(service sysadmin-service-type %sysadmins)
(service nginx-service-type
(nginx-configuration
(global-directives
'((events . ((use . epoll)))
(worker_processes . 16)))
(modules
(list
;; Module to redirect users to the localized pages of their choice.
(file-append
nginx-accept-language-module
"/etc/nginx/modules/ngx_http_accept_language_module.so")))
(extra-content %bayfront-nginx-service-extra-config)
(upstream-blocks
(list (nginx-upstream-configuration
(name "guix-build-coordinator-proxy")
(servers '("localhost:8745")))
(nginx-upstream-configuration
(name "nar-herder")
(servers '("localhost:8734"))
(extra-content
'("keepalive 4;"
"keepalive_requests 10000;")))
(nginx-upstream-configuration
(name "nar-storage")
(servers '("hydra-guix-129.guix.gnu.org:443"))
(extra-content
'("keepalive 2;")))
(nginx-upstream-configuration
(name "qa-frontpage")
(servers '("localhost:8765")))
(nginx-upstream-configuration
(name "bffe")
(servers '("localhost:8767")))
(nginx-upstream-configuration
(name "packages")
(servers '("localhost:3000")))))
(server-blocks
(append %guix.gnu.org-http-nginx-servers
%hpc.guix.info-nginx-servers
%guix-hpc.bordeaux.inria.fr-nginx-servers
%ten-years-of-guix-nginx-servers
%logs.guix.gnu.org-nginx-servers
%bayfront.guix.gnu.org-nginx-servers
%bordeaux.guix.gnu.org-nginx-servers
%qa.guix.gnu.org-nginx-servers
%packages.guix.gnu.org-nginx-servers
%coordinator.bayfront.guix.gnu.org-nginx-servers))))
(service nar-herder-service-type
(nar-herder-configuration
;; To make it easy for the guix-build-coordinator hooks
;; to populate the database, run as the
;; guix-build-coordinator user
(user "guix-build-coordinator")
(group "guix-build-coordinator")
(storage "/var/lib/nars")
(storage-limit 0)
(storage-nar-removal-criteria
'((and (stored-on "https://hydra-guix-129.guix.gnu.org")
(stored-on "https://hatysa.cbaines.net"))))
(ttl "180d")
(log-level 'INFO)
(cached-compressions
(list
(nar-herder-cached-compression-configuration
(type 'zstd)
(level 19)
(directory-max-size (* 400 GiB)))))
(cached-compression-workers 8)
(cached-compression-nar-source "https://hydra-guix-129.guix.gnu.org")
(extra-environment-variables
'("GC_RETRY_SIGNALS=0"))))
(service guix-build-coordinator-service-type
%guix-build-coordinator-configuration)
(service bffe-service-type
%bffe-configuration)
(service guix-build-coordinator-agent-service-type
(guix-build-coordinator-agent-configuration
(coordinator "https://coordinator.bayfront.guix.gnu.org")
(authentication
(guix-build-coordinator-agent-password-file-auth
(uuid "0c973ac8-4e62-4889-87b4-31c9536641db")
(password-file
"/etc/guix-build-coordinator-agent-password")))
(max-parallel-builds 6)
(max-parallel-uploads 6)
(max-1min-load-average 18)
(systems '("x86_64-linux" "i686-linux"))
(derivation-substitute-urls
(list "https://data.guix.gnu.org"
"https://data.qa.guix.gnu.org"))
(non-derivation-substitute-urls
(list "https://bordeaux.guix.gnu.org"))))
(append
(website-services)
(modify-services %base-services
(guix-service-type
config => (guix-configuration
(substitute-urls
'("https://bordeaux.guix.gnu.org"))
(authorized-keys
(cons*
(local-file "keys/guix/bordeaux.guix.gnu.org-export.pub")
(local-file "keys/guix/data.guix.gnu.org.pub")
(local-file "keys/guix/data.qa.guix.gnu.org.pub")
%build-node-keys))
(max-silent-time (* 12 3600))
(timeout (* 48 3600))
;; be friendly to 'guix publish' users
(log-compression 'gzip)
(build-accounts 64)
(extra-options
(list "--max-jobs" "4" "--cores" "8"))))
(login-service-type
config => (login-configuration
(inherit config)
(motd %motd))))))))
;; Local Variables:
;; eval: (put 'modify-services 'scheme-indent-function 1)
;; End: