{ lib, pkgs, config, name, ... }: let cfg = config.myEnv.backup; varDir = "/var/lib/duply"; duplyProfile = profile: remote: prefix: '' GPG_PW="${cfg.password}" TARGET="${cfg.remotes.${remote}.remote profile.bucket}${prefix}" export AWS_ACCESS_KEY_ID="${cfg.remotes.${remote}.accessKeyId}" export AWS_SECRET_ACCESS_KEY="${cfg.remotes.${remote}.secretAccessKey}" SOURCE="${profile.rootDir}" FILENAME=".duplicity-ignore" DUPL_PARAMS="$DUPL_PARAMS --exclude-if-present '$FILENAME'" VERBOSITY=4 ARCH_DIR="${varDir}/caches" # Do a full backup after 1 month MAX_FULLBKP_AGE=1M DUPL_PARAMS="$DUPL_PARAMS --allow-source-mismatch --exclude-other-filesystems --full-if-older-than $MAX_FULLBKP_AGE " # Backups older than 2months are deleted MAX_AGE=2M # Keep 2 full backups MAX_FULL_BACKUPS=2 MAX_FULLS_WITH_INCRS=2 ''; action = "bkp_purge_purgeFull_purgeIncr"; varName = k: remoteName: if remoteName == "eriomem" then k else remoteName + "_" + k; in { options = { services.duplyBackup.enable = lib.mkOption { type = lib.types.bool; default = false; description = '' Whether to enable remote backups. ''; }; services.duplyBackup.profiles = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule { options = { rootDir = lib.mkOption { type = lib.types.path; description = '' Path to backup ''; }; bucket = lib.mkOption { type = lib.types.str; default = "immae-${name}"; description = '' Bucket to use ''; }; remotes = lib.mkOption { type = lib.types.listOf lib.types.str; default = ["eriomem"]; description = '' Remotes to use for backup ''; }; excludeFile = lib.mkOption { type = lib.types.lines; default = ""; description = '' Content to put in exclude file ''; }; }; }); }; }; config = lib.mkIf config.services.duplyBackup.enable { system.activationScripts.backup = '' install -m 0700 -o root -g root -d ${varDir} ${varDir}/caches ''; secrets.keys = lib.flatten (lib.mapAttrsToList (k: v: map (remote: [ { permissions = "0400"; dest = "backup/${varName k remote}/conf"; text = duplyProfile v remote "${k}/"; } { permissions = "0400"; dest = "backup/${varName k remote}/exclude"; text = v.excludeFile; } ]) v.remotes) config.services.duplyBackup.profiles); services.cron = { enable = true; systemCronJobs = let backups = pkgs.writeScript "backups" '' #!${pkgs.stdenv.shell} ${builtins.concatStringsSep "\n" (lib.flatten (lib.mapAttrsToList (k: v: map (remote: [ '' touch ${varDir}/${varName k remote}.log ${pkgs.duply}/bin/duply ${config.secrets.location}/backup/${varName k remote}/ ${action} --force >> ${varDir}/${varName k remote}.log [[ $? = 0 ]] || echo -e "Error when doing backup for ${varName k remote}, see above\n---------------------------------------" >&2 '' ]) v.remotes ) config.services.duplyBackup.profiles))} ''; in [ "0 2 * * * root ${backups}" ]; }; security.pki.certificateFiles = [ (pkgs.fetchurl { url = "http://downloads.e.eriomem.net/eriomemca.pem"; sha256 = "1ixx4c6j3m26j8dp9a3dkvxc80v1nr5aqgmawwgs06bskasqkvvh"; }) ]; }; }