{ lib, config, pkgs, utils, ... }: let cfg = config.backup-helper; restic-wrapper = pkgs.writeShellApplication { name = "restic-wrapper"; runtimeInputs = [ pkgs.restic ]; text = '' if [ -z "$BACKUP_HELPER_DIRS" ]; then echo "BACKUP_HELPER_DIRS is not set" exit 1; fi exit_code=0; for i in ''${BACKUP_HELPER_DIRS//,/ }; do echo "Starting backup of $i"; output=$(restic backup "$i"); if [ "$?" -ne 0 ]; then exit_code="$?"; echo "Backup of $i failed with exit code $?:" echo "$output" else echo "Backup of $i successful:" echo "$output" fi done exit "$exit_code"; ''; }; in { options.backup-helper.enable = lib.mkEnableOption "Enable backup-helper"; options.backup-helper = { restic-repository = lib.mkOption { type = lib.types.str; default = "rest:http://10.69.12.52:8000/backup-nix"; description = "Repository to use for restic backup."; }; backup-dirs = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; description = "Directories to be backed up."; }; schedule = lib.mkOption { type = lib.types.str; default = "*-*-* 00:00:00"; description = "Schedule for backups. Needs to be valid systemd OnCalendar value."; }; password-file = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; description = "File containing the restic password."; }; randomized-delay = lib.mkOption { type = lib.types.int; default = 0; description = "Randomized delay in seconds to spread out backups."; }; }; config = lib.mkIf cfg.enable { systemd.services."backup-helper" = { after = [ "network-online.target" ]; environment = { RESTIC_REPOSITORY = cfg.restic-repository; BACKUP_HELPER_DIRS = lib.strings.concatStringsSep "," cfg.backup-dirs; } // lib.attrsets.optionalAttrs (builtins.hasAttr "password-file" cfg) { RESTIC_PASSWORD_FILE = cfg.password-file; }; serviceConfig = { Type = "oneshot"; ExecStart = "${restic-wrapper}/bin/restic-wrapper"; }; }; systemd.timers."backup-helper" = { timerConfig = { OnCalendar = cfg.schedule; Persistent = true; RandomizedDelaySec = cfg.randomized-delay; }; wantedBy = [ "timers.target" ]; }; }; }