summary refs log tree commit diff
path: root/nixos/modules/services/networking/nomad.nix
blob: e6bbb607aaaf4e20872b123524aeebc31ffa88cd (plain) (blame)
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 lib;
let
  cfg = config.services.nomad;
  format = pkgs.formats.json { };
in
{
  ##### interface
  options = {
    services.nomad = {
      enable = mkEnableOption "Nomad, a distributed, highly available, datacenter-aware scheduler";

      package = mkOption {
        type = types.package;
        default = pkgs.nomad;
        defaultText = "pkgs.nomad";
        description = ''
          The package used for the Nomad agent and CLI.
        '';
      };

      extraPackages = mkOption {
        type = types.listOf types.package;
        default = [ ];
        description = ''
          Extra packages to add to <envar>PATH</envar> for the Nomad agent process.
        '';
        example = literalExample ''
          with pkgs; [ cni-plugins ]
        '';
      };

      dropPrivileges = mkOption {
        type = types.bool;
        default = true;
        description = ''
          Whether the nomad agent should be run as a non-root nomad user.
        '';
      };

      enableDocker = mkOption {
        type = types.bool;
        default = true;
        description = ''
          Enable Docker support. Needed for Nomad's docker driver.

          Note that the docker group membership is effectively equivalent
          to being root, see https://github.com/moby/moby/issues/9976.
        '';
      };

      settings = mkOption {
        type = format.type;
        default = {
          # Agrees with `StateDirectory = "nomad"` set below.
          data_dir = "/var/lib/nomad";
        };
        description = ''
          Configuration for Nomad. See the <link xlink:href="https://www.nomadproject.io/docs/configuration">documentation</link>
          for supported values.
        '';
        example = literalExample ''
          {
            # A minimal config example:
            server = {
              enabled = true;
              bootstrap_expect = 1; # for demo; no fault tolerance
            };
            client = {
              enabled = true;
            };
          }
        '';
      };
    };
  };

  ##### implementation
  config = mkIf cfg.enable {
    environment = {
      etc."nomad.json".source = format.generate "nomad.json" cfg.settings;
      systemPackages = [ cfg.package ];
    };

    systemd.services.nomad = {
      description = "Nomad";
      wantedBy = [ "multi-user.target" ];
      wants = [ "network-online.target" ];
      after = [ "network-online.target" ];
      restartTriggers = [ config.environment.etc."nomad.json".source ];

      path = cfg.extraPackages ++ (with pkgs; [
        # Client mode requires at least the following:
        coreutils
        iproute
        iptables
      ]);

      serviceConfig = {
        DynamicUser = cfg.dropPrivileges;
        ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
        ExecStart = "${cfg.package}/bin/nomad agent -config=/etc/nomad.json";
        KillMode = "process";
        KillSignal = "SIGINT";
        LimitNOFILE = 65536;
        LimitNPROC = "infinity";
        OOMScoreAdjust = -1000;
        Restart = "on-failure";
        RestartSec = 2;
        # Agrees with the default `data_dir = "/var/lib/nomad"` in `settings` above.
        StateDirectory = "nomad";
        TasksMax = "infinity";
        User = optionalString cfg.dropPrivileges "nomad";
      } // (optionalAttrs cfg.enableDocker {
        SupplementaryGroups = "docker"; # space-separated string
      });
      unitConfig = {
        StartLimitIntervalSec = 10;
        StartLimitBurst = 3;
      };
    };

    # Docker support requires the Docker daemon to be running.
    virtualisation.docker.enable = mkIf cfg.enableDocker true;
  };
}