-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbackup.nix
125 lines (119 loc) · 3.31 KB
/
backup.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.backup;
hostname = config.networking.hostName;
defaultPaths = [
"/root"
"/home"
"/var/lib"
"/opt"
"/etc"
];
defaultExclude = [
"**/.cache"
"**/node_modules"
"**/cache"
"**/Cache"
"/var/lib/docker"
"/var/lib/containers" # podman
"/var/lib/systemd"
"/var/lib/libvirt"
"**/.rustup"
"**/.cargo"
"**/.docker"
"**/borg"
];
in
{
options.my.backup = {
enable = lib.mkEnableOption "backup";
paths = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Paths to backup. Appended to the list of defaultPaths";
};
exclude = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Paths to exclude. Appended to the list of defaultExclude";
};
repo = lib.mkOption {
type = lib.types.str;
description = "Borg repository to backup to. This is appended to `[email protected]:borg/`.";
};
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;
description = "Path to the file containing the SSH identity key";
};
};
config = lib.mkIf cfg.enable {
programs.ssh.knownHostsFiles = [
(pkgs.writeText "rsyncnet-keys" ''
zh5061.rsync.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJtclizeBy1Uo3D86HpgD3LONGVH0CJ0NT+YfZlldAJd
'')
]; # 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;
repo = "[email protected]:borg/" + cfg.repo;
encryption = {
mode = "repokey-blake2";
passCommand = "cat ${cfg.passFile}";
};
environment = {
BORG_RSH = "ssh -i ${cfg.sshKeyFile}";
BORG_REMOTE_PATH = "borg1";
BORG_EXIT_CODES = "modern";
BORG_RELOCATED_REPO_ACCESS_IS_OK = "yes";
};
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)
if [ "$exitStatus" -eq 0 ]; then
tag="v"
else
tag="rotating_light"
fi
${pkgs.curl}/bin/curl -sL -u $(cat ${config.sops.secrets."services/ntfy".path}) \
-H "Title: $title" \
-H "Tags: $tag" \
-d "$msg" \
https://ntfy.cything.io/backups > /dev/null
'';
prune.keep = {
within = "2d";
daily = 365;
};
extraPruneArgs = [ "--stats" ];
};
};
}