attic-client: init module

This commit is contained in:
Leon Schwarzäugl 2026-06-16 23:01:11 +02:00 committed by Austin Horstman
parent 0d33882bd4
commit 63d02d1c19
4 changed files with 173 additions and 0 deletions

View file

@ -0,0 +1,9 @@
{
time = "2026-07-06T00:46:00+00:00";
condition = true;
message = ''
A new module is available: `programs.attic-client`.
It manages the client configuration for the Attic Nix binary cache.
'';
}

View file

@ -0,0 +1,97 @@
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
mkOption
types
;
cfg = config.programs.attic-client;
settingsFormat = pkgs.formats.toml { };
in
{
options.programs.attic-client = {
enable = lib.mkEnableOption "the attic binary cache client";
package = lib.mkPackageOption pkgs "attic-client" {
nullable = true;
};
settings = mkOption {
inherit (settingsFormat) type;
default = { };
example = lib.literalExpression ''
{
default-server = "myserver";
servers.myserver = {
endpoint = "https://myserver.org";
token-file = "/run/secrets/attic-token";
};
}
'';
description = ''
Configuration written to
{file}`$XDG_CONFIG_HOME/attic/config.toml`.
See <https://github.com/zhaofengli/attic> for the available options.
'';
};
watchStore = mkOption {
type = types.listOf types.str;
default = [ ];
example = [ "mycacheserver:mycache" ];
description = ''
Caches to push new store paths to via `attic watch-store`.
Format: `server:cache` (or just `cache` to use the default server).
This relies on systemd and is only supported on Linux.
'';
};
};
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = cfg.watchStore == [ ] || pkgs.stdenv.hostPlatform.isLinux;
message = "programs.attic-client.watchStore requires systemd and is only supported on Linux.";
}
{
assertion = cfg.watchStore == [ ] || cfg.package != null;
message = "programs.attic-client.watchStore requires programs.attic-client.package to be set.";
}
];
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
xdg.configFile."attic/config.toml" = lib.mkIf (cfg.settings != { }) {
source = settingsFormat.generate "attic-config.toml" cfg.settings;
};
systemd.user.services = lib.mkIf (cfg.watchStore != [ ]) (
lib.listToAttrs (
map (
cache:
lib.nameValuePair "attic-watch-store--${lib.replaceStrings [ ":" ] [ "-" ] cache}" {
Unit.Description = "Push new store paths to the attic cache ${cache}";
Install.WantedBy = [ "default.target" ];
Service = {
ExecStart = "${lib.getExe cfg.package} watch-store ${cache}";
Restart = "always";
RestartSec = 30;
};
}
) cfg.watchStore
)
);
};
meta.maintainers = [ lib.maintainers.swarsel ];
}

View file

@ -0,0 +1,64 @@
{
config,
lib,
pkgs,
...
}:
let
inherit (pkgs.stdenv.hostPlatform) isLinux;
in
{
programs.attic-client = {
enable = true;
package = config.lib.test.mkStubPackage {
name = "attic";
outPath = "@attic@";
};
settings = {
default-server = "myserver";
servers = {
myserver = {
endpoint = "https://myserver.org";
token-file = "/run/secrets/attic-token";
};
myotherserver = {
endpoint = "https://myotherserver.org";
token-file = "/run/secrets/attic-token";
};
};
};
watchStore = lib.optionals isLinux [ "myserver:mycache" ];
};
nmt.script = ''
assertFileContent \
home-files/.config/attic/config.toml \
${builtins.toFile "expected.config" ''
default-server = "myserver"
[servers.myotherserver]
endpoint = "https://myotherserver.org"
token-file = "/run/secrets/attic-token"
[servers.myserver]
endpoint = "https://myserver.org"
token-file = "/run/secrets/attic-token"
''}
''
+ lib.optionalString isLinux ''
assertFileContent \
home-files/.config/systemd/user/attic-watch-store--myserver-mycache.service \
${builtins.toFile "expected.service" ''
[Install]
WantedBy=default.target
[Service]
ExecStart=@attic@/bin/attic watch-store myserver:mycache
Restart=always
RestartSec=30
[Unit]
Description=Push new store paths to the attic cache myserver:mycache
''}
'';
}

View file

@ -0,0 +1,3 @@
{
attic-client-basic-config = ./attic-client-basic-config.nix;
}