summary refs log tree commit diff
path: root/nixos/modules/services/backup/tarsnap.nix
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2018-03-28 09:36:47 -0400
committerShea Levy <shea@shealevy.com>2018-03-28 09:36:47 -0400
commit05e375d7103ac51e2da917965c37246c99f1ae4f (patch)
tree7ec4e9a2f5b7b1e2dea7c3e059f5b40e1dac1569 /nixos/modules/services/backup/tarsnap.nix
parent335934a073d6024d54c71bf82d5f8baab13abe75 (diff)
parentc7d7abc51e5f9b9c7481a83c47b37508bf08b05b (diff)
downloadnixpkgs-05e375d7103ac51e2da917965c37246c99f1ae4f.tar
nixpkgs-05e375d7103ac51e2da917965c37246c99f1ae4f.tar.gz
nixpkgs-05e375d7103ac51e2da917965c37246c99f1ae4f.tar.bz2
nixpkgs-05e375d7103ac51e2da917965c37246c99f1ae4f.tar.lz
nixpkgs-05e375d7103ac51e2da917965c37246c99f1ae4f.tar.xz
nixpkgs-05e375d7103ac51e2da917965c37246c99f1ae4f.tar.zst
nixpkgs-05e375d7103ac51e2da917965c37246c99f1ae4f.zip
Merge remote-tracking branch 'origin/master' into staging
Diffstat (limited to 'nixos/modules/services/backup/tarsnap.nix')
-rw-r--r--nixos/modules/services/backup/tarsnap.nix67
1 files changed, 60 insertions, 7 deletions
diff --git a/nixos/modules/services/backup/tarsnap.nix b/nixos/modules/services/backup/tarsnap.nix
index 59e9d122fb5..4fc7c24813a 100644
--- a/nixos/modules/services/backup/tarsnap.nix
+++ b/nixos/modules/services/backup/tarsnap.nix
@@ -238,6 +238,20 @@ in
                   Whether to produce verbose logging output.
                 '';
               };
+              explicitSymlinks = mkOption {
+                type = types.bool;
+                default = false;
+                description = ''
+                  Whether to follow symlinks specified as archives.
+                '';
+              };
+              followSymlinks = mkOption {
+                type = types.bool;
+                default = false;
+                description = ''
+                  Whether to follow all symlinks in archive trees.
+                '';
+              };
             };
           }
         ));
@@ -285,12 +299,12 @@ 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" ];
 
-        path = [ pkgs.iputils pkgs.tarsnap pkgs.utillinux ];
+        path = with pkgs; [ iputils tarsnap utillinux ];
 
         # In order for the persistent tarsnap timer to work reliably, we have to
         # make sure that the tarsnap server is reachable after systemd starts up
@@ -300,10 +314,12 @@ in
           while ! ping -q -c 1 v1-0-0-server.tarsnap.com &> /dev/null; do sleep 3; done
         '';
 
-        script =
-          let run = ''tarsnap --configfile "/etc/tarsnap/${name}.conf" \
-                        -c -f "${name}-$(date +"%Y%m%d%H%M%S")" \
+        script = let
+          tarsnap = ''tarsnap --configfile "/etc/tarsnap/${name}.conf"'';
+          run = ''${tarsnap} -c -f "${name}-$(date +"%Y%m%d%H%M%S")" \
                         ${optionalString cfg.verbose "-v"} \
+                        ${optionalString cfg.explicitSymlinks "-H"} \
+                        ${optionalString cfg.followSymlinks "-L"} \
                         ${concatStringsSep " " cfg.directories}'';
           in if (cfg.cachedir != null) then ''
             mkdir -p ${cfg.cachedir}
@@ -313,7 +329,7 @@ in
               if [ ! -e ${cfg.cachedir}/firstrun ]; then
                 ( flock 10
                   flock -u 9
-                  tarsnap --configfile "/etc/tarsnap/${name}.conf" --fsck
+                  ${tarsnap} --fsck
                   flock 9
                 ) 10>${cfg.cachedir}/firstrun
               fi
@@ -329,7 +345,44 @@ 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 = with pkgs; [ iputils tarsnap utillinux ];
+
+        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.