summaryrefslogtreecommitdiffstats
path: root/makefu/3modules/snapraid.nix
blob: 9c7854787ab0d19f5b95e2c5843e6d3f5b199b83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
{ config, lib, pkgs, ... }:

with import <stockholm/lib>;

let
  # returns dirname without / , used as disk name
  dname = dir: replaceChars ["/"] [""] (head (reverseList (splitString "/" dir)));
  snapraid-conf = ''
    # Disks
    ${concatMapStringsSep "\n" (d: "disk ${dname d} ${d}")  cfg.disks}
    # Parity
    ${optionalString (cfg.parity != "") "parity ${cfg.parity}/snapraid.parity"}

    # content on Disks
    ${optionalString cfg.contentOnDisks
      concatMapStringsSep "\n" (d: "content ${d}/snapraid.content")  cfg.disks}

    # content on Parity
    ${optionalString (cfg.contentOnParity && cfg.parity != "")
      "content ${cfg.parity}/snapraid.content"}
    # Default content file
    content ${cfg.defaultContentFile}

    # Extra Configuration
    ${cfg.extraConfig}
  '';
  cfg = config.makefu.snapraid;

  out = {
    options.makefu.snapraid = api;
    config = lib.mkIf cfg.enable imp;
  };

  api = {
    enable = mkEnableOption "snapraid";

    timerConfig = mkOption {
      type = with types;attrsOf str;
      description = ''
        Start snapraid service
      '';
      default = {
        OnCalendar = "daily";
      };
    };
    disks = mkOption {
      type = with types;listOf str;
      description = ''
        Disks to protect. Each disk is a path to the mounted directory of the
        disk.
      '';
    };
    parity = mkOption {
      type = types.str;
      description = ''
        Folder to store parity file.
        Set to empty string if you want to configure the parity yourself in
        extraConfig.

        All extra parity files (2,3,z, etc...) should be configured via
        extraConfig.
      '';
    };
    contentOnDisks = mkOption {
      type = types.bool;
      default = true;
      description = ''
        Store Content file on each Disk to protect.
        Set this to false if you do not want this behavior to apply.
      '';
    };
    contentOnParity = mkOption {
      type = types.bool;
      default = true;
      description = ''
        Store Content file on parity Disk.
        Set this to false if you do not want this behavior to apply.
      '';
    };
    defaultContentFile = mkOption {
      type = types.str;
      default = "/var/cache/snapraid.content";
      description = ''
        Path to default content file
        Set to empty string if this content file should be written.
      '';
    };
    extraConfig = mkOption {
      type = types.string;
      default = "";
      description = ''
        Extra configuration to be appended to the snapraid conf file.
        You can configure extra Parity files as well as extra content files.
        See `man snapraid` for additional configuration
      '';
    };
  };

  imp = {
    environment.systemPackages = [
      # for scrubbing,fixing
      pkgs.snapraid
    ];
    krebs.on-failure.plans.snapraid-sync.name = "snapraid-sync";
    environment.etc."snapraid.conf".text = snapraid-conf;
    systemd.timers.snapraid-sync = {
      description = "snapraid sync timer";
      wantedBy = [ "timers.target" ];
      timerConfig = cfg.timerConfig;
    };
    systemd.services.snapraid-sync = {
      description = "Snapraid sync service";
      after = [ "network.target" "local-fs.target" ];

      serviceConfig = {
        Type = "simple";
        ExecStartPre = pkgs.writeScript "Snapraid-sync-init" ''
          #! /bin/sh
          ${optionalString (cfg.defaultContentFile != "")
            "mkdir -p $(dirname ${cfg.defaultContentFile})"}
        '';
        ExecStart = "${pkgs.snapraid}/bin/snapraid sync";
      };
    };
  };
in out