127 lines
4.4 KiB
Nix
127 lines
4.4 KiB
Nix
{
|
|
domain,
|
|
...
|
|
}: {
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}: let
|
|
repackedActive = true;
|
|
migrationWriteFreeze = false;
|
|
|
|
repackedSettings = config.services.atticd.settings // {
|
|
listen = "127.0.0.1:8082";
|
|
allowed-hosts = [ "cache.${domain}" ];
|
|
api-endpoint = if repackedActive then "https://cache.${domain}/" else "https://cache.${domain}/next/";
|
|
substituter-endpoint = if repackedActive then "https://cache.${domain}/" else "https://cache.${domain}/next/";
|
|
database.url = "sqlite:///var/lib/atticd-repacked/server.db?mode=rwc";
|
|
storage = {
|
|
type = "s3";
|
|
bucket = "nix-cache-hectic-lab";
|
|
endpoint = "https://hel1.your-objectstorage.com";
|
|
region = "hel1";
|
|
};
|
|
chunking = {
|
|
nar-size-threshold = 1048576;
|
|
min-size = 1048576;
|
|
avg-size = 2097152;
|
|
max-size = 4194304;
|
|
};
|
|
compression.type = "zstd";
|
|
};
|
|
|
|
repackedConfigFile = pkgs.runCommand "checked-atticd-repacked.toml" {
|
|
configFile = (pkgs.formats.toml { }).generate "server-repacked.toml" repackedSettings;
|
|
} ''
|
|
export ATTIC_SERVER_TOKEN_RS256_SECRET_BASE64="$(${lib.getExe pkgs.openssl} genrsa -traditional 4096 | ${pkgs.coreutils}/bin/base64 -w0)"
|
|
export ATTIC_SERVER_DATABASE_URL="sqlite://:memory:"
|
|
${lib.getExe config.services.atticd.package} --mode check-config -f $configFile
|
|
cat <$configFile >$out
|
|
'';
|
|
in {
|
|
hectic.services.attic = {
|
|
enable = true;
|
|
hostName = "cache.${domain}";
|
|
port = 8081;
|
|
environmentFile = config.sops.secrets."atticd/environment".path;
|
|
storage = {
|
|
bucket = "cache-hectic-lab";
|
|
endpoint = "https://hel1.your-objectstorage.com";
|
|
region = "hel1";
|
|
};
|
|
};
|
|
|
|
# Slow S3 chunk reads can exceed the SDK's default 20-second stall grace.
|
|
services.atticd.package = pkgs.attic-server.overrideAttrs (old: {
|
|
postPatch = (old.postPatch or "") + ''
|
|
substituteInPlace server/src/storage/s3.rs \
|
|
--replace-fail 'let mut builder = S3ConfigBuilder::from(&shared_config);' \
|
|
'let mut builder = S3ConfigBuilder::from(&shared_config)
|
|
.stalled_stream_protection(
|
|
aws_sdk_s3::config::StalledStreamProtectionConfig::enabled()
|
|
.grace_period(Duration::from_secs(120))
|
|
.build(),
|
|
);'
|
|
'';
|
|
});
|
|
|
|
services.atticd.settings = lib.mkIf repackedActive {
|
|
api-endpoint = lib.mkForce "https://cache.${domain}/previous/";
|
|
substituter-endpoint = "https://cache.${domain}/previous/";
|
|
};
|
|
services.atticd.mode = if migrationWriteFreeze || repackedActive then "api-server" else "monolithic";
|
|
|
|
systemd.services.atticd-repacked = {
|
|
wantedBy = [ "multi-user.target" ];
|
|
after = [ "network-online.target" ];
|
|
wants = [ "network-online.target" ];
|
|
|
|
serviceConfig = config.systemd.services.atticd.serviceConfig // {
|
|
ExecStart = "${lib.getExe config.services.atticd.package} -f ${repackedConfigFile} --mode monolithic";
|
|
EnvironmentFile = config.sops.secrets."atticd/environment".path;
|
|
StateDirectory = "atticd-repacked";
|
|
User = "atticd-repacked";
|
|
Group = "atticd-repacked";
|
|
};
|
|
};
|
|
|
|
services.nginx.virtualHosts."cache.${domain}" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
extraConfig = ''
|
|
client_max_body_size 0;
|
|
'';
|
|
locations."/" = {
|
|
proxyPass = if repackedActive then "http://127.0.0.1:8082" else "http://127.0.0.1:8081";
|
|
extraConfig = ''
|
|
# Allow quiet periods while Attic fetches NAR chunks from object storage.
|
|
proxy_read_timeout 300s;
|
|
'' + lib.optionalString (migrationWriteFreeze && !repackedActive) ''
|
|
# Quiesce the old writer during the final snapshot and verification.
|
|
limit_except GET {
|
|
deny all;
|
|
}
|
|
'';
|
|
};
|
|
locations."/next/" = {
|
|
proxyPass = "http://127.0.0.1:8082/";
|
|
extraConfig = ''
|
|
# Allow quiet periods while Attic fetches NAR chunks from object storage.
|
|
proxy_read_timeout 300s;
|
|
'';
|
|
};
|
|
locations."/previous/" = {
|
|
proxyPass = "http://127.0.0.1:8081/";
|
|
extraConfig = ''
|
|
# Legacy backend is exposed for read-only migration checks.
|
|
limit_except GET {
|
|
deny all;
|
|
}
|
|
# Allow quiet periods while Attic fetches NAR chunks from object storage.
|
|
proxy_read_timeout 300s;
|
|
'';
|
|
};
|
|
};
|
|
}
|