1{
2 config,
3 lib,
4 pkgs,
5 ...
6}: let
7 # idk how to share this across files :(
8 mkNotify = {
9 message,
10 channel,
11 priority ? 1,
12 }: ''
13 LOGIN=$(cat "${config.age.secrets.ntfyAuto.path}")
14 ${pkgs.curl}/bin/curl -u $LOGIN \
15 -H "X-Priority: ${toString priority}" \
16 -d '${message}' \
17 https://${config.mySnippets.aylac-top.networkMap.ntfy.vHost}/${channel}
18 '';
19
20 repoMap = {
21 A = "rclone:a_gdrive:/backups/${config.networking.hostName}";
22 B = "rclone:b_gdrive:/backups/${config.networking.hostName}";
23 };
24 mkRepo = {
25 repo,
26 service,
27 }: "${repoMap.${repo}}/${service}";
28
29 stop = {
30 service,
31 repoPath,
32 }: ''
33 #!${pkgs.bash}/bin/bash
34 ${mkNotify {
35 message = "Backing up ${service} to ${repoPath}, stopping service";
36 channel = "network-status";
37 }}
38 ${pkgs.systemd}/bin/systemctl stop ${service}
39 '';
40
41 start = {
42 service,
43 repoPath,
44 }: ''
45 #!${pkgs.bash}/bin/bash
46 ${mkNotify {
47 message = "Back up for ${service} to ${repoPath} was completed (idk if successfully tho), starting service";
48 channel = "network-status";
49 }}
50 ${pkgs.systemd}/bin/systemctl start ${service}
51 '';
52
53 prepareNoService = {
54 service,
55 repoPath,
56 }: ''
57 #!${pkgs.bash}/bin/bash
58 ${mkNotify {
59 message = "Backing up ${service} to ${repoPath}";
60 channel = "network-status";
61 }}
62 '';
63
64 cleanupNoService = {
65 service,
66 repoPath,
67 }: ''
68 #!${pkgs.bash}/bin/bash
69 ${mkNotify {
70 message = "Back up for ${service} to ${repoPath} was completed (idk if successfully tho)";
71 channel = "network-status";
72 }}
73 '';
74
75 mkBackups = services:
76 lib.listToAttrs (map (service: let
77 repoKey = service.repo or "A";
78 repoPath = mkRepo {
79 repo = repoKey;
80 service = service.name;
81 };
82 systemdService =
83 if service.containerised or false
84 then "container@" + service.name
85 else service.name;
86 backupMode = service.backupMode or "stop"; # "stop", "notify", "quiet"
87
88 commands =
89 if backupMode == "stop"
90 then {
91 backupCleanupCommand = start {
92 service = systemdService;
93 inherit repoPath;
94 };
95 backupPrepareCommand = stop {
96 service = systemdService;
97 inherit repoPath;
98 };
99 }
100 else if backupMode == "notify"
101 then {
102 backupCleanupCommand = cleanupNoService {
103 service = service.name;
104 inherit repoPath;
105 };
106 backupPrepareCommand = prepareNoService {
107 service = service.name;
108 inherit repoPath;
109 };
110 }
111 else {};
112 in
113 lib.nameValuePair service.name (
114 config.mySnippets.restic
115 // {
116 repository = repoPath;
117 inherit (service) paths;
118 }
119 // commands
120 // (service.extraConfig or {})
121 )) (lib.filter (s: s.enable) services));
122in {
123 options.myNixOS.profiles.backups = {
124 enable = lib.mkEnableOption "automatically back up enabled services";
125 };
126
127 config = lib.mkIf config.myNixOS.profiles.backups.enable {
128 services.restic.backups = mkBackups [
129 {
130 name = "audiobookshelf";
131 inherit (config.services.audiobookshelf) enable;
132 paths = [config.services.audiobookshelf.dataDir];
133 }
134 {
135 name = "bazarr";
136 inherit (config.services.bazarr) enable;
137 paths = [config.services.bazarr.dataDir];
138 }
139 {
140 name = "couchdb";
141 inherit (config.services.couchdb) enable;
142 paths = [config.services.couchdb.databaseDir];
143 }
144 {
145 name = "forgejo";
146 containerised = true;
147 inherit (config.services.forgejo) enable;
148 paths = [config.services.forgejo.stateDir];
149 backupMode = "none";
150 }
151 # {
152 # name = "immich";
153 # inherit (config.services.immich) enable;
154 # name = "immich-server";
155 # paths = [
156 # "${config.services.immich.mediaLocation}/library"
157 # "${config.services.immich.mediaLocation}/profile"
158 # "${config.services.immich.mediaLocation}/upload"
159 # "${config.services.immich.mediaLocation}/backups"
160 # ];
161 # repo = "B";
162 # }
163 {
164 name = "jellyfin";
165 inherit (config.services.jellyfin) enable;
166 paths = [config.services.jellyfin.dataDir];
167 }
168 {
169 name = "lidarr";
170 inherit (config.services.lidarr) enable;
171 paths = [config.services.lidarr.dataDir];
172 }
173 {
174 name = "ombi";
175 inherit (config.services.ombi) enable;
176 paths = [config.services.ombi.dataDir];
177 }
178 {
179 # damn this is ugly
180 name = "pds";
181 containerised = true;
182 inherit (config.myNixOS.services.pds) enable;
183 paths = ["/var/lib/nixos-containers/pds${config.containers.pds.config.services.bluesky-pds.settings.PDS_DATA_DIRECTORY}"];
184 }
185 {
186 name = "plex";
187 inherit (config.services.plex) enable;
188 paths = [config.services.plex.dataDir];
189 extraConfig = {
190 exclude = ["${config.services.plex.dataDir}/Plex Media Server/Plug-in Support/Databases"];
191 };
192 }
193 {
194 name = "postgresql";
195 containerised = true;
196 inherit (config.services.postgresql) enable;
197 paths = [config.services.postgresql.dataDir];
198 backupMode = "quiet";
199 }
200 {
201 name = "prowlarr";
202 inherit (config.services.prowlarr) enable;
203 paths = [config.services.prowlarr.dataDir];
204 }
205 {
206 name = "qbittorrent";
207 inherit (config.services.qbittorrent) enable;
208 paths = [config.services.qbittorrent.dataDir];
209 }
210 {
211 name = "radarr";
212 inherit (config.services.radarr) enable;
213 paths = [config.services.radarr.dataDir];
214 }
215 {
216 name = "readarr";
217 inherit (config.services.readarr) enable;
218 paths = [config.services.readarr.dataDir];
219 }
220 {
221 name = "sonarr";
222 inherit (config.services.sonarr) enable;
223 paths = [config.services.sonarr.dataDir];
224 }
225 {
226 name = "autobrr";
227 inherit (config.services.autobrr) enable;
228 paths = ["${config.myNixOS.profiles.arr.dataDir}/autobrr"];
229 }
230 {
231 name = "tautulli";
232 inherit (config.services.tautulli) enable;
233 paths = [config.services.tautulli.dataDir];
234 }
235 {
236 name = "uptime-kuma";
237 inherit (config.services.uptime-kuma) enable;
238 paths = ["/var/lib/uptime-kuma"];
239 }
240 {
241 name = "vaultwarden";
242 inherit (config.services.vaultwarden) enable;
243 paths = ["/var/lib/vaultwarden"];
244 }
245 {
246 name = "passwords";
247 enable = builtins.elem config.networking.hostName config.mySnippets.syncthing.folders."Passwords".devices;
248 paths = [config.mySnippets.syncthing.folders."Passwords".path];
249 backupMode = "notify";
250 }
251 {
252 name = "radicale";
253 inherit (config.services.radicale) enable;
254 paths = ["/var/lib/radicale"];
255 }
256 {
257 name = "webdav";
258 inherit (config.services.webdav-server-rs) enable;
259 paths = ["/var/lib/webdav"];
260 backupMode = "notify";
261 }
262 {
263 name = "miniflux";
264 inherit (config.services.miniflux) enable;
265 paths = ["/var/lib/miniflux"];
266 }
267 {
268 name = "jellyseerr";
269 inherit (config.services.jellyseerr) enable;
270 paths = ["/var/lib/jellyseerr"];
271 }
272 {
273 name = "tangled-knot";
274 inherit (config.services.tangled-knot) enable;
275 paths = [config.services.tangled-knot.stateDir];
276 }
277 ];
278 };
279}