diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 76620f1d02a..94c1667d39d 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -78,8 +78,9 @@ ./services/backup/bacula.nix ./services/backup/mysql-backup.nix ./services/backup/postgresql-backup.nix - ./services/backup/sitecopy-backup.nix ./services/backup/rsnapshot.nix + ./services/backup/sitecopy-backup.nix + ./services/backup/tarsnap.nix ./services/databases/4store-endpoint.nix ./services/databases/4store.nix ./services/databases/couchdb.nix diff --git a/nixos/modules/services/backup/tarsnap.nix b/nixos/modules/services/backup/tarsnap.nix new file mode 100644 index 00000000000..3395a0b5263 --- /dev/null +++ b/nixos/modules/services/backup/tarsnap.nix @@ -0,0 +1,200 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +let + cfg = config.services.tarsnap; + + optionalNullStr = e: v: if e == null then "" else v; + + configFile = pkgs.writeText "tarsnap.conf" '' + cachedir ${cfg.cachedir} + keyfile ${cfg.keyfile} + ${optionalString cfg.nodump "nodump"} + ${optionalString cfg.printStats "print-stats"} + ${optionalNullStr cfg.checkpointBytes "checkpoint-bytes "+cfg.checkpointBytes} + ${optionalString cfg.aggressiveNetworking "aggressive-networking"} + ${concatStringsSep "\n" (map (v: "exclude "+v) cfg.excludes)} + ${concatStringsSep "\n" (map (v: "include "+v) cfg.includes)} + ${optionalString cfg.lowmem "lowmem"} + ${optionalString cfg.verylowmem "verylowmem"} + ''; +in +{ + options = { + services.tarsnap = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + If enabled, NixOS will periodically create backups of the + specified directories using the tarsnap + backup service. This installs a systemd + service called tarsnap-backup which is + periodically run by cron, or you may run it on-demand. + ''; + }; + + label = mkOption { + type = types.str; + default = "nixos"; + description = '' + Specifies the label for archives created by Tarsnap. The + full name will be + label-$(date+"%Y%m%d%H%M%S"). For + example, by default your backups will look similar to + nixos-20140301021501. + ''; + }; + + 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 + cachedir 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 + tarsnap --fsck 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 tarsnap-keygen utility, and providing + your Tarsnap login credentials. + ''; + }; + + nodump = mkOption { + type = types.bool; + default = true; + description = '' + If set to true, then don't archive files + which have the nodump 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, + checkpointBytes must be 1GB. + + Can also be set to null 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 update 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 + excludes 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 + lowmem option does. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + assertions = + [ { assertion = cfg.directories != []; + message = "Must specify directories for Tarsnap to back up"; + } + { assertion = cfg.lowmem -> !cfg.verylowmem && (cfg.verylowmem -> !cfg.lowmem); + message = "You cannot set both lowmem and verylowmem"; + } + ]; + + systemd.services.tarsnap-backup = { + description = "Tarsnap Backup process"; + path = [ pkgs.tarsnap pkgs.coreutils ]; + 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} + ''; + }; + + services.cron.systemCronJobs = optional cfg.enable + "${cfg.period} root ${config.systemd.package}/bin/systemctl start tarsnap-backup.service"; + + environment.systemPackages = [ pkgs.tarsnap ]; + }; +}