# Importing this adds a daily borgbackup job to a node. # It has all the common config and keys, but can # be extended invidually to include more folders. { lib, config, ...}: let cfg = config.services.private-storage.borgbackup; inherit (config.grid) publicKeyPath privateKeyPath; # Get a per-host number of hours to start the backup at a # time that should be "night" in most of the USA: ip-util = import ../../nixos/lib/ip-util.nix; backupDelayHours = with builtins; bitAnd (ip-util.fromHexString (hashString "md5" config.networking.hostName)) 15; in { options.services.private-storage.borgbackup = { enable = lib.mkEnableOption "Borgbackup daily backup job"; paths = lib.mkOption { type = lib.types.listOf lib.types.str; description = '' A list of directories to back up using Borg. ''; default = [ "/storage" ]; }; }; config = lib.mkIf cfg.enable { deployment = { secrets = { "borgbackup-passphrase" = { # The passphrase is used to encrypt the repo key # https://borgbackup.readthedocs.io/en/stable/usage/init.html destination = "/run/keys/borgbackup/passphrase"; source = "${privateKeyPath}/borgbackup/${config.networking.hostName}.passphrase"; }; "borgbackup-appendonly-ssh-key" = { # The ssh key is used to authenticate to the remote repo server destination = "/run/keys/borgbackup/ssh-key"; source = "${privateKeyPath}/borgbackup/${config.networking.hostName}.ssh-key"; }; }; }; services.borgbackup.jobs = { daily = { paths = cfg.paths; repo = lib.fileContents "${publicKeyPath}/borgbackup/${config.networking.hostName}.repopath"; doInit = false; encryption = { mode = "repokey-blake2"; passCommand = "cat /run/keys/borgbackup/passphrase"; }; environment = { BORG_RSH = "ssh -i /run/keys/borgbackup/ssh-key"; }; compression = "none"; # Start the backup at a different time per machine, # and not at the full hour, but somewhat later startAt = "*-*-* " + toString backupDelayHours + ":22:11 UTC"; }; }; }; }