feat(darwin): add kache build cache with R2 remote

Wire the kunobi-ninja/kache darwin module into the flake: global
RUSTC_WRAPPER, /etc/kache/config.toml pointing at the kache-build-cache
R2 bucket, and a launchd daemon whose wrapper loads sops-decrypted
KACHE_S3_* credentials at runtime (launchd does not inherit the shell
environment). Ignore the cf CLI's local cache dir.
This commit is contained in:
Rasyidan Akbar F. 2026-10-05 16:59:26 +07:00
commit 560d58bbde
4 changed files with 155 additions and 13 deletions

49
modules/darwin/kache.nix Normal file
View file

@ -0,0 +1,49 @@
{
inputs,
pkgs,
lib,
config,
...
}:
let
cfg = config.services.kache;
# launchd agents do not inherit the user shell environment, so the daemon
# would miss the sops-decrypted KACHE_S3_* credentials. This wrapper loads
# them from the runtime secret files, then execs the real daemon.
# Values are read at activation/runtime only - never baked into the store.
kacheDaemonWrapper = pkgs.writeShellScript "kache-daemon-wrapper" ''
secret_dir="''${XDG_CONFIG_HOME:-$HOME/.config}/secrets/global-env"
for secret_file in "$secret_dir"/KACHE_S3_*; do
[ -e "$secret_file" ] || continue
name="$(basename "$secret_file")"
case "$name" in
*[!A-Za-z0-9_]*) continue ;;
esac
export "$name=$(<"$secret_file")"
done
exec ${lib.getExe cfg.package} daemon run
'';
in
{
imports = [ inputs.kache.darwinModules.default ];
services.kache = {
enable = true;
daemon.enable = true;
settings.cache.remote = {
type = "s3";
bucket = "kache-build-cache";
endpoint = "https://bb8d9158f0640a3d950d2597f52e9104.r2.cloudflarestorage.com";
region = "auto";
};
};
# Point the upstream module's launchd agent at the credential wrapper.
launchd.user.agents.kache.serviceConfig.ProgramArguments = lib.mkForce [
"${kacheDaemonWrapper}"
];
}