| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  | { config, lib, pkgs, utils, ... }: | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-14 16:26:48 +02:00
										 |  |  | with lib; | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | let | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |   gcfg = config.services.tarsnap; | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-07 04:53:32 -06:00
										 |  |  |   configFile = name: cfg: ''
 | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |     keyfile ${cfg.keyfile} | 
					
						
							|  |  |  |     ${optionalString (cfg.cachedir != null) "cachedir ${cfg.cachedir}"} | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  |     ${optionalString cfg.nodump "nodump"} | 
					
						
							|  |  |  |     ${optionalString cfg.printStats "print-stats"} | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |     ${optionalString cfg.printStats "humanize-numbers"} | 
					
						
							| 
									
										
										
										
											2015-04-04 11:33:05 +02:00
										 |  |  |     ${optionalString (cfg.checkpointBytes != null) ("checkpoint-bytes "+cfg.checkpointBytes)} | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  |     ${optionalString cfg.aggressiveNetworking "aggressive-networking"} | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |     ${concatStringsSep "\n" (map (v: "exclude ${v}") cfg.excludes)} | 
					
						
							|  |  |  |     ${concatStringsSep "\n" (map (v: "include ${v}") cfg.includes)} | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  |     ${optionalString cfg.lowmem "lowmem"} | 
					
						
							|  |  |  |     ${optionalString cfg.verylowmem "verylowmem"} | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |     ${optionalString (cfg.maxbw != null) "maxbw ${toString cfg.maxbw}"} | 
					
						
							|  |  |  |     ${optionalString (cfg.maxbwRateUp != null) "maxbw-rate-up ${toString cfg.maxbwRateUp}"} | 
					
						
							|  |  |  |     ${optionalString (cfg.maxbwRateDown != null) "maxbw-rate-down ${toString cfg.maxbwRateDown}"} | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  |   '';
 | 
					
						
							|  |  |  | in | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-12-10 02:51:19 +01:00
										 |  |  |   imports = [ | 
					
						
							|  |  |  |     (mkRemovedOptionModule [ "services" "tarsnap" "cachedir" ] "Use services.tarsnap.archives.<name>.cachedir") | 
					
						
							|  |  |  |   ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  |   options = { | 
					
						
							|  |  |  |     services.tarsnap = { | 
					
						
							|  |  |  |       enable = mkOption { | 
					
						
							|  |  |  |         type = types.bool; | 
					
						
							|  |  |  |         default = false; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |           Enable periodic tarsnap backups. | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       keyfile = mkOption { | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |         type = types.str; | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  |         default = "/root/tarsnap.key"; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |           The keyfile which associates this machine with your tarsnap | 
					
						
							|  |  |  |           account. | 
					
						
							|  |  |  |           Create the keyfile with <command>tarsnap-keygen</command>. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-07 05:47:04 -06:00
										 |  |  |           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 | 
					
						
							|  |  |  |           <literal>"/root/tarsnap.key"</literal>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           It's recommended for backups that you generate a key for every archive | 
					
						
							|  |  |  |           using <literal>tarsnap-keygen(1)</literal>, and then generate a | 
					
						
							|  |  |  |           write-only tarsnap key using <literal>tarsnap-keymgmt(1)</literal>, | 
					
						
							|  |  |  |           and keep your master key(s) for a particular machine off-site. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |           The keyfile name should be given as a string and not a path, to | 
					
						
							|  |  |  |           avoid the key being copied into the Nix store. | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |       archives = mkOption { | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |         type = types.attrsOf (types.submodule ({ config, ... }: | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |           { | 
					
						
							|  |  |  |             options = { | 
					
						
							| 
									
										
										
										
											2016-01-07 05:47:04 -06:00
										 |  |  |               keyfile = mkOption { | 
					
						
							|  |  |  |                 type = types.str; | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |                 default = gcfg.keyfile; | 
					
						
							| 
									
										
										
										
											2016-01-07 05:47:04 -06:00
										 |  |  |                 description = ''
 | 
					
						
							|  |  |  |                   Set a specific keyfile for this archive. This defaults to | 
					
						
							|  |  |  |                   <literal>"/root/tarsnap.key"</literal> 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 <literal>tarsnap-keymgmt(1)</literal>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   Note: every archive must have an individual master key. You | 
					
						
							|  |  |  |                   must generate multiple keys with | 
					
						
							|  |  |  |                   <literal>tarsnap-keygen(1)</literal>, 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. | 
					
						
							|  |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |               cachedir = mkOption { | 
					
						
							|  |  |  |                 type = types.nullOr types.path; | 
					
						
							|  |  |  |                 default = "/var/cache/tarsnap/${utils.escapeSystemdPath config.keyfile}"; | 
					
						
							|  |  |  |                 description = ''
 | 
					
						
							|  |  |  |                   The cache allows tarsnap to identify previously stored data | 
					
						
							|  |  |  |                   blocks, reducing archival time and bandwidth usage. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   Should the cache become desynchronized or corrupted, tarsnap | 
					
						
							|  |  |  |                   will refuse to run until you manually rebuild the cache with | 
					
						
							|  |  |  |                   <command>tarsnap --fsck</command>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   Set to <literal>null</literal> to disable caching. | 
					
						
							|  |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |               nodump = mkOption { | 
					
						
							|  |  |  |                 type = types.bool; | 
					
						
							|  |  |  |                 default = true; | 
					
						
							|  |  |  |                 description = ''
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                   Exclude files with the <literal>nodump</literal> flag. | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               printStats = mkOption { | 
					
						
							|  |  |  |                 type = types.bool; | 
					
						
							|  |  |  |                 default = true; | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                 description = ''
 | 
					
						
							|  |  |  |                   Print global archive statistics upon completion. | 
					
						
							|  |  |  |                   The output is available via | 
					
						
							| 
									
										
										
										
											2017-12-20 07:35:57 +07:00
										 |  |  |                   <command>systemctl status tarsnap-archive-name</command>. | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                 '';
 | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               checkpointBytes = mkOption { | 
					
						
							|  |  |  |                 type = types.nullOr types.str; | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                 default = "1GB"; | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |                 description = ''
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                   Create a checkpoint every <literal>checkpointBytes</literal> | 
					
						
							|  |  |  |                   of uploaded data (optionally specified using an SI prefix). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   1GB is the minimum value. A higher value is recommended, | 
					
						
							|  |  |  |                   as checkpointing is expensive. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   Set to <literal>null</literal> to disable checkpointing. | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               period = mkOption { | 
					
						
							|  |  |  |                 type = types.str; | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                 default = "01:15"; | 
					
						
							|  |  |  |                 example = "hourly"; | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |                 description = ''
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                   Create archive at this interval. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   The format is described in | 
					
						
							|  |  |  |                   <citerefentry><refentrytitle>systemd.time</refentrytitle> | 
					
						
							|  |  |  |                   <manvolnum>7</manvolnum></citerefentry>. | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               aggressiveNetworking = mkOption { | 
					
						
							|  |  |  |                 type = types.bool; | 
					
						
							|  |  |  |                 default = false; | 
					
						
							|  |  |  |                 description = ''
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                   Upload data over multiple TCP connections, potentially | 
					
						
							|  |  |  |                   increasing tarsnap's bandwidth utilisation at the cost | 
					
						
							|  |  |  |                   of slowing down all other network traffic. Not | 
					
						
							|  |  |  |                   recommended unless TCP congestion is the dominant | 
					
						
							|  |  |  |                   limiting factor. | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               directories = mkOption { | 
					
						
							|  |  |  |                 type = types.listOf types.path; | 
					
						
							|  |  |  |                 default = []; | 
					
						
							|  |  |  |                 description = "List of filesystem paths to archive."; | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               excludes = mkOption { | 
					
						
							|  |  |  |                 type = types.listOf types.str; | 
					
						
							|  |  |  |                 default = []; | 
					
						
							|  |  |  |                 description = ''
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                   Exclude files and directories matching these patterns. | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               includes = mkOption { | 
					
						
							|  |  |  |                 type = types.listOf types.str; | 
					
						
							|  |  |  |                 default = []; | 
					
						
							|  |  |  |                 description = ''
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                   Include only files and directories matching these | 
					
						
							|  |  |  |                   patterns (the empty list includes everything). | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                   Exclusions have precedence over inclusions. | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               lowmem = mkOption { | 
					
						
							|  |  |  |                 type = types.bool; | 
					
						
							|  |  |  |                 default = false; | 
					
						
							|  |  |  |                 description = ''
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                   Reduce memory consumption by not caching small files. | 
					
						
							|  |  |  |                   Possibly beneficial if the average file size is smaller | 
					
						
							|  |  |  |                   than 1 MB and the number of files is lower than the | 
					
						
							|  |  |  |                   total amount of RAM in KB. | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               verylowmem = mkOption { | 
					
						
							|  |  |  |                 type = types.bool; | 
					
						
							|  |  |  |                 default = false; | 
					
						
							|  |  |  |                 description = ''
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                   Reduce memory consumption by a factor of 2 beyond what | 
					
						
							|  |  |  |                   <literal>lowmem</literal> does, at the cost of significantly | 
					
						
							|  |  |  |                   slowing down the archiving process. | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							| 
									
										
										
										
											2015-04-04 11:48:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |               maxbw = mkOption { | 
					
						
							|  |  |  |                 type = types.nullOr types.int; | 
					
						
							|  |  |  |                 default = null; | 
					
						
							|  |  |  |                 description = ''
 | 
					
						
							|  |  |  |                   Abort archival if upstream bandwidth usage in bytes | 
					
						
							|  |  |  |                   exceeds this threshold. | 
					
						
							|  |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               maxbwRateUp = mkOption { | 
					
						
							|  |  |  |                 type = types.nullOr types.int; | 
					
						
							|  |  |  |                 default = null; | 
					
						
							|  |  |  |                 example = literalExample "25 * 1000"; | 
					
						
							|  |  |  |                 description = ''
 | 
					
						
							|  |  |  |                   Upload bandwidth rate limit in bytes. | 
					
						
							|  |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               maxbwRateDown = mkOption { | 
					
						
							|  |  |  |                 type = types.nullOr types.int; | 
					
						
							|  |  |  |                 default = null; | 
					
						
							|  |  |  |                 example = literalExample "50 * 1000"; | 
					
						
							|  |  |  |                 description = ''
 | 
					
						
							|  |  |  |                   Download bandwidth rate limit in bytes. | 
					
						
							|  |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							| 
									
										
										
										
											2017-05-01 17:09:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |               verbose = mkOption { | 
					
						
							|  |  |  |                 type = types.bool; | 
					
						
							|  |  |  |                 default = false; | 
					
						
							|  |  |  |                 description = ''
 | 
					
						
							|  |  |  |                   Whether to produce verbose logging output. | 
					
						
							|  |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							| 
									
										
										
										
											2018-03-26 12:39:00 +01:00
										 |  |  |               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. | 
					
						
							|  |  |  |                 '';
 | 
					
						
							|  |  |  |               }; | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |             }; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         )); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         default = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         example = literalExample ''
 | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             nixos = | 
					
						
							|  |  |  |               { directories = [ "/home" "/root/ssl" ]; | 
					
						
							|  |  |  |               }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             gamedata = | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |               { directories = [ "/var/lib/minecraft" ]; | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |                 period      = "*:30"; | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |               }; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  |         '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |           Tarsnap archive configurations. Each attribute names an archive | 
					
						
							|  |  |  |           to be created at a given time interval, according to the options | 
					
						
							|  |  |  |           associated with it. When uploading to the tarsnap server, | 
					
						
							|  |  |  |           archive names are suffixed by a 1 second resolution timestamp. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           For each member of the set is created a timer which triggers the | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |           instanced <literal>tarsnap-archive-name</literal> service unit. You may use | 
					
						
							|  |  |  |           <command>systemctl start tarsnap-archive-name</command> to | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |           manually trigger creation of <literal>archive-name</literal> at | 
					
						
							|  |  |  |           any time. | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |   config = mkIf gcfg.enable { | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  |     assertions = | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |       (mapAttrsToList (name: cfg: | 
					
						
							|  |  |  |         { assertion = cfg.directories != []; | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |           message = "Must specify paths for tarsnap to back up"; | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |         }) gcfg.archives) ++ | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  |       (mapAttrsToList (name: cfg: | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |         { assertion = !(cfg.lowmem && cfg.verylowmem); | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  |           message = "You cannot set both lowmem and verylowmem"; | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |         }) gcfg.archives); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     systemd.services = | 
					
						
							| 
									
										
										
										
											2018-03-27 01:12:26 +01:00
										 |  |  |       (mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}" { | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |         description = "Tarsnap archive '${name}'"; | 
					
						
							|  |  |  |         requires    = [ "network-online.target" ]; | 
					
						
							|  |  |  |         after       = [ "network-online.target" ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-27 16:35:54 +01:00
										 |  |  |         path = with pkgs; [ iputils tarsnap utillinux ]; | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # 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 | 
					
						
							|  |  |  |         # the service - therefore we sleep in a loop until we can ping the | 
					
						
							|  |  |  |         # endpoint. | 
					
						
							|  |  |  |         preStart = ''
 | 
					
						
							|  |  |  |           while ! ping -q -c 1 v1-0-0-server.tarsnap.com &> /dev/null; do sleep 3; done | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-27 16:35:54 +01:00
										 |  |  |         script = let | 
					
						
							|  |  |  |           tarsnap = ''tarsnap --configfile "/etc/tarsnap/${name}.conf"''; | 
					
						
							|  |  |  |           run = ''${tarsnap} -c -f "${name}-$(date +"%Y%m%d%H%M%S")" \
 | 
					
						
							| 
									
										
										
										
											2017-05-01 17:09:45 +02:00
										 |  |  |                         ${optionalString cfg.verbose "-v"} \ | 
					
						
							| 
									
										
										
										
											2018-03-26 12:39:00 +01:00
										 |  |  |                         ${optionalString cfg.explicitSymlinks "-H"} \ | 
					
						
							|  |  |  |                         ${optionalString cfg.followSymlinks "-L"} \ | 
					
						
							| 
									
										
										
										
											2017-05-01 17:09:45 +02:00
										 |  |  |                         ${concatStringsSep " " cfg.directories}'';
 | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |           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 | 
					
						
							| 
									
										
										
										
											2018-03-27 16:35:54 +01:00
										 |  |  |                   ${tarsnap} --fsck | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |                   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"; | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2018-03-27 01:12:26 +01:00
										 |  |  |       }) gcfg.archives) // | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       (mapAttrs' (name: cfg: nameValuePair "tarsnap-restore-${name}"{ | 
					
						
							|  |  |  |         description = "Tarsnap restore '${name}'"; | 
					
						
							|  |  |  |         requires    = [ "network-online.target" ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-27 16:35:54 +01:00
										 |  |  |         path = with pkgs; [ iputils tarsnap utillinux ]; | 
					
						
							| 
									
										
										
										
											2018-03-27 01:12:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-27 16:35:54 +01:00
										 |  |  |         script = let | 
					
						
							| 
									
										
										
										
											2018-03-27 01:12:26 +01:00
										 |  |  |           tarsnap = ''tarsnap --configfile "/etc/tarsnap/${name}.conf"''; | 
					
						
							|  |  |  |           lastArchive = ''$(${tarsnap} --list-archives | sort | tail -1)''; | 
					
						
							|  |  |  |           run = ''${tarsnap} -x -f "${lastArchive}" ${optionalString cfg.verbose "-v"}''; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-27 16:35:54 +01:00
										 |  |  |         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}";
 | 
					
						
							| 
									
										
										
										
											2018-03-27 01:12:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         serviceConfig = { | 
					
						
							|  |  |  |           Type = "oneshot"; | 
					
						
							|  |  |  |           IOSchedulingClass = "idle"; | 
					
						
							|  |  |  |           NoNewPrivileges = "true"; | 
					
						
							|  |  |  |           CapabilityBoundingSet = [ "CAP_DAC_READ_SEARCH" ]; | 
					
						
							|  |  |  |           PermissionsStartOnly = "true"; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       }) gcfg.archives); | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-07 05:06:05 -06:00
										 |  |  |     # 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. | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |     systemd.timers = mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}" | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |       { timerConfig.OnCalendar = cfg.period; | 
					
						
							| 
									
										
										
										
											2016-01-07 05:06:05 -06:00
										 |  |  |         timerConfig.Persistent = "true"; | 
					
						
							| 
									
										
										
										
											2015-03-10 08:40:08 +01:00
										 |  |  |         wantedBy = [ "timers.target" ]; | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |       }) gcfg.archives; | 
					
						
							| 
									
										
										
										
											2014-04-28 18:15:14 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     environment.etc = | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |       mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.conf" | 
					
						
							| 
									
										
										
										
											2016-01-07 04:53:32 -06:00
										 |  |  |         { text = configFile name cfg; | 
					
						
							| 
									
										
										
										
											2016-09-30 02:27:34 +03:00
										 |  |  |         }) gcfg.archives; | 
					
						
							| 
									
										
										
										
											2014-02-23 22:10:14 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     environment.systemPackages = [ pkgs.tarsnap ]; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } |