diff options
author | Austin Seipp <aseipp@pobox.com> | 2014-04-28 18:15:14 -0500 |
---|---|---|
committer | Austin Seipp <aseipp@pobox.com> | 2014-04-28 18:15:16 -0500 |
commit | 9242ed1fe297daf144fd4034af95d4fb0f0e3fa9 (patch) | |
tree | 2623212e8c62dea63d06841b9bd05b15704e5cda /nixos/modules/services/backup/tarsnap.nix | |
parent | 7faaa9e6daa79f40ae3725e97c463746d079f3ae (diff) |
nixos: refactor tarsnap module
The Tarsnap module is now far more flexible, allowing individual archives with individual options to be specified at will, allowing granular backup schedules, etc. Signed-off-by: Austin Seipp <aseipp@pobox.com>
Diffstat (limited to 'nixos/modules/services/backup/tarsnap.nix')
-rw-r--r-- | nixos/modules/services/backup/tarsnap.nix | 310 |
1 files changed, 180 insertions, 130 deletions
diff --git a/nixos/modules/services/backup/tarsnap.nix b/nixos/modules/services/backup/tarsnap.nix index 1966242e3dcbc..1b0bcadca1515 100644 --- a/nixos/modules/services/backup/tarsnap.nix +++ b/nixos/modules/services/backup/tarsnap.nix @@ -7,9 +7,9 @@ let optionalNullStr = e: v: if e == null then "" else v; - configFile = pkgs.writeText "tarsnap.conf" '' - cachedir ${cfg.cachedir} - keyfile ${cfg.keyfile} + configFile = cfg: '' + cachedir ${config.services.tarsnap.cachedir} + keyfile ${config.services.tarsnap.keyfile} ${optionalString cfg.nodump "nodump"} ${optionalString cfg.printStats "print-stats"} ${optionalNullStr cfg.checkpointBytes "checkpoint-bytes "+cfg.checkpointBytes} @@ -39,138 +39,174 @@ in ''; }; - label = mkOption { - type = types.str; - default = "nixos"; - description = '' - Specifies the label for archives created by Tarsnap. The - full name will be - <literal>label-$(date+"%Y%m%d%H%M%S")</literal>. For - example, by default your backups will look similar to - <literal>nixos-20140301011501</literal>. - ''; - }; - - cachedir = mkOption { - type = types.path; - default = "/var/cache/tarsnap"; - description = '' - Tarsnap operations use a "cache directory" which allows - Tarsnap to identify which blocks of data have been - previously stored; this directory is specified via the - <literal>cachedir</literal> option. If the cache directory - is lost or out of date, tarsnap creation/deletion operations - will exit with an error message instructing you to run - <literal>tarsnap --fsck</literal> to regenerate the cache - directory. - ''; - }; - keyfile = mkOption { type = types.path; default = "/root/tarsnap.key"; description = '' - Path to the keyfile which identifies the machine associated - with your Tarsnap account. This file can be created using - the <literal>tarsnap-keygen</literal> utility, and providing - your Tarsnap login credentials. - ''; - }; - - nodump = mkOption { - type = types.bool; - default = true; - description = '' - If set to <literal>true</literal>, then don't archive files - which have the <literal>nodump</literal> flag set. + Path to the keyfile which identifies the machine + associated with your Tarsnap account. This file can + be created using the + <literal>tarsnap-keygen</literal> utility, and + providing your Tarsnap login credentials. ''; }; - printStats = mkOption { - type = types.bool; - default = true; - description = "Print statistics when creating archives."; - }; - - checkpointBytes = mkOption { - type = types.nullOr types.str; - default = "1G"; - description = '' - Create a checkpoint per a particular amount of uploaded - data. By default, Tarsnap will create checkpoints once per - GB of data uploaded. At minimum, - <literal>checkpointBytes</literal> must be 1GB. - - Can also be set to <literal>null</literal> to disable - checkpointing. - ''; - }; - - period = mkOption { - type = types.str; - default = "15 01 * * *"; - description = '' - This option defines (in the format used by cron) when - tarsnap is run for backups. The default is to backup the - specified paths at 01:15 at night every day. - ''; - }; - - aggressiveNetworking = mkOption { - type = types.bool; - default = false; - description = '' - Aggressive network behaviour: Use multiple TCP connections - when writing archives. Use of this option is recommended - only in cases where TCP congestion control is known to be - the limiting factor in upload performance. - ''; - }; - - directories = mkOption { - type = types.listOf types.path; - default = []; - description = "List of filesystem paths to archive."; - }; - - excludes = mkOption { - type = types.listOf types.str; - default = []; - description = '' - Exclude files and directories matching the specified patterns. - ''; - }; - - includes = mkOption { - type = types.listOf types.str; - default = []; + cachedir = mkOption { + type = types.path; + default = "/var/cache/tarsnap"; description = '' - Include only files and directories matching the specified patterns. - - Note that exclusions specified via - <literal>excludes</literal> take precedence over inclusions. + Tarsnap operations use a "cache directory" which + allows Tarsnap to identify which blocks of data have + been previously stored; this directory is specified + via the <literal>cachedir</literal> option. If the + cache directory is lost or out of date, tarsnap + creation/deletion operations will exit with an error + message instructing you to run <literal>tarsnap + --fsck</literal> to regenerate the cache directory. ''; }; - lowmem = mkOption { - type = types.bool; - default = false; - description = '' - Attempt to reduce tarsnap memory consumption. This option - will slow down the process of creating archives, but may - help on systems where the average size of files being backed - up is less than 1 MB. + config = mkOption { + type = types.attrsOf (types.submodule ( + { + options = { + nodump = mkOption { + type = types.bool; + default = true; + description = '' + If set to <literal>true</literal>, then don't + archive files which have the + <literal>nodump</literal> flag set. + ''; + }; + + printStats = mkOption { + type = types.bool; + default = true; + description = "Print statistics when creating archives."; + }; + + checkpointBytes = mkOption { + type = types.nullOr types.str; + default = "1G"; + description = '' + Create a checkpoint per a particular amount of + uploaded data. By default, Tarsnap will create + checkpoints once per GB of data uploaded. At + minimum, <literal>checkpointBytes</literal> must be + 1GB. + + Can also be set to <literal>null</literal> to + disable checkpointing. + ''; + }; + + period = mkOption { + type = types.str; + default = "15 01 * * *"; + description = '' + This option defines (in the format used by cron) + when tarsnap is run for backups. The default is to + backup the specified paths at 01:15 at night every + day. + ''; + }; + + aggressiveNetworking = mkOption { + type = types.bool; + default = false; + description = '' + Aggressive network behaviour: Use multiple TCP + connections when writing archives. Use of this + option is recommended only in cases where TCP + congestion control is known to be the limiting + factor in upload performance. + ''; + }; + + directories = mkOption { + type = types.listOf types.path; + default = []; + description = "List of filesystem paths to archive."; + }; + + excludes = mkOption { + type = types.listOf types.str; + default = []; + description = '' + Exclude files and directories matching the specified + patterns. + ''; + }; + + includes = mkOption { + type = types.listOf types.str; + default = []; + description = '' + Include only files and directories matching the + specified patterns. + + Note that exclusions specified via + <literal>excludes</literal> take precedence over + inclusions. + ''; + }; + + lowmem = mkOption { + type = types.bool; + default = false; + description = '' + Attempt to reduce tarsnap memory consumption. This + option will slow down the process of creating + archives, but may help on systems where the average + size of files being backed up is less than 1 MB. + ''; + }; + + verylowmem = mkOption { + type = types.bool; + default = false; + description = '' + Try even harder to reduce tarsnap memory + consumption. This can significantly slow down + tarsnap, but reduces its memory usage by an + additional factor of 2 beyond what the + <literal>lowmem</literal> option does. + ''; + }; + }; + } + )); + + default = {}; + + example = literalExample '' + { + nixos = + { directories = [ "/home" "/root/ssl" ]; + }; + + gamedata = + { directories = [ "/var/lib/minecraft "]; + period = "*/30 * * * *"; + }; + } ''; - }; - verylowmem = mkOption { - type = types.bool; - default = false; description = '' - Try even harder to reduce tarsnap memory consumption. This - can significantly slow down tarsnap, but reduces its memory - usage by an additional factor of 2 beyond what the - <literal>lowmem</literal> option does. + Configuration of a Tarsnap archive. In the example, your + machine will have two tarsnap archives: + <literal>gamedata</literal> (backed up every 30 minutes) and + <literal>nixos</literal> (backed up at 1:15 AM every night by + default). You can control individual archive backups using + <literal>systemctl</literal>, using the + <literal>tarsnap@nixos</literal> or + <literal>tarsnap@gamedata</literal> units. For example, + <literal>systemctl start tarsnap@nixos</literal> will + immediately create a new NixOS archive. By default, archives + are suffixed with the timestamp of when they were started, + down to second resolution. This means you can use GNU + <literal>sort</literal> to sort output easily. ''; }; }; @@ -178,26 +214,40 @@ in config = mkIf cfg.enable { assertions = - [ { assertion = cfg.directories != []; + (mapAttrsToList (name: cfg: + { assertion = cfg.directories != []; message = "Must specify directories for Tarsnap to back up"; - } + }) cfg.config) ++ + (mapAttrsToList (name: cfg: { assertion = cfg.lowmem -> !cfg.verylowmem && (cfg.verylowmem -> !cfg.lowmem); message = "You cannot set both lowmem and verylowmem"; - } - ]; + }) cfg.config); + + systemd.services."tarsnap@" = { + description = "Tarsnap Backup of '%i'"; + requires = [ "network.target" ]; - systemd.services.tarsnap-backup = { - description = "Tarsnap Backup process"; path = [ pkgs.tarsnap pkgs.coreutils ]; + scriptArgs = "%i"; script = '' mkdir -p -m 0755 $(dirname ${cfg.cachedir}) mkdir -p -m 0600 ${cfg.cachedir} - exec tarsnap --configfile ${configFile} -c -f ${cfg.label}-$(date +"%Y%m%d%H%M%S") ${concatStringsSep " " cfg.directories} + DIRS=`cat /etc/tarsnap/$1.dirs` + exec tarsnap --configfile /etc/tarsnap/$1.conf -c -f $1-$(date +"%Y%m%d%H%M%S") $DIRS ''; }; - services.cron.systemCronJobs = optional cfg.enable - "${cfg.period} root ${config.systemd.package}/bin/systemctl start tarsnap-backup.service"; + services.cron.systemCronJobs = mapAttrsToList (name: cfg: + "${cfg.period} root ${config.systemd.package}/bin/systemctl start tarsnap@${name}" + ) cfg.config; + + environment.etc = + (mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.conf" + { text = configFile cfg; + }) cfg.config) // + (mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.dirs" + { text = concatStringsSep " " cfg.directories; + }) cfg.config); environment.systemPackages = [ pkgs.tarsnap ]; }; |