homelab/modules/homelab/backup/restic.nix
plasmagoat bcbcc8b17b
Some checks failed
Test / tests (push) Has been cancelled
/ OpenTofu (push) Has been cancelled
homelab framework module init (everything is a mess)
2025-07-28 02:05:13 +02:00

105 lines
3 KiB
Nix

{
config,
lib,
...
}:
with lib; let
cfg = config.homelab.backups;
# Get restic backend config if it exists
resticBackend = cfg.backends.restic or null;
resticEnabled = resticBackend.enable or false;
# Filter jobs that use the restic backend
resticJobs = filter (job: job.backend == "restic") cfg.jobs;
in {
options.homelab.backups.backends.restic = mkOption {
type = types.nullOr (types.submodule {
options = {
enable = mkEnableOption "Restic backup backend";
# Default restic options - these map directly to services.restic.backups.<name>
repository = mkOption {
type = types.str;
description = "Default repository for restic backups";
};
initialize = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Create the repository if it doesn't exist.
'';
};
passwordFile = mkOption {
type = types.nullOr types.path;
default = null;
description = "Default password file for restic repository";
};
environmentFile = mkOption {
type = types.nullOr types.path;
default = null;
description = "Default environment file for restic credentials";
};
paths = mkOption {
type = types.listOf types.str;
default = [];
description = "Default paths to backup";
};
exclude = mkOption {
type = types.listOf types.str;
default = [];
description = "Default exclude patterns";
};
timerConfig = mkOption {
type = types.attrs;
default = {
OnCalendar = "daily";
RandomizedDelaySec = "1h";
};
description = "Default timer configuration";
};
pruneOpts = mkOption {
type = types.listOf types.str;
default = [
"--keep-daily 7"
"--keep-weekly 4"
"--keep-monthly 6"
];
description = "Default pruning options";
};
# Allow any other restic options
extraOptions = mkOption {
type = types.attrs;
default = {};
description = "Additional default restic options";
};
};
});
default = null;
description = "Restic backend configuration";
};
config = mkIf (cfg.enable && resticEnabled && length resticJobs > 0) {
# Configure restic service for each job using the restic backend
services.restic.backups = listToAttrs (map (
job: let
# Get base config without the 'enable' field
baseConfig = removeAttrs resticBackend ["enable"];
# Merge extraOptions into base config
baseWithExtras = recursiveUpdate (removeAttrs baseConfig ["extraOptions"]) (baseConfig.extraOptions or {});
# Apply job-specific overrides
finalConfig = recursiveUpdate baseWithExtras job.backendOptions;
in
nameValuePair job.name finalConfig
)
resticJobs);
};
}