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

3
.gitignore vendored
View file

@ -13,3 +13,6 @@ result-*
# Neovim
modules/home/rsydn/programs/nvim/lazy-lock.json
# Cloudflare CLI (cf) local cache
.cloudflare/

101
flake.lock generated
View file

@ -215,20 +215,40 @@
"type": "github"
}
},
"kache": {
"inputs": {
"nixpkgs": "nixpkgs_2",
"rust-overlay": "rust-overlay_2",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1791194368,
"narHash": "sha256-Kbww7mmdUAASh1sbjdoqoosSA76EALJata+Aa8SJUnE=",
"owner": "kunobi-ninja",
"repo": "kache",
"rev": "7c27329c286e32c17a8dac05cff22442926ff719",
"type": "github"
},
"original": {
"owner": "kunobi-ninja",
"repo": "kache",
"type": "github"
}
},
"llm-agents": {
"inputs": {
"bun2nix": "bun2nix",
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs_2",
"nixpkgs": "nixpkgs_3",
"systems": "systems",
"treefmt-nix": "treefmt-nix"
"treefmt-nix": "treefmt-nix_2"
},
"locked": {
"lastModified": 1790918187,
"narHash": "sha256-F3py52yPDHBSKKkx4CzpTMc5KxzCBT+jLUIRNOYpr4Q=",
"lastModified": 1791175671,
"narHash": "sha256-1szYaEAFYPApOgy2HGLbqtVys8SIqk5mlvz9agPFLr0=",
"owner": "numtide",
"repo": "llm-agents.nix",
"rev": "20762f12777a611184868a1a4408bc42a014adf1",
"rev": "ba24820b562c0e1ff95d283a2e2e1debcbcbad83",
"type": "github"
},
"original": {
@ -240,8 +260,8 @@
"llm-agents-pinned": {
"inputs": {
"blueprint": "blueprint",
"nixpkgs": "nixpkgs_3",
"treefmt-nix": "treefmt-nix_2"
"nixpkgs": "nixpkgs_4",
"treefmt-nix": "treefmt-nix_3"
},
"locked": {
"lastModified": 1765334436,
@ -329,6 +349,22 @@
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1773597492,
"narHash": "sha256-hQ284SkIeNaeyud+LS0WVLX+WL2rxcVZLFEaK0e03zg=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "a07d4ce6bee67d7c838a8a5796e75dff9caa21ef",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1790600678,
"narHash": "sha256-6k3n7X2UsZ6tAlWTz99RimiZab+17tMUrw9sRUcELiA=",
@ -344,7 +380,7 @@
"type": "github"
}
},
"nixpkgs_3": {
"nixpkgs_4": {
"locked": {
"lastModified": 1764947035,
"narHash": "sha256-EYHSjVM4Ox4lvCXUMiKKs2vETUSL5mx+J2FfutM7T9w=",
@ -360,7 +396,7 @@
"type": "github"
}
},
"nixpkgs_4": {
"nixpkgs_5": {
"locked": {
"lastModified": 1770197578,
"narHash": "sha256-AYqlWrX09+HvGs8zM6ebZ1pwUqjkfpnv8mewYwAo+iM=",
@ -381,9 +417,10 @@
"chaotic": "chaotic",
"darwin": "darwin",
"home-manager": "home-manager_2",
"kache": "kache",
"llm-agents": "llm-agents",
"llm-agents-pinned": "llm-agents-pinned",
"nixpkgs": "nixpkgs_4",
"nixpkgs": "nixpkgs_5",
"nixpkgs-stable": "nixpkgs-stable",
"sops-nix": "sops-nix",
"try": "try"
@ -410,6 +447,27 @@
"type": "github"
}
},
"rust-overlay_2": {
"inputs": {
"nixpkgs": [
"kache",
"nixpkgs"
]
},
"locked": {
"lastModified": 1791101754,
"narHash": "sha256-y/GF+9B0t0TZ0nQiSRMqDXpr76yT7sdDbS/3GNLhzkE=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "dbc715a4b7c0ace63b9769a032d1dd34cd89e5bd",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": [
@ -461,6 +519,27 @@
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"kache",
"nixpkgs"
]
},
"locked": {
"lastModified": 1784369104,
"narHash": "sha256-47cxbcZODibHv3rELFQ9vZly0vUNkND/atn/U7HLeb0=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "df3c0640565d04a0261253cdd89fce78ec50168a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"treefmt-nix_2": {
"inputs": {
"nixpkgs": [
"llm-agents",
@ -481,7 +560,7 @@
"type": "github"
}
},
"treefmt-nix_2": {
"treefmt-nix_3": {
"inputs": {
"nixpkgs": [
"llm-agents-pinned",

View file

@ -24,6 +24,9 @@
try.url = "github:tobi/try";
try.inputs.nixpkgs.follows = "nixpkgs";
# Rust/C++ build cache (RUSTC_WRAPPER + launchd daemon, backed by R2)
kache.url = "github:kunobi-ninja/kache";
};
outputs =
@ -37,6 +40,7 @@
sops-nix,
chaotic,
try,
kache,
...
}:
let
@ -58,7 +62,11 @@
# No overlays needed for Darwin builds
# - gitOverlay: removed - was causing mypy to rebuild from source
# - chaotic: removed - only needed for NixOS, was causing nix to rebuild with failing tests
overlaysList = [ ];
# kache overlay (includes rust-overlay) so pkgs.kache builds with the
# toolchain pinned in kache's rust-toolchain.toml
overlaysList = [
kache.overlays.default
];
mkPkgs =
system:
@ -68,7 +76,10 @@
config.allowUnfree = true;
};
sharedDarwinModules = [ ./modules/darwin/system.nix ];
sharedDarwinModules = [
./modules/darwin/system.nix
./modules/darwin/kache.nix
];
sharedNixosModules = [
./modules/nixos/system.nix
chaotic.nixosModules.default

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}"
];
}