]> git.immae.eu Git - perso/Immae/Config/Nix.git/blobdiff - systems/eldiron/duply_backup.nix
Squash changes containing private information
[perso/Immae/Config/Nix.git] / systems / eldiron / duply_backup.nix
diff --git a/systems/eldiron/duply_backup.nix b/systems/eldiron/duply_backup.nix
new file mode 100644 (file)
index 0000000..590d125
--- /dev/null
@@ -0,0 +1,151 @@
+{ 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.listToAttrs (lib.flatten (lib.mapAttrsToList (k: v:
+      map (remote: [
+        (lib.nameValuePair "backup/${varName k remote}/conf" {
+          permissions = "0400";
+          text = duplyProfile v remote "${k}/";
+        })
+        (lib.nameValuePair "backup/${varName k remote}/exclude" {
+          permissions = "0400";
+          text = v.excludeFile;
+        })
+        (lib.nameValuePair "backup/${varName k remote}" {
+          permissions = "0500";
+          isDir = true;
+        })
+    ]) 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.fullPaths."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";
+      })
+    ];
+
+    myServices.monitoring.fromMasterActivatedPlugins = [ "eriomem" ];
+    myServices.monitoring.fromMasterObjects.service = [
+      {
+        service_description = "eriomem backup is up and not full";
+        host_name = config.hostEnv.fqdn;
+        use = "external-service";
+        check_command = "check_backup_eriomem";
+
+        check_interval = 120;
+        notification_interval = "1440";
+
+        servicegroups = "webstatus-backup";
+      }
+
+      {
+        service_description = "ovh backup is up and not full";
+        host_name = config.hostEnv.fqdn;
+        use = "external-service";
+        check_command = "check_ok";
+
+        check_interval = 120;
+        notification_interval = "1440";
+
+        servicegroups = "webstatus-backup";
+      }
+    ];
+  };
+}