summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorMichishige Kaito <me@mkaito.com>2018-03-27 01:12:26 +0100
committerMichishige Kaito <me@mkaito.com>2018-03-27 01:19:02 +0100
commitbde525aaaff5cd99e79a21e30b9fdfdf2cd616d2 (patch)
tree9f1173d6fe89daab3e3f8f089b85f0a630bb6622 /nixos
parentd46259560030851e9a0ea73375779b9bf56e3b92 (diff)
downloadnixpkgs-bde525aaaff5cd99e79a21e30b9fdfdf2cd616d2.tar
nixpkgs-bde525aaaff5cd99e79a21e30b9fdfdf2cd616d2.tar.gz
nixpkgs-bde525aaaff5cd99e79a21e30b9fdfdf2cd616d2.tar.bz2
nixpkgs-bde525aaaff5cd99e79a21e30b9fdfdf2cd616d2.tar.lz
nixpkgs-bde525aaaff5cd99e79a21e30b9fdfdf2cd616d2.tar.xz
nixpkgs-bde525aaaff5cd99e79a21e30b9fdfdf2cd616d2.tar.zst
nixpkgs-bde525aaaff5cd99e79a21e30b9fdfdf2cd616d2.zip
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`.
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/services/backup/tarsnap.nix47
1 files changed, 45 insertions, 2 deletions
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.