diff --git a/nixos/modules/services/backup/tarsnap.nix b/nixos/modules/services/backup/tarsnap.nix index c33aeb76cb0..88c847ed92c 100644 --- a/nixos/modules/services/backup/tarsnap.nix +++ b/nixos/modules/services/backup/tarsnap.nix @@ -299,7 +299,7 @@ in }) gcfg.archives); systemd.services = - mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}" { + (mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}" { description = "Tarsnap archive '${name}'"; requires = [ "network-online.target" ]; after = [ "network-online.target" ]; @@ -345,7 +345,50 @@ in CapabilityBoundingSet = [ "CAP_DAC_READ_SEARCH" ]; PermissionsStartOnly = "true"; }; - }) gcfg.archives; + }) gcfg.archives) // + + (mapAttrs' (name: cfg: nameValuePair "tarsnap-restore-${name}"{ + description = "Tarsnap restore '${name}'"; + requires = [ "network-online.target" ]; + + path = [ pkgs.iputils pkgs.tarsnap pkgs.utillinux ]; + + ## + preStart = '' + while ! ping -q -c 1 v1-0-0-server.tarsnap.com &> /dev/null; do sleep 3; done + ''; + + script = + let + tarsnap = ''tarsnap --configfile "/etc/tarsnap/${name}.conf"''; + lastArchive = ''$(${tarsnap} --list-archives | sort | tail -1)''; + run = ''${tarsnap} -x -f "${lastArchive}" ${optionalString cfg.verbose "-v"}''; + + in if (cfg.cachedir != null) then '' + mkdir -p ${cfg.cachedir} + chmod 0700 ${cfg.cachedir} + + ( flock 9 + if [ ! -e ${cfg.cachedir}/firstrun ]; then + ( flock 10 + flock -u 9 + ${tarsnap} --fsck + flock 9 + ) 10>${cfg.cachedir}/firstrun + fi + ) 9>${cfg.cachedir}/lockf + + exec flock ${cfg.cachedir}/firstrun ${run} + '' else "exec ${run}"; + + serviceConfig = { + Type = "oneshot"; + IOSchedulingClass = "idle"; + NoNewPrivileges = "true"; + CapabilityBoundingSet = [ "CAP_DAC_READ_SEARCH" ]; + PermissionsStartOnly = "true"; + }; + }) gcfg.archives); # Note: the timer must be Persistent=true, so that systemd will start it even # if e.g. your laptop was asleep while the latest interval occurred.