2024-12-30 23:14:25 -05:00
|
|
|
{
|
|
|
|
config,
|
|
|
|
lib,
|
|
|
|
pkgs,
|
|
|
|
...
|
|
|
|
}:
|
|
|
|
let
|
2024-12-30 21:54:25 -05:00
|
|
|
cfg = config.my.backup;
|
|
|
|
hostname = config.networking.hostName;
|
|
|
|
defaultPaths = [
|
|
|
|
"/root"
|
|
|
|
"/home"
|
|
|
|
"/var/lib"
|
|
|
|
"/opt"
|
|
|
|
"/etc"
|
|
|
|
];
|
|
|
|
defaultExclude = [
|
|
|
|
"**/.cache"
|
|
|
|
"**/node_modules"
|
|
|
|
"**/cache"
|
|
|
|
"**/Cache"
|
|
|
|
"/var/lib/docker"
|
2024-12-30 23:30:31 -05:00
|
|
|
"/var/lib/containers" # podman
|
2024-12-30 21:54:25 -05:00
|
|
|
"/var/lib/systemd"
|
|
|
|
"/var/lib/libvirt"
|
|
|
|
"**/.rustup"
|
|
|
|
"**/.cargo"
|
|
|
|
"**/.docker"
|
|
|
|
"**/borg"
|
|
|
|
];
|
2024-12-30 23:14:25 -05:00
|
|
|
in
|
|
|
|
{
|
2024-12-30 21:54:25 -05:00
|
|
|
options.my.backup = {
|
|
|
|
enable = lib.mkEnableOption "backup";
|
|
|
|
paths = lib.mkOption {
|
|
|
|
type = lib.types.listOf lib.types.str;
|
2024-12-30 23:14:25 -05:00
|
|
|
default = [ ];
|
2024-12-30 21:54:25 -05:00
|
|
|
description = "Paths to backup. Appended to the list of defaultPaths";
|
|
|
|
};
|
|
|
|
exclude = lib.mkOption {
|
|
|
|
type = lib.types.listOf lib.types.str;
|
2024-12-30 23:14:25 -05:00
|
|
|
default = [ ];
|
2024-12-30 21:54:25 -05:00
|
|
|
description = "Paths to exclude. Appended to the list of defaultExclude";
|
|
|
|
};
|
|
|
|
repo = lib.mkOption {
|
|
|
|
type = lib.types.str;
|
2025-01-06 19:10:07 -05:00
|
|
|
description = "Borg repository to backup to. This is appended to `zh5061@zh5061.rsync.net:borg/`.";
|
2024-12-30 21:54:25 -05:00
|
|
|
};
|
|
|
|
startAt = lib.mkOption {
|
|
|
|
type = lib.types.str;
|
|
|
|
default = "hourly";
|
|
|
|
description = "see systemd.timer(5)";
|
|
|
|
};
|
|
|
|
jobName = lib.mkOption {
|
|
|
|
type = lib.types.str;
|
|
|
|
description = "Name of the job to run as. Archives created are prefixed with hostName-jobName";
|
|
|
|
};
|
|
|
|
passFile = lib.mkOption {
|
|
|
|
type = lib.types.str;
|
|
|
|
description = "Path to the file containing the encryption passphrase";
|
|
|
|
};
|
|
|
|
sshKeyFile = lib.mkOption {
|
|
|
|
type = lib.types.str;
|
2025-01-01 03:43:02 -05:00
|
|
|
description = "Path to the file containing the SSH identity key";
|
2024-12-30 21:54:25 -05:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
|
|
programs.ssh.knownHostsFiles = [
|
|
|
|
(pkgs.writeText "rsyncnet-keys" ''
|
2025-01-06 19:10:07 -05:00
|
|
|
zh5061.rsync.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJtclizeBy1Uo3D86HpgD3LONGVH0CJ0NT+YfZlldAJd
|
2024-12-30 21:54:25 -05:00
|
|
|
'')
|
|
|
|
]; # needs to be a list
|
|
|
|
|
|
|
|
services.borgbackup.jobs.${cfg.jobName} = {
|
|
|
|
inherit (cfg) startAt;
|
|
|
|
|
|
|
|
# systemd.timer(5)
|
|
|
|
persistentTimer = true;
|
|
|
|
paths = defaultPaths ++ cfg.paths;
|
|
|
|
exclude = defaultExclude ++ cfg.exclude;
|
2025-01-06 19:10:07 -05:00
|
|
|
repo = "zh5061@zh5061.rsync.net:borg/" + cfg.repo;
|
2024-12-30 21:54:25 -05:00
|
|
|
encryption = {
|
|
|
|
mode = "repokey-blake2";
|
|
|
|
passCommand = "cat ${cfg.passFile}";
|
|
|
|
};
|
|
|
|
environment = {
|
|
|
|
BORG_RSH = "ssh -i ${cfg.sshKeyFile}";
|
|
|
|
BORG_REMOTE_PATH = "borg1";
|
|
|
|
BORG_EXIT_CODES = "modern";
|
2025-01-06 19:10:07 -05:00
|
|
|
BORG_RELOCATED_REPO_ACCESS_IS_OK = "yes";
|
2024-12-30 21:54:25 -05:00
|
|
|
};
|
|
|
|
compression = "auto,zstd,8";
|
|
|
|
extraCreateArgs = [
|
|
|
|
"--stats"
|
|
|
|
"-x"
|
|
|
|
];
|
|
|
|
# warnings are often not that serious
|
|
|
|
failOnWarnings = false;
|
|
|
|
postHook = ''
|
|
|
|
invocationId=$(systemctl show -p InvocationID --value borgbackup-job-${cfg.jobName}.service)
|
|
|
|
title="${hostname}: backup completed with exit code: $exitStatus"
|
|
|
|
msg=$(journalctl -o cat _SYSTEMD_INVOCATION_ID=$invocationId)
|
|
|
|
|
2024-12-31 12:20:32 -05:00
|
|
|
if [ "$exitStatus" -eq 0 ]; then
|
|
|
|
tag="v"
|
|
|
|
else
|
|
|
|
tag="rotating_light"
|
|
|
|
fi
|
|
|
|
|
2024-12-30 23:14:25 -05:00
|
|
|
${pkgs.curl}/bin/curl -sL -u $(cat ${config.sops.secrets."services/ntfy".path}) \
|
2024-12-30 21:54:25 -05:00
|
|
|
-H "Title: $title" \
|
2024-12-31 12:20:32 -05:00
|
|
|
-H "Tags: $tag" \
|
2024-12-30 21:54:25 -05:00
|
|
|
-d "$msg" \
|
|
|
|
https://ntfy.cything.io/backups > /dev/null
|
|
|
|
'';
|
|
|
|
|
|
|
|
prune.keep = {
|
|
|
|
within = "2d";
|
|
|
|
daily = 365;
|
|
|
|
};
|
|
|
|
extraPruneArgs = [ "--stats" ];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|