diff --git a/nixos/modules/services/backup/tarsnap.nix b/nixos/modules/services/backup/tarsnap.nix
index 3a51e6b7aa6..78776786468 100644
--- a/nixos/modules/services/backup/tarsnap.nix
+++ b/nixos/modules/services/backup/tarsnap.nix
@@ -5,9 +5,9 @@ with lib;
let
cfg = config.services.tarsnap;
- configFile = cfg: ''
- cachedir ${config.services.tarsnap.cachedir}
- keyfile ${config.services.tarsnap.keyfile}
+ configFile = name: cfg: ''
+ cachedir ${config.services.tarsnap.cachedir}/${name}
+ keyfile ${cfg.keyfile}
${optionalString cfg.nodump "nodump"}
${optionalString cfg.printStats "print-stats"}
${optionalString cfg.printStats "humanize-numbers"}
@@ -41,6 +41,20 @@ in
account.
Create the keyfile with tarsnap-keygen.
+ Note that each individual archive (specified below) may also have its
+ own individual keyfile specified. Tarsnap does not allow multiple
+ concurrent backups with the same cache directory and key (starting a
+ new backup will cause another one to fail). If you have multiple
+ archives specified, you should either spread out your backups to be
+ far apart, or specify a separate key for each archive. By default
+ every archive defaults to using
+ "/root/tarsnap.key".
+
+ It's recommended for backups that you generate a key for every archive
+ using tarsnap-keygen(1), and then generate a
+ write-only tarsnap key using tarsnap-keymgmt(1),
+ and keep your master key(s) for a particular machine off-site.
+
The keyfile name should be given as a string and not a path, to
avoid the key being copied into the Nix store.
'';
@@ -57,6 +71,12 @@ in
will refuse to run until you manually rebuild the cache with
tarsnap --fsck.
+ Note that each individual archive (specified below) has its own cache
+ directory specified under cachedir; this is because
+ tarsnap locks the cache during backups, meaning multiple services
+ archives cannot be backed up concurrently or overlap with a shared
+ cache.
+
Set to null to disable caching.
'';
};
@@ -65,6 +85,28 @@ in
type = types.attrsOf (types.submodule (
{
options = {
+ keyfile = mkOption {
+ type = types.str;
+ default = config.services.tarsnap.keyfile;
+ description = ''
+ Set a specific keyfile for this archive. This defaults to
+ "/root/tarsnap.key" if left unspecified.
+
+ Use this option if you want to run multiple backups
+ concurrently - each archive must have a unique key. You can
+ generate a write-only key derived from your master key (which
+ is recommended) using tarsnap-keymgmt(1).
+
+ Note: every archive must have an individual master key. You
+ must generate multiple keys with
+ tarsnap-keygen(1), and then generate write
+ only keys from those.
+
+ The keyfile name should be given as a string and not a path, to
+ avoid the key being copied into the Nix store.
+ '';
+ };
+
nodump = mkOption {
type = types.bool;
default = true;
@@ -258,6 +300,7 @@ in
mkdir -p -m 0700 ${cfg.cachedir}
chown root:root ${cfg.cachedir}
chmod 0700 ${cfg.cachedir}
+ mkdir -p -m 0700 ${cfg.cachedir}/$1
DIRS=`cat /etc/tarsnap/$1.dirs`
exec tarsnap --configfile /etc/tarsnap/$1.conf -c -f $1-$(date +"%Y%m%d%H%M%S") $DIRS
'';
@@ -280,7 +323,7 @@ in
environment.etc =
(mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.conf"
- { text = configFile cfg;
+ { text = configFile name cfg;
}) cfg.archives) //
(mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.dirs"
{ text = concatStringsSep " " cfg.directories;