{ ... }: { flake.modules.nixos.backup = { pkgs, config, lib, ... }: let aqback-create = pkgs.writeShellScriptBin "aqback-create" '' ${pkgs.borgbackup}/bin/borg create --stats \ ${lib.concatStringsSep " " config.aquaticConfig.backup.extra} \ ${config.aquaticConfig.backup.repo}::{hostname}-{now} \ ${lib.concatStringsSep " " config.aquaticConfig.backup.dirs} ''; aqback-prune = pkgs.writeShellScriptBin "aqback-prune" '' ${pkgs.borgbackup}/bin/borg prune -s \ --keep-last 4 \ --keep-hourly ${config.aquaticConfig.backup.keep.hourly} \ --keep-daily ${config.aquaticConfig.backup.keep.daily} \ --keep-weekly ${config.aquaticConfig.backup.keep.weekly} \ --keep-monthly ${config.aquaticConfig.backup.keep.monthly} \ --keep-yearly ${config.aquaticConfig.backup.keep.yearly} \ ${config.aquaticConfig.backup.repo} ''; aqback-compact = pkgs.writeShellScriptBin "aqback-compact" '' ${pkgs.borgbackup}/bin/borg compact ${config.aquaticConfig.backup.repo} ''; notify-backup-failure = pkgs.writeShellScriptBin "notify-backup-failure" '' ${pkgs.curl}/bin/curl -s \ -H "Title: Backup Error" \ -H "Tags: warning" \ -d "${config.networking.hostName} - $1 failed" \ http://192.168.0.80:4351/etc-notifications ''; in { options.aquaticConfig.backup = { enable = lib.mkEnableOption "Enable Backups"; repo = lib.mkOption { description = "Where to backup to"; }; dirs = lib.mkOption { type = lib.types.listOf lib.types.str; default = []; description = "What to backup"; }; extra = lib.mkOption { type = lib.types.listOf lib.types.str; default = []; description = "Extra arguments for backup"; }; frequency = { create = lib.mkOption { default="*:0/15"; description = "How often to create a backup"; }; prune = lib.mkOption { default="0/2:07:0"; description = "How often to prune backups"; }; compact = lib.mkOption { default="*-*-1,14 01:07:00"; description = "How often compact backups"; }; }; keep = { hourly = lib.mkOption { default="24"; description = "How many hourly backups to keep"; }; daily = lib.mkOption { default="7"; description = "How many daily backups to keep"; }; weekly = lib.mkOption { default="4"; description = "How many weekly backups to keep"; }; monthly = lib.mkOption { default="6"; description = "How many monthly backups to keep"; }; yearly = lib.mkOption { default="3"; description = "How many yearly backups to keep"; }; }; }; config = { environment.systemPackages = [ aqback-create aqback-prune aqback-compact pkgs.borgbackup ]; systemd = { services = { backup-create = { enable = true; description = "Create a backup"; serviceConfig = { Type = "simple"; OnFailure = "backup-notify@%n.service"; ExecStart = "${pkgs.util-linux}/bin/flock /var/lock/borg-backup.lock ${aqback-create}/bin/aqback-create"; }; }; backup-prune = { enable = true; description = "Prune old backups"; serviceConfig = { Type = "simple"; OnFailure = "backup-notify@%n.service"; ExecStart = "${pkgs.util-linux}/bin/flock /var/lock/borg-backup.lock ${aqback-prune}/bin/aqback-prune"; }; }; backup-compact = { enable = true; description = "Compact backup repo"; serviceConfig = { Type = "simple"; OnFailure = "backup-notify@%n.service"; ExecStart = "${pkgs.util-linux}/bin/flock /var/lock/borg-backup.lock ${aqback-compact}/bin/aqback-compact"; }; }; "backup-notify@" = { description = "Notify on backup failure"; serviceConfig = { Type = "oneshot"; ExecStart = "${notify-backup-failure}/bin/notify-backup-failure %i"; }; }; }; timers = { backup-create = { wantedBy = [ "timers.target" ]; timerConfig = { OnCalendar = "${config.aquaticConfig.backup.frequency.create}"; Persistent=true; Unit = "backup-create.service"; }; }; backup-prune = { wantedBy = [ "timers.target" ]; timerConfig = { OnCalendar = "${config.aquaticConfig.backup.frequency.prune}"; Persistent=true; Unit = "backup-prune.service"; }; }; backup-compact = { wantedBy = [ "timers.target" ]; timerConfig = { OnCalendar= "${config.aquaticConfig.backup.frequency.compact}"; Persistent=true; Unit = "backup-compact.service"; }; }; }; }; }; }; }