From ec70f64ecd3030192a4c31573da8f6e883621700 Mon Sep 17 00:00:00 2001 From: Austin Seipp Date: Thu, 7 Jan 2016 04:53:32 -0600 Subject: [PATCH 1/2] nixos: tarsnap - separate archive cachedirs Tarsnap locks the cachedir during backup, meaning if you specify multiple backups with a shared cache that might overlap (for example, one backup may take an hour), secondary backups will fail. This isn't very nice behavior for the obvious reasons. This splits the cache dirs for each archive appropriately. Note that this will require a rebuild of your archive caches (although if you were only using one archive for your whole system, you can just move the directory). Signed-off-by: Austin Seipp --- nixos/modules/services/backup/tarsnap.nix | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/nixos/modules/services/backup/tarsnap.nix b/nixos/modules/services/backup/tarsnap.nix index 3a51e6b7aa6..d9a57eedc9b 100644 --- a/nixos/modules/services/backup/tarsnap.nix +++ b/nixos/modules/services/backup/tarsnap.nix @@ -5,8 +5,8 @@ with lib; let cfg = config.services.tarsnap; - configFile = cfg: '' - cachedir ${config.services.tarsnap.cachedir} + configFile = name: cfg: '' + cachedir ${config.services.tarsnap.cachedir}/${name} keyfile ${config.services.tarsnap.keyfile} ${optionalString cfg.nodump "nodump"} ${optionalString cfg.printStats "print-stats"} @@ -57,6 +57,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. ''; }; @@ -258,6 +264,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 +287,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; From 7a01badef58ae91cbfa140df7f9f62f6bec5761e Mon Sep 17 00:00:00 2001 From: Austin Seipp Date: Thu, 7 Jan 2016 05:47:04 -0600 Subject: [PATCH 2/2] nixos: tarsnap - allow keys for individual archives Two concurrent tarsnap backups cannot be run at the same time with the same keys - completely separate sets of keys must be generated for each archive in this case, if you want backups to overlap. This extends the archives attrset to support a 'keyfile' option, which defaults to /root/tarsnap.key like the top-level attribute. With this change, if you generate two keys with tarsnap-keygen(1) and use each of those separately for each archive, you can backup concurrently. Signed-off-by: Austin Seipp --- nixos/modules/services/backup/tarsnap.nix | 38 ++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/nixos/modules/services/backup/tarsnap.nix b/nixos/modules/services/backup/tarsnap.nix index d9a57eedc9b..78776786468 100644 --- a/nixos/modules/services/backup/tarsnap.nix +++ b/nixos/modules/services/backup/tarsnap.nix @@ -7,7 +7,7 @@ let configFile = name: cfg: '' cachedir ${config.services.tarsnap.cachedir}/${name} - keyfile ${config.services.tarsnap.keyfile} + 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. ''; @@ -71,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;