config

NixOS config
Log | Files | Refs | README | LICENSE

default.nix (3330B) - Raw


      1 {
      2   config,
      3   pkgs,
      4   lib,
      5   ...
      6 }:
      7 let
      8   cfg = config.mj.services.btrfsborg;
      9 in
     10 {
     11   options.mj.services.btrfsborg = with lib.types; {
     12     enable = lib.mkEnableOption "backup btrfs snapshots with borg";
     13 
     14     passwordPath = lib.mkOption { type = str; };
     15     sshKeyPath = lib.mkOption {
     16       type = nullOr path;
     17       default = null;
     18     };
     19 
     20     dirs = lib.mkOption {
     21       default = { };
     22       type = listOf (submodule {
     23         options = {
     24           subvolume = lib.mkOption { type = path; };
     25           repo = lib.mkOption { type = str; };
     26           paths = lib.mkOption { type = listOf str; };
     27           patterns = lib.mkOption {
     28             type = listOf str;
     29             default = [ ];
     30           };
     31           prune = lib.mkOption {
     32             type = anything;
     33             default = { };
     34           };
     35           backup_at = lib.mkOption { type = str; };
     36           compression = lib.mkOption {
     37             type = str;
     38             default = "auto,zstd,10";
     39           };
     40         };
     41       });
     42     };
     43   };
     44 
     45   config = lib.mkIf cfg.enable {
     46     systemd.services = lib.listToAttrs (
     47       lib.imap0 (
     48         i: attr:
     49         let
     50           svcName = "borgbackup-job-${lib.strings.sanitizeDerivationName attr.subvolume}-${toString i}";
     51         in
     52         lib.nameValuePair svcName { serviceConfig.RuntimeDirectory = svcName; }
     53       ) cfg.dirs
     54     );
     55 
     56     services.borgbackup.jobs = builtins.listToAttrs (
     57       lib.imap0 (
     58         i: attrs:
     59         let
     60           subvolume = builtins.getAttr "subvolume" attrs;
     61         in
     62         assert lib.assertMsg config.mj.base.unitstatus.enable
     63           "config.mj.base.unitstatus.enable must be true";
     64         lib.nameValuePair "${lib.strings.sanitizeDerivationName subvolume}-${toString i}" (
     65           {
     66             inherit (attrs) repo paths compression;
     67 
     68             doInit = true;
     69             encryption = {
     70               mode = "repokey-blake2";
     71               passCommand = "cat ${cfg.passwordPath}";
     72             };
     73             extraArgs = "--remote-path=borg1";
     74             extraCreateArgs = "--chunker-params buzhash,10,23,16,4095";
     75             startAt = attrs.backup_at;
     76             preHook = ''
     77               set -x
     78               sleep ${toString i}
     79               SNAPSHOT=$(${pkgs.btrfs-progs}/bin/btrfs subvolume list --sort=-gen -r -o ${subvolume} | \
     80                   ${pkgs.gawk}/bin/awk '{print $9; exit}')
     81               cd "/$SNAPSHOT"
     82             '';
     83             prune.keep = {
     84               within = "1d";
     85               daily = 7;
     86               weekly = 4;
     87             };
     88             environment = {
     89               BORG_RELOCATED_REPO_ACCESS_IS_OK = "yes";
     90               BORG_HOST_ID =
     91                 let
     92                   h = config.networking;
     93                 in
     94                 "${h.hostName}.${h.domain}@${h.hostId}";
     95             }
     96             // lib.optionalAttrs (cfg.sshKeyPath != null) { BORG_RSH = ''ssh -i "${cfg.sshKeyPath}"''; };
     97           }
     98           // lib.optionalAttrs (attrs ? patterns) { inherit (attrs) patterns; }
     99           // lib.optionalAttrs (attrs ? prune) { inherit (attrs) prune; }
    100         )
    101       ) cfg.dirs
    102     );
    103 
    104     mj.base.unitstatus.units =
    105       let
    106         sanitized = map lib.strings.sanitizeDerivationName (lib.catAttrs "subvolume" cfg.dirs);
    107       in
    108       lib.imap0 (i: name: "borgbackup-job-${name}-${toString i}") sanitized;
    109   };
    110 }