zfs_unstable: 2.3.0-rc3 -> 2.3.0-rc4 (#365045)
[NixPkgs.git] / nixos / modules / services / networking / nomad.nix
blobf66e82e7143b8dc5d7514ec470141af9c1605405
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
7 with lib;
8 let
9   cfg = config.services.nomad;
10   format = pkgs.formats.json { };
13   ##### interface
14   options = {
15     services.nomad = {
16       enable = mkEnableOption "Nomad, a distributed, highly available, datacenter-aware scheduler";
18       package = mkPackageOption pkgs "nomad" { };
20       extraPackages = mkOption {
21         type = types.listOf types.package;
22         default = [ ];
23         description = ''
24           Extra packages to add to {env}`PATH` for the Nomad agent process.
25         '';
26         example = literalExpression ''
27           with pkgs; [ cni-plugins ]
28         '';
29       };
31       dropPrivileges = mkOption {
32         type = types.bool;
33         default = true;
34         description = ''
35           Whether the nomad agent should be run as a non-root nomad user.
36         '';
37       };
39       enableDocker = mkOption {
40         type = types.bool;
41         default = true;
42         description = ''
43           Enable Docker support. Needed for Nomad's docker driver.
45           Note that the docker group membership is effectively equivalent
46           to being root, see https://github.com/moby/moby/issues/9976.
47         '';
48       };
50       extraSettingsPaths = mkOption {
51         type = types.listOf types.path;
52         default = [ ];
53         description = ''
54           Additional settings paths used to configure nomad. These can be files or directories.
55         '';
56         example = literalExpression ''
57           [ "/etc/nomad-mutable.json" "/run/keys/nomad-with-secrets.json" "/etc/nomad/config.d" ]
58         '';
59       };
61       extraSettingsPlugins = mkOption {
62         type = types.listOf (types.either types.package types.path);
63         default = [ ];
64         description = ''
65           Additional plugins dir used to configure nomad.
66         '';
67         example = literalExpression ''
68           [ "<pluginDir>" pkgs.nomad-driver-nix pkgs.nomad-driver-podman  ]
69         '';
70       };
72       credentials = mkOption {
73         description = ''
74           Credentials envs used to configure nomad secrets.
75         '';
76         type = types.attrsOf types.str;
77         default = { };
79         example = {
80           logs_remote_write_password = "/run/keys/nomad_write_password";
81         };
82       };
84       settings = mkOption {
85         type = format.type;
86         default = { };
87         description = ''
88           Configuration for Nomad. See the [documentation](https://www.nomadproject.io/docs/configuration)
89           for supported values.
91           Notes about `data_dir`:
93           If `data_dir` is set to a value other than the
94           default value of `"/var/lib/nomad"` it is the Nomad
95           cluster manager's responsibility to make sure that this directory
96           exists and has the appropriate permissions.
98           Additionally, if `dropPrivileges` is
99           `true` then `data_dir`
100           *cannot* be customized. Setting
101           `dropPrivileges` to `true` enables
102           the `DynamicUser` feature of systemd which directly
103           manages and operates on `StateDirectory`.
104         '';
105         example = literalExpression ''
106           {
107             # A minimal config example:
108             server = {
109               enabled = true;
110               bootstrap_expect = 1; # for demo; no fault tolerance
111             };
112             client = {
113               enabled = true;
114             };
115           }
116         '';
117       };
118     };
119   };
121   ##### implementation
122   config = mkIf cfg.enable {
123     services.nomad.settings = {
124       # Agrees with `StateDirectory = "nomad"` set below.
125       data_dir = mkDefault "/var/lib/nomad";
126     };
128     environment = {
129       etc."nomad.json".source = format.generate "nomad.json" cfg.settings;
130       systemPackages = [ cfg.package ];
131     };
133     systemd.services.nomad = {
134       description = "Nomad";
135       wantedBy = [ "multi-user.target" ];
136       wants = [ "network-online.target" ];
137       after = [ "network-online.target" ];
138       restartTriggers = [ config.environment.etc."nomad.json".source ];
140       path =
141         cfg.extraPackages
142         ++ (with pkgs; [
143           # Client mode requires at least the following:
144           coreutils
145           iproute2
146           iptables
147         ]);
149       serviceConfig = mkMerge [
150         {
151           DynamicUser = cfg.dropPrivileges;
152           ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
153           ExecStart =
154             let
155               pluginsDir = pkgs.symlinkJoin {
156                 name = "nomad-plugins";
157                 paths = cfg.extraSettingsPlugins;
158               };
159             in
160             "${cfg.package}/bin/nomad agent -config=/etc/nomad.json -plugin-dir=${pluginsDir}/bin"
161             + concatMapStrings (path: " -config=${path}") cfg.extraSettingsPaths
162             + concatMapStrings (key: " -config=\${CREDENTIALS_DIRECTORY}/${key}") (
163               lib.attrNames cfg.credentials
164             );
165           KillMode = "process";
166           KillSignal = "SIGINT";
167           LimitNOFILE = 65536;
168           LimitNPROC = "infinity";
169           OOMScoreAdjust = -1000;
170           Restart = "on-failure";
171           RestartSec = 2;
172           TasksMax = "infinity";
173           LoadCredential = lib.mapAttrsToList (key: value: "${key}:${value}") cfg.credentials;
174         }
175         (mkIf cfg.enableDocker {
176           SupplementaryGroups = "docker"; # space-separated string
177         })
178         (mkIf (cfg.settings.data_dir == "/var/lib/nomad") {
179           StateDirectory = "nomad";
180         })
181       ];
183       unitConfig = {
184         StartLimitIntervalSec = 10;
185         StartLimitBurst = 3;
186       };
187     };
189     assertions = [
190       {
191         assertion = cfg.dropPrivileges -> cfg.settings.data_dir == "/var/lib/nomad";
192         message = "settings.data_dir must be equal to \"/var/lib/nomad\" if dropPrivileges is true";
193       }
194     ];
196     # Docker support requires the Docker daemon to be running.
197     virtualisation.docker.enable = mkIf cfg.enableDocker true;
198   };