From 09e381ecc405af2667c5ca4be81948008ed01b21 Mon Sep 17 00:00:00 2001 From: Dominik Polakovics Date: Tue, 14 Oct 2025 22:30:20 +0200 Subject: [PATCH] feat: add attic cache --- .sops.yaml | 5 +- hosts/nb/configuration.nix | 3 +- utils/modules/attic-cache/default.nix | 87 ++++++++++++++++++++++++++ utils/modules/attic-cache/secrets.yaml | 34 ++++++++++ 4 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 utils/modules/attic-cache/default.nix create mode 100644 utils/modules/attic-cache/secrets.yaml diff --git a/.sops.yaml b/.sops.yaml index 8958b8f..6d9e951 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -4,7 +4,7 @@ # for a more complex example. keys: - &bitwarden age14grjcxaq4h55yfnjxvnqhtswxhj9sfdcvyas4lwvpa8py27pjy2sv3g6v7 # nixos age key - - &dominik age16veg3fmvpfm7a89a9fc8dvvsxmsthlm70nfxqspr6t8vnf9wkcwsvdq38d + - &dominik age1exny8unxynaw03yu8ppahu5z28uermghr8ag34e7kdqnaduq9stsyettzz - &dominik2 age1v6p8dan2t3w9h94fz4flldl32082j3s9x6zqq7u5j66keth9aphsd6pvch - &git-server age106n5n3rrrss45eqqzz8pq90la3kqdtnw63uw0sfa2mahk5xpe30sxs5x58 - &web-02 age1gjm4c3swt8u88e36gf2qlg3syxfc0ly94u64c42f2tsf24npw4csa6e4fw @@ -94,12 +94,13 @@ creation_rules: - *netboot - *fw - *fw-new - - path_regex: utils/modules/plausible/[^/]+\.yaml$ + - path_regex: utils/modules/attic-cache/[^/]+\.yaml$ key_groups: - age: - *bitwarden - *dominik - *dominik2 + - *nb - path_regex: utils/modules/promtail/[^/]+\.yaml$ key_groups: - age: diff --git a/hosts/nb/configuration.nix b/hosts/nb/configuration.nix index 2236ff3..115c2a9 100644 --- a/hosts/nb/configuration.nix +++ b/hosts/nb/configuration.nix @@ -15,9 +15,10 @@ in { [ "${impermanence}/nixos.nix" ./utils/bento.nix - + ./utils/modules/sops.nix ./utils/modules/nur.nix + ./utils/modules/attic-cache ./modules/appimage.nix ./modules/desktop ./modules/development diff --git a/utils/modules/attic-cache/default.nix b/utils/modules/attic-cache/default.nix new file mode 100644 index 0000000..1b65bbc --- /dev/null +++ b/utils/modules/attic-cache/default.nix @@ -0,0 +1,87 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cacheUrl = "https://attic.cloonar.com"; + cacheName = "cloonar-nixos"; + publicKey = "cloonar-nixos:u0S8Q3CShMkXeBk/eo8iooqrcSBTwNGBxQDS9HfkseE="; + authTokenFile = config.sops.secrets.attic_auth_token.path; + + # Post-build hook script that pushes to Attic + atticPushHook = pkgs.writeShellScript "attic-push-hook" '' + #!${pkgs.bash}/bin/bash + set -euo pipefail + + # Load configuration from sops secrets at runtime + ATTIC_CACHE="${cacheName}" + ATTIC_URL="${cacheUrl}" + + # Check if we have the required configuration + if [[ -z "$ATTIC_CACHE" ]] || [[ -z "$ATTIC_URL" ]]; then + echo "Attic cache not configured, skipping push" >&2 + exit 0 + fi + + # Read the auth token from sops if available + ATTIC_AUTH_TOKEN=$(cat "${authTokenFile}") + + # Function to check if a path exists in cache + path_in_cache() { + local path="$1" + ${pkgs.attic-client}/bin/attic cache info "$ATTIC_CACHE" "$path" &>/dev/null + } + + # Function to push a path to cache + push_to_cache() { + local path="$1" + echo "Pushing $path to Attic cache..." >&2 + if ${pkgs.attic-client}/bin/attic push "$ATTIC_CACHE" "$path"; then + echo "Successfully pushed $path" >&2 + else + echo "Failed to push $path (non-fatal)" >&2 + fi + } + + # Read paths from stdin (provided by Nix post-build-hook) + while IFS= read -r path; do + if [[ -e "$path" ]]; then + # Check if already in cache before pushing + if ! path_in_cache "$path"; then + push_to_cache "$path" + else + echo "Path $path already in cache, skipping" >&2 + fi + fi + done + + echo "Attic cache push completed" >&2 + ''; + +in { + sops.secrets.attic_auth_token = { + sopsFile = ./secrets.yaml; + }; + + # Install attic client + environment.systemPackages = with pkgs; [ + attic-client + ]; + + # Configure Nix settings + nix.settings = { + substituters = [ cacheUrl ]; + trusted-public-keys = [ publicKey ]; + post-build-hook = atticPushHook; + }; + + # Create a systemd service for manual cache operations + systemd.services.attic-push-closure = { + description = "Push a closure to Attic cache"; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.bash}/bin/bash -c '${pkgs.attic-client}/bin/attic push ${cacheName} $CLOSURE_PATH'"; + EnvironmentFile = authTokenFile; + }; + }; +} diff --git a/utils/modules/attic-cache/secrets.yaml b/utils/modules/attic-cache/secrets.yaml new file mode 100644 index 0000000..8a41058 --- /dev/null +++ b/utils/modules/attic-cache/secrets.yaml @@ -0,0 +1,34 @@ +attic_auth_token: ENC[AES256_GCM,data:O9wRQe+llEvCE/9mx7VckgCY/5/ZryUFz+0qpgauFRsnNWiB31yOTXo1sOn1lPldGpfsSpUZnGDTLvg5S6mzZ9UYdhDTcSk6V+E9YV5wXLFJv6HGVVI7TVhkSSBIUrxx8sbQvC/hYQ+YQ0zzfreaIz7eMVbHgk+FNnNr3pFNcLYLTacugvMOyZDwkEJcKIFMcWj+zCGu90s3W7LutfudJ37LB4M9sU1Ifjj46NGTe3fAj+lmS1IyJ+2ZUlVoQd4pCbWB0wm3bTpwjJhDYhjQj5gJPuMjBQcCpP7uBvelcmBo+8V/LJ9HY6pRFxPlp48+tOwlGGrzb5WyqWPE3sP3F2eQj4EnlQoULrfi6ARO0xO4qs0FJhN2YhvHJYRyd9leNWNLIe1SdRQ9PK5ksvuoM1rTlbgrPotPYa1PkfmgFuWBMwI+hBf0+DMJtZxJpVES3WAcOuibZukeA5lvQ+AAFTpHRW8AiZF2ry3gWxStLsUrqNQTTt1gZQq6WrHbYbXr3DCuTXxqVLX4mXO1Slbm7JLxni7Sn5nCfUiKCAmFdxuL0L22RMa5yd9+7+wdcFJfhqu9pZ8U5KoTMuaJKnxp0KISog3gDVAfxkrrtfhLnHtJkkLB+/Aa3Ypqowle9iAq1I0IdH6Nzwl63C2nbqPafL5mcXkFMwPktHlkqrflUl/QKnJqBBvcgThdHZIbsQUq2xo589cpvDLouWL2xUHNpIqWotowF5m4n/iN53i6/cJayNpLWMEWWLtslXtG1CN7arjoYYJOuEqdzkqTjornSU7Q1kF6/eLgB8e2BVnMKfBT59F4sX2c6kuK0QXPohcpLWI1ZEYxnSv/44W0i/Ij5NvqZOQ1pEsyMIlPbuh37khw1gv+fMKrbEUUyquzHTX7DEGYEECzWjHQ3/WeDuRmiHlrZC/3StMf9888qm5v2yw/Vk5rQwNY1nbeTf8yWg47qKi2GgSSdsqrUrW5yWLs4MWKF2cSSDMC/kbgvGkHoS9KVI5dBGJhGuAf98tzOBO/UO39X0TjTzcay0AQ27/r8+QeIimviaZO41/GQOjoMzzSDHGxWEf2Nf/40nrM5Vcqj3I6hvRFE4u2m6jxCMqCqsIuy9avW8EuZyC6zJMoHSe/lUnYrx4tSUf3VhN85o6QSSJqfIFUN0jPQwNFpsz3X+A=,iv:X6xSygAtem7ekQruSZirdW/LKwf0kw+/Iq35wAcNyyQ=,tag:gRuPBxM5VeoJHimC6sbSow==,type:str] +sops: + age: + - recipient: age14grjcxaq4h55yfnjxvnqhtswxhj9sfdcvyas4lwvpa8py27pjy2sv3g6v7 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2ZnRYdjlOZHB3ZWNkVG42 + OWZDdGNjNmNoQmozeGlxSHBJSXNWTjc2VUE0ClZISko5d0piR3RRMGNNSVZjc2Rr + NnZHZWtCQytNeG5FeGQyRVBCcE9tdzAKLS0tIFdaVXBWK1ppYUpaQVJTUzVUOUR4 + Nmd6KzN5Unh2bFdyaEd6aTluUEt6aFEKfxYq7UwQOwSGUpXnS8+8EsqA8mk3a2oT + eCssbrBsKvjkqOMvDNieBah5h5k13r5JJKHIENkJK6rhTUkvxJUdaw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1exny8unxynaw03yu8ppahu5z28uermghr8ag34e7kdqnaduq9stsyettzz + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuZDI4V2RBWUIvVzhEUzBX + Tng2MTAyOHl1TDhnVTY3OG1YUkZLem1TSGd3Ckorbi9wRTlodFZnVkpkUDgwdTRi + ZUZOUFFMUENzQzQvbk9XNnZsWVRIRjgKLS0tIGxoUUYvTUsyZ3BweGlrdzRhSUxr + YzRBbEZZMyt2VVpiTFJQUi8vS1BpMXcK8zmi27Kvp+0ujLQ+UEnq90bHjq5j+EWu + CnaKbqpQzCm+7TphBDR7tmUj2QoS2P0EXwub3DZtjZv6lnyMeD2DXQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1v6p8dan2t3w9h94fz4flldl32082j3s9x6zqq7u5j66keth9aphsd6pvch + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvMldwQzhMOXhWcUYvSDFT + d29kRFNWZzZ2TkNIeFBTVk5HNjZMdmlOQWdBCkpmUjJDdHdXRzVZUzlVVGM2ak1l + dnlHMURTUjR3MEhwd2RLbGsvWkRIbncKLS0tIHNVQUl3QXBwUEM5ZzUyczlHUXA3 + UzVENGtNSnZVcDQvR1hDR2oyZDh5KzAKhg+AQNdiJM/RvCdMNLH5er25U+yvcnM2 + 4Z0rOkkYsT6TerZHLllbm5AAyOLnKUn4PhZFMvKvGhVbc1Xg9t2XDg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-10-14T20:22:06Z" + mac: ENC[AES256_GCM,data:dt+rZ7GTlooTFhQOxRQvVpqKJksEJC5I5vsjSQ6GWPsi4EewGl2NY2gyjF6bVjYj6DHWuw/Kp79KGzJajmlYtQFdL54ydjaJUz4oMhoKO3xR4TxshW9XYEfOWavlMVqHHZQ6mPR1pyWQkonzwyni9ug8XmOJ0cN2OmZmKwdWzZQ=,iv:6AJocLlXZcNGG3nuXLc+ycfm6OA/oZOUFqFw4OoBetU=,tag:Qpa1RKS1/nqbDiAL5Jrb7w==,type:str] + unencrypted_suffix: _unencrypted + version: 3.11.0