Files
nix/modules/backups/cloud-hosts.nix

106 lines
3.0 KiB
Nix

{
lib,
config,
...
}:
let
cfg = config.cloud-host-backup;
in
{
options = {
cloud-host-backup = {
enable = lib.mkEnableOption "pull backups from cloud hosts via SFTP";
hosts = lib.mkOption {
type = lib.types.attrsOf (
lib.types.submodule {
options = {
hostname = lib.mkOption {
type = lib.types.str;
description = "SSH hostname of the cloud host";
};
username = lib.mkOption {
type = lib.types.str;
default = config.secrets.username;
description = "SSH username for the cloud host";
};
remotePath = lib.mkOption {
type = lib.types.str;
default = "/home";
description = "Remote path to backup";
};
excludePatterns = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Exclude patterns for restic";
default = [ ];
};
};
}
);
default = { };
example = {
andromache = {
hostname = "andromache.local";
};
};
};
b2Bucket = lib.mkOption {
type = lib.types.str;
description = "B2 bucket name";
};
passwordFile = lib.mkOption {
type = lib.types.str;
default = config.sops.secrets."restic_password".path;
};
sshKeyFile = lib.mkOption {
type = lib.types.str;
default = "/home/${config.secrets.username}/.ssh/id_ed25519";
description = "SSH private key file for authentication";
};
};
};
config = lib.mkIf cfg.enable {
sops.templates = lib.mapAttrs' (
hostName: hostCfg:
lib.nameValuePair "restic/repo-cloud-${hostName}" {
content = "b2:${config.sops.placeholder."b2_bucket_name"}:${hostName}/";
}
) cfg.hosts;
services.restic.backups = lib.mapAttrs' (
hostName: hostCfg:
lib.nameValuePair "cloud-${hostName}" {
repositoryFile = config.sops.templates."restic/repo-cloud-${hostName}".path;
passwordFile = cfg.passwordFile;
paths = [ "sftp:${hostCfg.username}@${hostCfg.hostname}:${hostCfg.remotePath}" ];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
};
initialize = true;
extraBackupArgs = [
"--one-file-system"
]
++ lib.optional (hostCfg.excludePatterns != [ ]) (
builtins.concatStringsSep " " (map (p: "--exclude ${p}") hostCfg.excludePatterns)
);
pruneOpts = [
"--keep-daily 7"
"--keep-weekly 4"
"--keep-monthly 6"
"--keep-yearly 1"
];
environmentFile = config.sops.templates."restic/b2-env".path;
extraOptions = [
"sftp.command=ssh -i ${cfg.sshKeyFile} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
];
}
) cfg.hosts;
};
}