guix-machines/.guix/rekahsoft/guix-config/vms/guix-ci0-home-rekahsoft-ca.scm

315 lines
12 KiB
Scheme

(define-module (rekahsoft guix-config vms guix-ci0-home-rekahsoft-ca)
#:use-module (gnu)
#:use-module (gnu system)
#:use-module (gnu packages shells)
#:use-module (gnu services base)
#:use-module (gnu services cuirass)
#:use-module (gnu services web)
#:use-module (rekahsoft guix-config proxmox-vm-lvm-minimal)
#:export (system))
(define base-system (proxmox-vm-lvm-minimal "guix-ci0"))
(define %cuirass-specs
#~(let ((rekahsoft-guix-channel
(channel
(name 'rekahsoft-guix)
(url "https://git.rekahsoft.ca/rekahsoft/rekahsoft-guix.git"))))
(list (specification
(name "rekahsoft-guix")
(priority 0)
(build '(channels rekahsoft-guix))
(channels
(cons rekahsoft-guix-channel
%default-channels)))
(specification
(name "rekahsoft-dotfiles")
(build '(manifests "home-manifest.scm"))
(channels
(cons* (channel
(name 'rekahsoft-dotfiles)
(url "https://git.home.rekahsoft.ca/rekahsoft-public/dotfiles.git"))
(channel
(name 'nonguix)
(url "https://gitlab.com/nonguix/nonguix"))
rekahsoft-guix-channel
%default-channels))))))
;; Taken from: https://git.savannah.gnu.org/cgit/guix/maintenance.git/tree/hydra/nginx/berlin.scm
(define (publish-locations url)
"Return the nginx location blocks for 'guix publish' running on URL."
(list (nginx-location-configuration
(uri "/nix-cache-info")
(body
(list
(string-append
"proxy_pass " url "/nix-cache-info;")
;; Cache this file since that's always the first thing we ask
;; for.
"proxy_cache static;"
"proxy_cache_valid 200 100d;" ; cache hits for a looong time.
"proxy_cache_valid any 5m;" ; cache misses/others for 5 min.
"proxy_ignore_client_abort on;"
;; We need to hide and ignore the Set-Cookie header to enable
;; caching.
"proxy_hide_header Set-Cookie;"
"proxy_ignore_headers Set-Cookie;")))
(nginx-location-configuration
(uri "/nar/")
(body
(list
(string-append "proxy_pass " url ";")
"client_body_buffer_size 256k;"
;; Be more tolerant of delays when fetching a nar.
"proxy_read_timeout 60s;"
"proxy_send_timeout 60s;"
;; Enable caching for nar files, to avoid reconstructing and
;; recompressing archives.
"proxy_cache nar;"
"proxy_cache_valid 200 30d;" ; cache hits for 1 month
"proxy_cache_valid 504 3m;" ; timeout, when hydra.gnu.org is overloaded
"proxy_cache_valid any 1h;" ; cache misses/others for 1h.
"proxy_ignore_client_abort on;"
;; Nars are already compressed.
"gzip off;"
;; We need to hide and ignore the Set-Cookie header to enable
;; caching.
"proxy_hide_header Set-Cookie;"
"proxy_ignore_headers Set-Cookie;"
;; Provide a 'content-length' header so that 'guix
;; substitute-binary' knows upfront how much it is downloading.
;; "add_header Content-Length $body_bytes_sent;"
)))
(nginx-location-configuration
(uri "~ \\.narinfo$")
(body
(list
;; Since 'guix publish' has its own caching, and since it relies
;; on the atime of cached narinfos to determine whether a
;; narinfo can be removed from the cache, don't do any caching
;; here.
(string-append "proxy_pass " url ";")
;; 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 600;"
;; Do not tolerate slowness of hydra.gnu.org when fetching
;; narinfos: better return 504 quickly than wait forever.
"proxy_connect_timeout 10s;"
"proxy_read_timeout 10s;"
"proxy_send_timeout 10s;"
;; 'guix publish --ttl' produces a 'Cache-Control' header for
;; use by 'guix substitute'. Let it through rather than use
;; nginx's "expire" directive since the expiration time defined
;; by 'guix publish' is the right one.
"proxy_pass_header Cache-Control;"
"proxy_ignore_client_abort on;"
;; We need to hide and ignore the Set-Cookie header to enable
;; caching.
"proxy_hide_header Set-Cookie;"
"proxy_ignore_headers Set-Cookie;")))
;; Content-addressed files served by 'guix publish'.
(nginx-location-configuration
(uri "/file/")
(body
(list
(string-append "proxy_pass " url ";")
"proxy_cache cas;"
"proxy_cache_valid 200 200d;" ; cache hits
"proxy_cache_valid any 5m;" ; cache misses/others
"proxy_ignore_client_abort on;")))))
(define %publish-url "http://localhost:3000")
;; Modified from: https://git.savannah.gnu.org/cgit/guix/maintenance.git/tree/hydra/nginx/berlin.scm (berlin-locations)
(define (nginx-locations publish-url)
"Return nginx location blocks with 'guix publish' reachable at
PUBLISH-URL."
(append (publish-locations publish-url)
(list
;; Cuirass.
(nginx-location-configuration
(uri "/")
(body (list "proxy_pass http://localhost:8081;")))
;; TODO: disabled as currently there is no auth setup for cuirass
;; (nginx-location-configuration
;; (uri "~ ^/admin")
;; (body
;; (list "if ($ssl_client_verify != SUCCESS) { return 403; } proxy_pass http://localhost:8081;")))
(nginx-location-configuration
(uri "/static")
(body
(list
"proxy_pass http://localhost:8081;"
;; Let browsers cache this for a while.
"expires 10d;"
;; Cache quite aggressively.
"proxy_cache static;"
"proxy_cache_valid 200 5d;"
"proxy_cache_valid any 10m;"
"proxy_ignore_client_abort on;"))))))
(define %extra-content
(list
"default_type application/octet-stream;"
"sendfile on;"
; (accept-languages)
;; 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
;; If Hydra cannot honor these delays, then something is wrong and
;; we'd better drop the connection and return 504.
"proxy_connect_timeout 10s;"
"proxy_read_timeout 10s;"
"proxy_send_timeout 10s;"
;; Cache timeouts for a little while to avoid increasing pressure.
"proxy_cache_valid 504 30s;"))
(define %nginx-configuration
(nginx-configuration
(server-blocks
(list
(nginx-server-configuration
(listen '("80"))
(server-name '("guix-ci0.home.rekahsoft.ca"
"guix-ci.home.rekahsoft.ca"
;; <https://logs.guix.gnu.org/guix/2021-11-20.log#155427>
"~[0-9]$"))
(locations (nginx-locations %publish-url))
(raw-content
(list
"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;")))))
(global-directives
'((worker_processes . 4)
(pcre_jit . on)
(events . ((worker_connections . 1024)))))
(extra-content
(string-join %extra-content "\n"))))
(define %nginx-cache-activation
;; Make sure /var/cache/nginx exists on the first run.
(simple-service 'nginx-/var/cache/nginx
activation-service-type
(with-imported-modules '((guix build utils))
#~(begin
(use-modules (guix build utils))
(mkdir-p "/var/cache/nginx")))))
(define system
(operating-system
(inherit base-system)
(users (cons*
(user-account
(name "collin")
(comment "Master User")
(group "users")
(shell #~(string-append #$zsh "/bin/zsh"))
(supplementary-groups
'("wheel" "netdev" "audio" "video"))
(home-directory "/home/collin"))
(operating-system-users base-system)))
(services
(append
(list (service cuirass-service-type
(cuirass-configuration
(host "localhost")
(specifications %cuirass-specs)
(use-substitutes? #t)))
%nginx-cache-activation
(service nginx-service-type %nginx-configuration)
(service guix-publish-service-type
(guix-publish-configuration
(port 3000)
(cache "/var/cache/guix/publish"))))
(modify-services %proxmox-vm-lvm-minimal-services
;; Add and authorize non-guix substitute server
(guix-service-type config =>
(guix-configuration
(inherit config)
(substitute-urls
(append (list "https://substitutes.nonguix.org")
(guix-configuration-substitute-urls config)))
(authorized-keys
(append (list (plain-file "non-guix.pub"
"(public-key
(ecc
(curve Ed25519)
(q #C1FD53E5D4CE971933EC50C9F307AE2171A2D3B52C804642A7A35F84F3A4EA98#)
)
)"))
(guix-configuration-authorized-keys config))))))))))