2022-01-13 21:27:08 +01:00
|
|
|
# Restic user backups
|
|
|
|
#
|
|
|
|
# This _assumes_ a few things:
|
|
|
|
# - There is a sops.secrets with the name "restic-backup-USERNAME"
|
|
|
|
# - That the repository is actually reachable, which is a little flaky still
|
2022-03-23 13:10:18 +01:00
|
|
|
{
|
|
|
|
nixosConfig,
|
|
|
|
pkgs,
|
|
|
|
lib,
|
|
|
|
config,
|
|
|
|
...
|
|
|
|
}: let
|
2022-01-13 21:27:08 +01:00
|
|
|
resticCmd = "${pkgs.restic}/bin/restic";
|
2022-05-30 18:35:52 +02:00
|
|
|
inherit (config.home) username;
|
2022-01-13 21:27:08 +01:00
|
|
|
|
2022-09-26 17:11:16 +02:00
|
|
|
repository = "rest:http://faunus-ater:8000/${username}";
|
2022-01-13 21:27:08 +01:00
|
|
|
passwordFile = nixosConfig.sops.secrets."restic-backup-${username}".path;
|
|
|
|
defaultPruneOpts = [
|
|
|
|
"--keep-hourly 5"
|
|
|
|
"--keep-daily 5"
|
|
|
|
"--keep-weekly 5"
|
|
|
|
"--keep-monthly 5"
|
|
|
|
"--keep-yearly 5"
|
|
|
|
];
|
|
|
|
sessionVars = {
|
|
|
|
RESTIC_REPOSITORY = repository;
|
|
|
|
RESTIC_PASSWORD_FILE = passwordFile;
|
|
|
|
};
|
|
|
|
|
|
|
|
cfg = config.services.restic;
|
|
|
|
in {
|
|
|
|
options.services.restic = with lib; {
|
|
|
|
enable = mkEnableOption "restic backup service";
|
|
|
|
|
|
|
|
paths = mkOption {
|
|
|
|
type = types.listOf types.str;
|
2022-03-23 13:10:18 +01:00
|
|
|
default = [];
|
2022-01-13 21:27:08 +01:00
|
|
|
description = "Paths to backup";
|
|
|
|
};
|
|
|
|
|
|
|
|
pruneOpts = mkOption {
|
|
|
|
type = types.listOf types.str;
|
|
|
|
default = defaultPruneOpts;
|
|
|
|
description = "Additional options for pruning";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
|
|
# Add restic for the user (they will need to initialize the repo)
|
2022-03-23 13:10:18 +01:00
|
|
|
home.packages = [pkgs.restic];
|
2022-01-13 21:27:08 +01:00
|
|
|
# Add the above env variables, so that using restic is easy for them
|
|
|
|
home.sessionVariables = sessionVars;
|
|
|
|
# Create a systemd service for the backup
|
2022-09-26 17:11:16 +02:00
|
|
|
systemd.user.services.restic-backups-to-faunus-ater = {
|
2022-01-13 21:27:08 +01:00
|
|
|
Unit = {
|
2022-09-26 17:11:16 +02:00
|
|
|
Description = "Backup to faunus-ater using restic";
|
2022-03-23 13:10:18 +01:00
|
|
|
After = ["network.target"];
|
2022-01-13 21:27:08 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
Service = {
|
|
|
|
Type = "oneshot";
|
|
|
|
ExecStart = [
|
|
|
|
# Start by backing up every directory requested
|
2022-09-26 17:11:16 +02:00
|
|
|
"${resticCmd} backup --cache-dir=%C/restic-backups-to-faunus-ater ${
|
2022-01-13 21:27:08 +01:00
|
|
|
toString cfg.paths
|
|
|
|
}"
|
|
|
|
# Prune old backups to keep the repo tidy
|
|
|
|
"${resticCmd} forget --prune ${toString cfg.pruneOpts}"
|
|
|
|
];
|
2022-09-26 17:11:16 +02:00
|
|
|
RuntimeDirectory = "restic-backups-to-faunus-ater";
|
|
|
|
CacheDirectory = "restic-backups-to-faunus-ater";
|
2022-01-13 21:27:08 +01:00
|
|
|
CacheDirectoryMode = "0700";
|
|
|
|
# Convert the above map of environment variables into a list
|
2023-04-19 02:10:55 +02:00
|
|
|
# of "KEY=VALUE" entries
|
2022-03-23 13:10:18 +01:00
|
|
|
Environment =
|
|
|
|
builtins.attrValues
|
2022-01-13 21:27:08 +01:00
|
|
|
(builtins.mapAttrs (k: v: "${k}=${v}") sessionVars);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
# Run the above service every hour
|
2022-09-26 17:11:16 +02:00
|
|
|
systemd.user.timers.restic-backups-to-faunus-ater = {
|
2022-03-23 13:10:18 +01:00
|
|
|
Unit = {Description = "Run restic backups every hour";};
|
|
|
|
Install = {WantedBy = ["timers.target"];};
|
2022-05-23 15:44:40 +02:00
|
|
|
Timer = {
|
|
|
|
OnCalendar = "hourly";
|
|
|
|
RandomizedDelaySec = "600";
|
|
|
|
};
|
2022-01-13 21:27:08 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|