mirror of
https://github.com/JulienMalka/snowfield.git
synced 2025-03-25 21:30:52 +01:00
135 lines
3.2 KiB
Nix
135 lines
3.2 KiB
Nix
{
|
|
lib,
|
|
config,
|
|
...
|
|
}:
|
|
|
|
let
|
|
cfg = config.services.backup;
|
|
# We backup on gustave
|
|
host = "gustave.luj";
|
|
port = "45";
|
|
hostPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDJrHUzjPX0v2FX5gJALCjEJaUJ4sbfkv8CBWc6zm0Oe";
|
|
sshKey = config.age.secrets."borg-ssh-key".path;
|
|
secretPath = config.age.secrets."borg-encryption-secret".path;
|
|
|
|
in
|
|
{
|
|
options.services.backup =
|
|
with lib;
|
|
with types;
|
|
{
|
|
quota = mkOption {
|
|
type = nullOr str;
|
|
default = null;
|
|
example = "90G";
|
|
description = ''
|
|
Quota for the borg repository. Useful to prevent the target disk from running full and ensuring borg keeps some space to work with.
|
|
'';
|
|
};
|
|
|
|
includes = mkOption {
|
|
type = listOf path;
|
|
default = [ ];
|
|
description = ''
|
|
Paths to include in the backup.
|
|
'';
|
|
};
|
|
|
|
excludes = mkOption {
|
|
type = listOf path;
|
|
default = [ ];
|
|
description = ''
|
|
Paths to exclude in the backup.
|
|
'';
|
|
};
|
|
|
|
preHook = mkOption {
|
|
type = lines;
|
|
default = "";
|
|
description = ''
|
|
Shell commands to run before the backup.
|
|
'';
|
|
};
|
|
|
|
postHook = mkOption {
|
|
type = lines;
|
|
default = "";
|
|
description = ''
|
|
Shell commands to run after the backup.
|
|
'';
|
|
};
|
|
|
|
wantedUnits = mkOption {
|
|
type = listOf str;
|
|
default = [ ];
|
|
description = ''
|
|
List of units to require before starting the backup.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf (cfg.includes != [ ]) {
|
|
|
|
age.secrets."borg-ssh-key" = {
|
|
file = ../../secrets/borg-ssh-priv.age;
|
|
owner = "root";
|
|
mode = "0600";
|
|
};
|
|
|
|
age.secrets."borg-encryption-secret".file = ../../secrets/borg-encryption-secret.age;
|
|
|
|
programs.ssh.knownHosts."${if port != 22 then "[${host}]:${port}" else host}" = {
|
|
publicKey = "${hostPublicKey}";
|
|
};
|
|
|
|
systemd.services.borgbackup-job-state = {
|
|
wants = cfg.wantedUnits;
|
|
after = cfg.wantedUnits;
|
|
};
|
|
|
|
systemd.timers.borgbackup-job-state.timerConfig = {
|
|
# Spread all backups over the day
|
|
RandomizedDelaySec = "30m";
|
|
FixedRandomDelay = true;
|
|
};
|
|
|
|
services.borgbackup.jobs.state = {
|
|
inherit (cfg) preHook postHook;
|
|
|
|
# Create the repo
|
|
doInit = true;
|
|
|
|
# Create daily backups, but prune to a reasonable amount
|
|
startAt = [ "hourly" ];
|
|
prune.keep = {
|
|
daily = 7;
|
|
weekly = 4;
|
|
monthly = 3;
|
|
};
|
|
|
|
# What to backup
|
|
paths = cfg.includes;
|
|
exclude = cfg.excludes;
|
|
|
|
# Where to backup it to
|
|
repo = "borg@gustave.luj:${config.networking.hostName}";
|
|
environment.BORG_RSH = "ssh -p ${port} -i ${sshKey}";
|
|
|
|
# Ensure we don't fill up the destination disk
|
|
extraInitArgs = lib.optionalString (cfg.quota != null) "--storage-quota ${cfg.quota}";
|
|
|
|
# Authenticated & encrypted, key resides in the repository
|
|
encryption = {
|
|
mode = "repokey-blake2";
|
|
passCommand = "cat ${secretPath}";
|
|
};
|
|
|
|
# Reduce the backup size
|
|
compression = "auto,zstd";
|
|
|
|
# Show summary detailing data usage once completed
|
|
extraCreateArgs = "--stats";
|
|
};
|
|
};
|
|
}
|