mirror of
https://github.com/oddlama/nix-config.git
synced 2025-10-10 14:50:40 +02:00
87 lines
2.5 KiB
Nix
87 lines
2.5 KiB
Nix
{
|
|
config,
|
|
globals,
|
|
lib,
|
|
...
|
|
}:
|
|
let
|
|
inherit (lib)
|
|
attrValues
|
|
flip
|
|
mkIf
|
|
mkMerge
|
|
mkOption
|
|
types
|
|
;
|
|
in
|
|
{
|
|
options.backups.storageBoxes = mkOption {
|
|
description = "Backups to Hetzner Storage Boxes using restic";
|
|
default = { };
|
|
type = types.attrsOf (
|
|
types.submodule (submod: {
|
|
options = {
|
|
name = mkOption {
|
|
description = "The name of the storage box to backup to. The box must be defined in the globals. Defaults to the attribute name.";
|
|
default = submod.config._module.args.name;
|
|
type = types.str;
|
|
};
|
|
|
|
subuser = mkOption {
|
|
description = "The name of the storage box subuser as defined in the globals, mapping this user to a subuser id.";
|
|
type = types.str;
|
|
};
|
|
|
|
paths = mkOption {
|
|
description = "The paths to backup.";
|
|
type = types.listOf types.path;
|
|
};
|
|
};
|
|
})
|
|
);
|
|
};
|
|
|
|
config = mkIf (config.backups.storageBoxes != { }) {
|
|
age.secrets.restic-encryption-password.generator.script = "alnum";
|
|
age.secrets.restic-ssh-privkey.generator.script = "ssh-ed25519";
|
|
|
|
services.restic.backups = mkMerge (
|
|
flip map (attrValues config.backups.storageBoxes) (boxCfg: {
|
|
"storage-box-${boxCfg.name}" = {
|
|
hetznerStorageBox =
|
|
let
|
|
box = globals.hetzner.storageboxes.${boxCfg.name};
|
|
in
|
|
{
|
|
enable = true;
|
|
inherit (box) mainUser;
|
|
inherit (box.users.${boxCfg.subuser}) subUid path;
|
|
sshAgeSecret = "restic-ssh-privkey";
|
|
};
|
|
|
|
# A) We need to backup stuff from other users, so run as root.
|
|
# B) We also need to be root because the ssh key will only
|
|
# be accessible to root so whatever service is running cannot
|
|
# just access our backup server.
|
|
user = "root";
|
|
|
|
inherit (boxCfg) paths;
|
|
timerConfig = {
|
|
OnCalendar = "06:15";
|
|
RandomizedDelaySec = "3h";
|
|
Persistent = true;
|
|
};
|
|
initialize = true;
|
|
passwordFile = config.age.secrets.restic-encryption-password.path;
|
|
# We cannot prune ourselves, since the remote repository will be append-only
|
|
# pruneOpts = [
|
|
# "--keep-daily 14"
|
|
# "--keep-weekly 7"
|
|
# "--keep-monthly 12"
|
|
# "--keep-yearly 75"
|
|
# ];
|
|
};
|
|
})
|
|
);
|
|
};
|
|
}
|