lol

Add restore service for tarsnap archives

This service will never run automatically, but it encapsulates the
necessary logic and configuration to run a restore of the latest
archive, and allows to hook more specific logic, such as loading
a database dump, via `postStart`.

+45 -2
+45 -2
nixos/modules/services/backup/tarsnap.nix
··· 299 299 }) gcfg.archives); 300 300 301 301 systemd.services = 302 - mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}" { 302 + (mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}" { 303 303 description = "Tarsnap archive '${name}'"; 304 304 requires = [ "network-online.target" ]; 305 305 after = [ "network-online.target" ]; ··· 345 345 CapabilityBoundingSet = [ "CAP_DAC_READ_SEARCH" ]; 346 346 PermissionsStartOnly = "true"; 347 347 }; 348 - }) gcfg.archives; 348 + }) gcfg.archives) // 349 + 350 + (mapAttrs' (name: cfg: nameValuePair "tarsnap-restore-${name}"{ 351 + description = "Tarsnap restore '${name}'"; 352 + requires = [ "network-online.target" ]; 353 + 354 + path = [ pkgs.iputils pkgs.tarsnap pkgs.utillinux ]; 355 + 356 + ## 357 + preStart = '' 358 + while ! ping -q -c 1 v1-0-0-server.tarsnap.com &> /dev/null; do sleep 3; done 359 + ''; 360 + 361 + script = 362 + let 363 + tarsnap = ''tarsnap --configfile "/etc/tarsnap/${name}.conf"''; 364 + lastArchive = ''$(${tarsnap} --list-archives | sort | tail -1)''; 365 + run = ''${tarsnap} -x -f "${lastArchive}" ${optionalString cfg.verbose "-v"}''; 366 + 367 + in if (cfg.cachedir != null) then '' 368 + mkdir -p ${cfg.cachedir} 369 + chmod 0700 ${cfg.cachedir} 370 + 371 + ( flock 9 372 + if [ ! -e ${cfg.cachedir}/firstrun ]; then 373 + ( flock 10 374 + flock -u 9 375 + ${tarsnap} --fsck 376 + flock 9 377 + ) 10>${cfg.cachedir}/firstrun 378 + fi 379 + ) 9>${cfg.cachedir}/lockf 380 + 381 + exec flock ${cfg.cachedir}/firstrun ${run} 382 + '' else "exec ${run}"; 383 + 384 + serviceConfig = { 385 + Type = "oneshot"; 386 + IOSchedulingClass = "idle"; 387 + NoNewPrivileges = "true"; 388 + CapabilityBoundingSet = [ "CAP_DAC_READ_SEARCH" ]; 389 + PermissionsStartOnly = "true"; 390 + }; 391 + }) gcfg.archives); 349 392 350 393 # Note: the timer must be Persistent=true, so that systemd will start it even 351 394 # if e.g. your laptop was asleep while the latest interval occurred.