at 21.11-pre 5.2 kB view raw
1{ config, lib, pkgs, ... }: 2with lib; 3let 4 cfg = config.services.nomad; 5 format = pkgs.formats.json { }; 6in 7{ 8 ##### interface 9 options = { 10 services.nomad = { 11 enable = mkEnableOption "Nomad, a distributed, highly available, datacenter-aware scheduler"; 12 13 package = mkOption { 14 type = types.package; 15 default = pkgs.nomad; 16 defaultText = "pkgs.nomad"; 17 description = '' 18 The package used for the Nomad agent and CLI. 19 ''; 20 }; 21 22 extraPackages = mkOption { 23 type = types.listOf types.package; 24 default = [ ]; 25 description = '' 26 Extra packages to add to <envar>PATH</envar> for the Nomad agent process. 27 ''; 28 example = literalExample '' 29 with pkgs; [ cni-plugins ] 30 ''; 31 }; 32 33 dropPrivileges = mkOption { 34 type = types.bool; 35 default = true; 36 description = '' 37 Whether the nomad agent should be run as a non-root nomad user. 38 ''; 39 }; 40 41 enableDocker = mkOption { 42 type = types.bool; 43 default = true; 44 description = '' 45 Enable Docker support. Needed for Nomad's docker driver. 46 47 Note that the docker group membership is effectively equivalent 48 to being root, see https://github.com/moby/moby/issues/9976. 49 ''; 50 }; 51 52 extraSettingsPaths = mkOption { 53 type = types.listOf types.path; 54 default = []; 55 description = '' 56 Additional settings paths used to configure nomad. These can be files or directories. 57 ''; 58 example = literalExample '' 59 [ "/etc/nomad-mutable.json" "/run/keys/nomad-with-secrets.json" "/etc/nomad/config.d" ] 60 ''; 61 }; 62 63 settings = mkOption { 64 type = format.type; 65 default = {}; 66 description = '' 67 Configuration for Nomad. See the <link xlink:href="https://www.nomadproject.io/docs/configuration">documentation</link> 68 for supported values. 69 70 Notes about <literal>data_dir</literal>: 71 72 If <literal>data_dir</literal> is set to a value other than the 73 default value of <literal>"/var/lib/nomad"</literal> it is the Nomad 74 cluster manager's responsibility to make sure that this directory 75 exists and has the appropriate permissions. 76 77 Additionally, if <literal>dropPrivileges</literal> is 78 <literal>true</literal> then <literal>data_dir</literal> 79 <emphasis>cannot</emphasis> be customized. Setting 80 <literal>dropPrivileges</literal> to <literal>true</literal> enables 81 the <literal>DynamicUser</literal> feature of systemd which directly 82 manages and operates on <literal>StateDirectory</literal>. 83 ''; 84 example = literalExample '' 85 { 86 # A minimal config example: 87 server = { 88 enabled = true; 89 bootstrap_expect = 1; # for demo; no fault tolerance 90 }; 91 client = { 92 enabled = true; 93 }; 94 } 95 ''; 96 }; 97 }; 98 }; 99 100 ##### implementation 101 config = mkIf cfg.enable { 102 services.nomad.settings = { 103 # Agrees with `StateDirectory = "nomad"` set below. 104 data_dir = mkDefault "/var/lib/nomad"; 105 }; 106 107 environment = { 108 etc."nomad.json".source = format.generate "nomad.json" cfg.settings; 109 systemPackages = [ cfg.package ]; 110 }; 111 112 systemd.services.nomad = { 113 description = "Nomad"; 114 wantedBy = [ "multi-user.target" ]; 115 wants = [ "network-online.target" ]; 116 after = [ "network-online.target" ]; 117 restartTriggers = [ config.environment.etc."nomad.json".source ]; 118 119 path = cfg.extraPackages ++ (with pkgs; [ 120 # Client mode requires at least the following: 121 coreutils 122 iproute2 123 iptables 124 ]); 125 126 serviceConfig = mkMerge [ 127 { 128 DynamicUser = cfg.dropPrivileges; 129 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 130 ExecStart = "${cfg.package}/bin/nomad agent -config=/etc/nomad.json" + 131 concatMapStrings (path: " -config=${path}") cfg.extraSettingsPaths; 132 KillMode = "process"; 133 KillSignal = "SIGINT"; 134 LimitNOFILE = 65536; 135 LimitNPROC = "infinity"; 136 OOMScoreAdjust = -1000; 137 Restart = "on-failure"; 138 RestartSec = 2; 139 TasksMax = "infinity"; 140 } 141 (mkIf cfg.enableDocker { 142 SupplementaryGroups = "docker"; # space-separated string 143 }) 144 (mkIf (cfg.settings.data_dir == "/var/lib/nomad") { 145 StateDirectory = "nomad"; 146 }) 147 ]; 148 149 unitConfig = { 150 StartLimitIntervalSec = 10; 151 StartLimitBurst = 3; 152 }; 153 }; 154 155 assertions = [ 156 { 157 assertion = cfg.dropPrivileges -> cfg.settings.data_dir == "/var/lib/nomad"; 158 message = "settings.data_dir must be equal to \"/var/lib/nomad\" if dropPrivileges is true"; 159 } 160 ]; 161 162 # Docker support requires the Docker daemon to be running. 163 virtualisation.docker.enable = mkIf cfg.enableDocker true; 164 }; 165}