nixos/restic: init (#38948)
parent
8ef9f40cc3
commit
6db2057f00
@ -0,0 +1,150 @@ |
||||
{ config, lib, pkgs, ... }: |
||||
|
||||
with lib; |
||||
{ |
||||
options.services.restic.backups = mkOption { |
||||
description = '' |
||||
Periodic backups to create with Restic. |
||||
''; |
||||
type = types.attrsOf (types.submodule ({ name, config, ... }: { |
||||
options = { |
||||
passwordFile = mkOption { |
||||
type = types.str; |
||||
description = '' |
||||
Read the repository password from a file. |
||||
''; |
||||
example = "/etc/nixos/restic-password"; |
||||
|
||||
}; |
||||
|
||||
repository = mkOption { |
||||
type = types.str; |
||||
description = '' |
||||
repository to backup to. |
||||
''; |
||||
example = "sftp:backup@192.168.1.100:/backups/${name}"; |
||||
}; |
||||
|
||||
paths = mkOption { |
||||
type = types.listOf types.str; |
||||
default = []; |
||||
description = '' |
||||
Which paths to backup. |
||||
''; |
||||
example = [ |
||||
"/var/lib/postgresql" |
||||
"/home/user/backup" |
||||
]; |
||||
}; |
||||
|
||||
timerConfig = mkOption { |
||||
type = types.attrsOf types.str; |
||||
default = { |
||||
OnCalendar = "daily"; |
||||
}; |
||||
description = '' |
||||
When to run the backup. See man systemd.timer for details. |
||||
''; |
||||
example = { |
||||
OnCalendar = "00:05"; |
||||
RandomizedDelaySec = "5h"; |
||||
}; |
||||
}; |
||||
|
||||
user = mkOption { |
||||
type = types.str; |
||||
default = "root"; |
||||
description = '' |
||||
As which user the backup should run. |
||||
''; |
||||
example = "postgresql"; |
||||
}; |
||||
|
||||
extraBackupArgs = mkOption { |
||||
type = types.listOf types.str; |
||||
default = []; |
||||
description = '' |
||||
Extra arguments passed to restic backup. |
||||
''; |
||||
example = [ |
||||
"--exclude-file=/etc/nixos/restic-ignore" |
||||
]; |
||||
}; |
||||
|
||||
extraOptions = mkOption { |
||||
type = types.listOf types.str; |
||||
default = []; |
||||
description = '' |
||||
Extra extended options to be passed to the restic --option flag. |
||||
''; |
||||
example = [ |
||||
"sftp.command='ssh backup@192.168.1.100 -i /home/user/.ssh/id_rsa -s sftp'" |
||||
]; |
||||
}; |
||||
|
||||
initialize = mkOption { |
||||
type = types.bool; |
||||
default = false; |
||||
description = '' |
||||
Create the repository if it doesn't exist. |
||||
''; |
||||
}; |
||||
}; |
||||
})); |
||||
default = {}; |
||||
example = { |
||||
localbackup = { |
||||
paths = [ "/home" ]; |
||||
repository = "/mnt/backup-hdd"; |
||||
passwordFile = "/etc/nixos/secrets/restic-password"; |
||||
initialize = true; |
||||
}; |
||||
remotebackup = { |
||||
paths = [ "/home" ]; |
||||
repository = "sftp:backup@host:/backups/home"; |
||||
passwordFile = "/etc/nixos/secrets/restic-password"; |
||||
extraOptions = [ |
||||
"sftp.command='ssh backup@host -i /etc/nixos/secrets/backup-private-key -s sftp'" |
||||
]; |
||||
timerConfig = { |
||||
OnCalendar = "00:05"; |
||||
RandomizedDelaySec = "5h"; |
||||
}; |
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
config = { |
||||
systemd.services = |
||||
mapAttrs' (name: backup: |
||||
let |
||||
extraOptions = concatMapStrings (arg: " -o ${arg}") backup.extraOptions; |
||||
connectTo = elemAt (splitString ":" backup.repository) 1; |
||||
resticCmd = "${pkgs.restic}/bin/restic${extraOptions}"; |
||||
in nameValuePair "restic-backups-${name}" ({ |
||||
environment = { |
||||
RESTIC_PASSWORD_FILE = backup.passwordFile; |
||||
RESTIC_REPOSITORY = backup.repository; |
||||
}; |
||||
path = with pkgs; [ |
||||
openssh |
||||
]; |
||||
restartIfChanged = false; |
||||
serviceConfig = { |
||||
Type = "oneshot"; |
||||
ExecStart = "${resticCmd} backup ${concatStringsSep " " backup.extraBackupArgs} ${concatStringsSep " " backup.paths}"; |
||||
User = backup.user; |
||||
}; |
||||
} // optionalAttrs backup.initialize { |
||||
preStart = '' |
||||
${resticCmd} snapshots || ${resticCmd} init |
||||
''; |
||||
}) |
||||
) config.services.restic.backups; |
||||
systemd.timers = |
||||
mapAttrs' (name: backup: nameValuePair "restic-backups-${name}" { |
||||
wantedBy = [ "timers.target" ]; |
||||
timerConfig = backup.timerConfig; |
||||
}) config.services.restic.backups; |
||||
}; |
||||
} |
Loading…
Reference in new issue