;; OS configuration for bayfront ;; Copyright © 2016-2022 Ludovic Courtès ;; Copyright © 2016, 2017, 2018, 2019, 2020 Andreas Enge ;; Copyright © 2017, 2019 Ricardo Wurmus ;; Copyright © 2019 Julien Lepiller ;; Copyright © 2020, 2021 Christopher Baines ;; Copyright © 2020, 2021 Tobias Geerinckx-Rice ;; Copyright © 2021 Mathieu Othacehe ;; 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, ;; . 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 , but also the nginx docs # mention that \"Without the limit, one fast connection may # seize the worker process entirely.\" # 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 . 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 ;; . (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: