burrow/nixos/modules/burrow-nix-cache.nix
Conrad Kramer 002bd382e9
Some checks failed
Cache: Publish Nix / Publish Nix Cache (push) Waiting to run
Build Rust / Cargo Test (push) Successful in 4m14s
Build Site / Next.js Build (push) Failing after 6s
Infra: OpenTofu / OpenTofu (grafana) (push) Successful in 5s
Lint Governance / BEP Metadata (push) Successful in 0s
Build: Android / Android Rust Core Stub (push) Failing after 23s
Wire Forge-native release infrastructure
2026-06-07 05:51:12 -07:00

162 lines
4.9 KiB
Nix

{ config, lib, pkgs, ... }:
let
cfg = config.services.burrow.nixCache;
garageCfg = config.services.burrow.garage;
in
{
options.services.burrow.nixCache = {
enable = lib.mkEnableOption "Burrow Nix binary cache";
domain = lib.mkOption {
type = lib.types.str;
default = "nix.burrow.net";
description = "Public domain for the Burrow Nix binary cache.";
};
listenAddress = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = "Attic listen address.";
};
port = lib.mkOption {
type = lib.types.port;
default = 8080;
description = "Attic listen port.";
};
cacheName = lib.mkOption {
type = lib.types.str;
default = "burrow";
description = "Default public Attic cache name.";
};
environmentFile = lib.mkOption {
type = lib.types.path;
default = garageCfg.environmentFile;
description = "Environment file containing Attic JWT and Garage S3 credentials.";
};
adminTokenFile = lib.mkOption {
type = lib.types.path;
default = "/var/lib/burrow/nix-cache/admin-token";
description = "Host-local file containing the generated Attic admin token.";
};
ciPushTokenFile = lib.mkOption {
type = lib.types.path;
default = "/var/lib/burrow/nix-cache/ci-push-token";
description = "Host-local file containing the generated Attic CI push token.";
};
ciPushTokenValidity = lib.mkOption {
type = lib.types.str;
default = "1y";
description = "Validity duration for the generated Attic CI push token.";
};
};
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = garageCfg.enable;
message = "services.burrow.nixCache requires services.burrow.garage.enable = true.";
}
];
services.atticd = {
enable = true;
environmentFile = cfg.environmentFile;
settings = {
listen = "${cfg.listenAddress}:${toString cfg.port}";
allowed-hosts = [ cfg.domain ];
api-endpoint = "https://${cfg.domain}/";
require-proof-of-possession = true;
storage = {
type = "s3";
bucket = garageCfg.atticBucket;
region = garageCfg.region;
endpoint = "http://${garageCfg.apiListenAddress}:${toString garageCfg.apiPort}";
};
};
};
environment.systemPackages = [
pkgs.attic-client
];
services.caddy.virtualHosts."${cfg.domain}".extraConfig = ''
encode gzip zstd
reverse_proxy ${cfg.listenAddress}:${toString cfg.port}
'';
systemd.services.atticd = {
after = [ "burrow-garage-bootstrap.service" ];
wants = [ "burrow-garage-bootstrap.service" ];
requires = [ "burrow-garage-bootstrap.service" ];
};
systemd.services.burrow-nix-cache-bootstrap = {
description = "Bootstrap Burrow Nix binary cache";
after = [ "atticd.service" ];
requires = [ "atticd.service" ];
wantedBy = [ "multi-user.target" ];
path = [
pkgs.attic-client
pkgs.coreutils
];
serviceConfig = {
Type = "oneshot";
User = "root";
Group = "root";
};
script = ''
set -euo pipefail
install -d -m 0700 "$(dirname ${lib.escapeShellArg cfg.adminTokenFile})"
install -d -m 0700 "$(dirname ${lib.escapeShellArg cfg.ciPushTokenFile})"
for _ in $(seq 1 60); do
if (: > /dev/tcp/${cfg.listenAddress}/${toString cfg.port}) >/dev/null 2>&1; then
break
fi
sleep 1
done
if [ ! -s ${lib.escapeShellArg cfg.adminTokenFile} ]; then
umask 077
atticd-atticadm make-token \
--sub burrow-nix-cache-bootstrap \
--validity 10y \
--create-cache '*' \
--pull '*' \
--push '*' \
--delete '*' \
--configure-cache '*' \
--configure-cache-retention '*' \
> ${lib.escapeShellArg cfg.adminTokenFile}
fi
token="$(cat ${lib.escapeShellArg cfg.adminTokenFile})"
export HOME=/var/lib/burrow/nix-cache
install -d -m 0700 "$HOME"
attic login local http://${cfg.listenAddress}:${toString cfg.port} "$token" --set-default
if ! attic cache info ${lib.escapeShellArg "local:${cfg.cacheName}"} >/dev/null 2>&1; then
attic cache create --public --priority 39 ${lib.escapeShellArg "local:${cfg.cacheName}"}
fi
if [ ! -s ${lib.escapeShellArg cfg.ciPushTokenFile} ]; then
umask 077
atticd-atticadm make-token \
--sub burrow-ci-cache-publisher \
--validity ${lib.escapeShellArg cfg.ciPushTokenValidity} \
--pull ${lib.escapeShellArg cfg.cacheName} \
--push ${lib.escapeShellArg cfg.cacheName} \
> ${lib.escapeShellArg cfg.ciPushTokenFile}
fi
'';
};
};
}