mirror of
git://git.savannah.gnu.org/guix/maintenance.git
synced 2023-12-14 03:33:04 +01:00
fa245ea65b
For the build coordinator. This helps to avoid a backlog of build-started event hooks. * hydra/bayfront.scm (%guix-build-coordinator-configuration): Increase build-started from 2 to 6.
1143 lines
44 KiB
Scheme
1143 lines
44 KiB
Scheme
;; OS configuration for bayfront
|
||
;; Copyright © 2016-2022 Ludovic Courtès <ludo@gnu.org>
|
||
;; Copyright © 2016, 2017, 2018, 2019, 2020 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
|
||
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 "marusich")
|
||
(full-name "Chris Marusich")
|
||
(ssh-public-key (local-file "keys/ssh/marusich.pub"))
|
||
(restricted? #t))
|
||
(sysadmin (name "cbaines")
|
||
(full-name "Christopher Baines")
|
||
(ssh-public-key (local-file "keys/ssh/cbaines.pub")))
|
||
(sysadmin (name "dannym")
|
||
(full-name "Danny Milosavljevic")
|
||
(ssh-public-key (local-file "keys/ssh/dannym.pub"))
|
||
(restricted? #t))
|
||
(sysadmin (name "efraim")
|
||
(full-name "Efraim Flashner")
|
||
(ssh-public-key (local-file "keys/ssh/efraim.pub"))
|
||
(restricted? #t))
|
||
(sysadmin (name "kuba")
|
||
(full-name "Jakub Kądziołka")
|
||
(ssh-public-key (local-file "keys/ssh/kuba.pub"))
|
||
(restricted? #t))
|
||
(sysadmin (name "roptat")
|
||
(full-name "Julien Lepiller")
|
||
(ssh-public-key (local-file "keys/ssh/roptat.pub"))
|
||
(restricted? #t))
|
||
(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")))
|
||
|
||
;; Not a sysadmin in any sense, but has access for the length of their
|
||
;; Outreachy internship to speed up their work. nckx will help them.
|
||
(sysadmin (name "raghavgururajan")
|
||
(full-name "Raghav Gururajan")
|
||
(ssh-public-key (local-file "keys/ssh/raghavgururajan.pub"))
|
||
(restricted? #t))
|
||
(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 '("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
|
||
;; IPv4 address of "ns1.gnu.org".
|
||
"209.51.188.164")
|
||
|
||
(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")))))))
|
||
|
||
|
||
;;;
|
||
;;; 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"))))
|
||
|
||
(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=2048g; # 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 %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;")))
|
||
|
||
;; 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;")))
|
||
(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
|
||
'("
|
||
access_log /var/log/nginx/guix-hpc.access.log;
|
||
|
||
# Limit embedding in HTML frames.
|
||
add_header X-Frame-Options SAMEORIGIN;"))
|
||
(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
|
||
(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
|
||
'("
|
||
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-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")
|
||
(raw-content
|
||
(list %common-tls-options
|
||
"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-named-location-configuration
|
||
(name "nar-storage")
|
||
(body '("rewrite /internal/(.*) /$1 break;"
|
||
"proxy_pass https://nar-storage;"
|
||
"proxy_cache bordeaux-nar;"
|
||
"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 "~ \"\\/build\\/([a-z0-9-]{36})$\"")
|
||
;; At some point a detailed page for each build would be
|
||
;; nice, but for now, just show the log file.
|
||
(body '("rewrite /(.*) /$1/log last;")))
|
||
(nginx-location-configuration
|
||
(uri "~ /build/(.*)/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;"))))))
|
||
|
||
(list
|
||
(nginx-server-configuration
|
||
(server-name '("bordeaux.guix.gnu.org"))
|
||
(listen '("80 reuseport"
|
||
"[::]:80 reuseport"))
|
||
(root (local-file "nginx/html/bordeaux" #:recursive? #t))
|
||
(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 (local-file "nginx/html/bordeaux" #:recursive? #t))
|
||
(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 %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 . 4)))
|
||
(hooks
|
||
`((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))))))
|
||
#:post-publish-hook
|
||
(lambda (directory narinfo-filename nar-filename)
|
||
(let* ((narinfo
|
||
(string-append directory "/" narinfo-filename))
|
||
(command
|
||
(list #$(file-append nar-herder "/bin/nar-herder")
|
||
"import"
|
||
"--tag=unknown-if-for-master=true"
|
||
"--database=/var/lib/nar-herder/nar_herder.db"
|
||
narinfo)))
|
||
(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))))
|
||
(simple-format (current-error-port)
|
||
"deleting ~A\n"
|
||
narinfo)
|
||
(delete-file narinfo))))
|
||
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))))))))))
|
||
|
||
|
||
;;;
|
||
;;; 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))
|
||
(file-system
|
||
;; This is how Goggles' IRC network is currently configured :-)
|
||
(device "/home/rekado/.znc/users/bayfront-log/networks/libera/moddata/log")
|
||
(mount-point "/var/www/.well-known/all-logs")
|
||
(type "none")
|
||
(flags '(bind-mount))
|
||
(check? #f))
|
||
%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.
|
||
(tor-hidden-service "http"
|
||
'((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)
|
||
|
||
;; 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"))
|
||
(notify '("gnu-master")))))
|
||
(acls (list (knot-acl-configuration
|
||
(id "transfer-allow")
|
||
(address (list berlin-ip4))
|
||
(action '(transfer)))
|
||
(knot-acl-configuration
|
||
(id "gnu-transfer")
|
||
(address (list gnu-ns1-ip4))
|
||
(action '(transfer)))))
|
||
|
||
(remotes (list (knot-remote-configuration
|
||
(id "gnu-master")
|
||
(address (list gnu-ns1-ip4)))))))
|
||
|
||
;; 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))
|
||
|
||
(define site-config
|
||
(hpcweb-configuration
|
||
(title-prefix "Guix-HPC — ")
|
||
(package-filter-proc (const #t))
|
||
(package-page-extension-proc
|
||
(lambda (path)
|
||
(let ((url (string-append
|
||
"https://data.guix.gnu.org"
|
||
"/repository/1/branch/master/package/"
|
||
(basename path))))
|
||
`(div
|
||
(a (@ (href ,url))
|
||
"View package version history.")))))
|
||
(menu '(("/about" "ABOUT")
|
||
("/browse" "BROWSE")
|
||
("/blog" "BLOG")))
|
||
(channels #$%hpcguix-web-channels)))))))
|
||
|
||
(service certbot-service-type %certbot-configuration)
|
||
(service goggles-service-type)
|
||
|
||
(service mcron-service-type
|
||
(mcron-configuration
|
||
(jobs
|
||
(let ((threshold (* 800 GiB)))
|
||
(list #~(job '(next-hour '(4))
|
||
(string-append
|
||
#$guix "/bin/guix gc -F"
|
||
#$(number->string threshold)))
|
||
|
||
;; Half a day later, make sure
|
||
;; half of our quota is available.
|
||
#~(job '(next-hour '(16))
|
||
(string-append
|
||
#$guix "/bin/guix gc -F"
|
||
#$(number->string
|
||
(quotient threshold 2)))))))))
|
||
|
||
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 '("bishan.guix.gnu.org:443")))))
|
||
(server-blocks
|
||
(append %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
|
||
%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://bishan.guix.gnu.org")
|
||
(stored-on "https://hatysa.cbaines.net"))))
|
||
(ttl "180d")
|
||
(log-level 'INFO)))
|
||
|
||
(service guix-build-coordinator-service-type
|
||
%guix-build-coordinator-configuration)
|
||
|
||
(service guix-build-coordinator-queue-builds-service-type
|
||
(guix-build-coordinator-queue-builds-configuration
|
||
(systems '("x86_64-linux" "i686-linux"
|
||
"aarch64-linux"
|
||
"armhf-linux"
|
||
"powerpc64le-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")))))
|
||
|
||
(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 1)
|
||
(max-1min-load-average 8)
|
||
(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" "1" "--cores" "16"))))
|
||
(login-service-type
|
||
config => (login-configuration
|
||
(inherit config)
|
||
(motd %motd))))))))
|
||
|
||
;; Local Variables:
|
||
;; eval: (put 'modify-services 'scheme-indent-function 1)
|
||
;; End:
|