at v192 12 kB view raw
1{ config, lib }: 2 3with lib; 4with import ./systemd-lib.nix { inherit config lib pkgs; }; 5 6let 7 checkService = checkUnitConfig "Service" [ 8 (assertValueOneOf "Type" [ 9 "simple" "forking" "oneshot" "dbus" "notify" "idle" 10 ]) 11 (assertValueOneOf "Restart" [ 12 "no" "on-success" "on-failure" "on-abnormal" "on-abort" "always" 13 ]) 14 ]; 15 16in rec { 17 18 unitOption = mkOptionType { 19 name = "systemd option"; 20 merge = loc: defs: 21 let 22 defs' = filterOverrides defs; 23 defs'' = getValues defs'; 24 in 25 if isList (head defs'') 26 then concatLists defs'' 27 else mergeOneOption loc defs'; 28 }; 29 30 sharedOptions = { 31 32 enable = mkOption { 33 default = true; 34 type = types.bool; 35 description = '' 36 If set to false, this unit will be a symlink to 37 /dev/null. This is primarily useful to prevent specific 38 template instances (e.g. <literal>serial-getty@ttyS0</literal>) 39 from being started. 40 ''; 41 }; 42 43 requiredBy = mkOption { 44 default = []; 45 type = types.listOf types.str; 46 description = "Units that require (i.e. depend on and need to go down with) this unit."; 47 }; 48 49 wantedBy = mkOption { 50 default = []; 51 type = types.listOf types.str; 52 description = "Units that want (i.e. depend on) this unit."; 53 }; 54 55 }; 56 57 concreteUnitOptions = sharedOptions // { 58 59 text = mkOption { 60 type = types.nullOr types.str; 61 default = null; 62 description = "Text of this systemd unit."; 63 }; 64 65 unit = mkOption { 66 internal = true; 67 description = "The generated unit."; 68 }; 69 70 }; 71 72 commonUnitOptions = sharedOptions // { 73 74 description = mkOption { 75 default = ""; 76 type = types.str; 77 description = "Description of this unit used in systemd messages and progress indicators."; 78 }; 79 80 requires = mkOption { 81 default = []; 82 type = types.listOf types.str; 83 description = '' 84 Start the specified units when this unit is started, and stop 85 this unit when the specified units are stopped or fail. 86 ''; 87 }; 88 89 wants = mkOption { 90 default = []; 91 type = types.listOf types.str; 92 description = '' 93 Start the specified units when this unit is started. 94 ''; 95 }; 96 97 after = mkOption { 98 default = []; 99 type = types.listOf types.str; 100 description = '' 101 If the specified units are started at the same time as 102 this unit, delay this unit until they have started. 103 ''; 104 }; 105 106 before = mkOption { 107 default = []; 108 type = types.listOf types.str; 109 description = '' 110 If the specified units are started at the same time as 111 this unit, delay them until this unit has started. 112 ''; 113 }; 114 115 bindsTo = mkOption { 116 default = []; 117 type = types.listOf types.str; 118 description = '' 119 Like requires, but in addition, if the specified units 120 unexpectedly disappear, this unit will be stopped as well. 121 ''; 122 }; 123 124 partOf = mkOption { 125 default = []; 126 type = types.listOf types.str; 127 description = '' 128 If the specified units are stopped or restarted, then this 129 unit is stopped or restarted as well. 130 ''; 131 }; 132 133 conflicts = mkOption { 134 default = []; 135 type = types.listOf types.str; 136 description = '' 137 If the specified units are started, then this unit is stopped 138 and vice versa. 139 ''; 140 }; 141 142 requisite = mkOption { 143 default = []; 144 type = types.listOf types.str; 145 description = '' 146 Similar to requires. However if the units listed are not started, 147 they will not be started and the transaction will fail. 148 ''; 149 }; 150 151 unitConfig = mkOption { 152 default = {}; 153 example = { RequiresMountsFor = "/data"; }; 154 type = types.attrsOf unitOption; 155 description = '' 156 Each attribute in this set specifies an option in the 157 <literal>[Unit]</literal> section of the unit. See 158 <citerefentry><refentrytitle>systemd.unit</refentrytitle> 159 <manvolnum>5</manvolnum></citerefentry> for details. 160 ''; 161 }; 162 163 restartTriggers = mkOption { 164 default = []; 165 type = types.listOf types.unspecified; 166 description = '' 167 An arbitrary list of items such as derivations. If any item 168 in the list changes between reconfigurations, the service will 169 be restarted. 170 ''; 171 }; 172 173 }; 174 175 176 serviceOptions = commonUnitOptions // { 177 178 environment = mkOption { 179 default = {}; 180 type = types.attrs; # FIXME 181 example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; }; 182 description = "Environment variables passed to the service's processes."; 183 }; 184 185 path = mkOption { 186 default = []; 187 apply = ps: "${makeSearchPath "bin" ps}:${makeSearchPath "sbin" ps}"; 188 description = '' 189 Packages added to the service's <envar>PATH</envar> 190 environment variable. Both the <filename>bin</filename> 191 and <filename>sbin</filename> subdirectories of each 192 package are added. 193 ''; 194 }; 195 196 serviceConfig = mkOption { 197 default = {}; 198 example = 199 { StartLimitInterval = 10; 200 RestartSec = 5; 201 }; 202 type = types.addCheck (types.attrsOf unitOption) checkService; 203 description = '' 204 Each attribute in this set specifies an option in the 205 <literal>[Service]</literal> section of the unit. See 206 <citerefentry><refentrytitle>systemd.service</refentrytitle> 207 <manvolnum>5</manvolnum></citerefentry> for details. 208 ''; 209 }; 210 211 script = mkOption { 212 type = types.lines; 213 default = ""; 214 description = "Shell commands executed as the service's main process."; 215 }; 216 217 scriptArgs = mkOption { 218 type = types.str; 219 default = ""; 220 description = "Arguments passed to the main process script."; 221 }; 222 223 preStart = mkOption { 224 type = types.lines; 225 default = ""; 226 description = '' 227 Shell commands executed before the service's main process 228 is started. 229 ''; 230 }; 231 232 postStart = mkOption { 233 type = types.lines; 234 default = ""; 235 description = '' 236 Shell commands executed after the service's main process 237 is started. 238 ''; 239 }; 240 241 reload = mkOption { 242 type = types.lines; 243 default = ""; 244 description = '' 245 Shell commands executed when the service's main process 246 is reloaded. 247 ''; 248 }; 249 250 preStop = mkOption { 251 type = types.lines; 252 default = ""; 253 description = '' 254 Shell commands executed to stop the service. 255 ''; 256 }; 257 258 postStop = mkOption { 259 type = types.lines; 260 default = ""; 261 description = '' 262 Shell commands executed after the service's main process 263 has exited. 264 ''; 265 }; 266 267 restartIfChanged = mkOption { 268 type = types.bool; 269 default = true; 270 description = '' 271 Whether the service should be restarted during a NixOS 272 configuration switch if its definition has changed. 273 ''; 274 }; 275 276 reloadIfChanged = mkOption { 277 type = types.bool; 278 default = false; 279 description = '' 280 Whether the service should be reloaded during a NixOS 281 configuration switch if its definition has changed. If 282 enabled, the value of <option>restartIfChanged</option> is 283 ignored. 284 ''; 285 }; 286 287 stopIfChanged = mkOption { 288 type = types.bool; 289 default = true; 290 description = '' 291 If set, a changed unit is restarted by calling 292 <command>systemctl stop</command> in the old configuration, 293 then <command>systemctl start</command> in the new one. 294 Otherwise, it is restarted in a single step using 295 <command>systemctl restart</command> in the new configuration. 296 The latter is less correct because it runs the 297 <literal>ExecStop</literal> commands from the new 298 configuration. 299 ''; 300 }; 301 302 startAt = mkOption { 303 type = types.str; 304 default = ""; 305 example = "Sun 14:00:00"; 306 description = '' 307 Automatically start this unit at the given date/time, which 308 must be in the format described in 309 <citerefentry><refentrytitle>systemd.time</refentrytitle> 310 <manvolnum>5</manvolnum></citerefentry>. This is equivalent 311 to adding a corresponding timer unit with 312 <option>OnCalendar</option> set to the value given here. 313 ''; 314 }; 315 316 }; 317 318 319 socketOptions = commonUnitOptions // { 320 321 listenStreams = mkOption { 322 default = []; 323 type = types.listOf types.str; 324 example = [ "0.0.0.0:993" "/run/my-socket" ]; 325 description = '' 326 For each item in this list, a <literal>ListenStream</literal> 327 option in the <literal>[Socket]</literal> section will be created. 328 ''; 329 }; 330 331 socketConfig = mkOption { 332 default = {}; 333 example = { ListenStream = "/run/my-socket"; }; 334 type = types.attrsOf unitOption; 335 description = '' 336 Each attribute in this set specifies an option in the 337 <literal>[Socket]</literal> section of the unit. See 338 <citerefentry><refentrytitle>systemd.socket</refentrytitle> 339 <manvolnum>5</manvolnum></citerefentry> for details. 340 ''; 341 }; 342 343 }; 344 345 346 timerOptions = commonUnitOptions // { 347 348 timerConfig = mkOption { 349 default = {}; 350 example = { OnCalendar = "Sun 14:00:00"; Unit = "foo.service"; }; 351 type = types.attrsOf unitOption; 352 description = '' 353 Each attribute in this set specifies an option in the 354 <literal>[Timer]</literal> section of the unit. See 355 <citerefentry><refentrytitle>systemd.timer</refentrytitle> 356 <manvolnum>5</manvolnum></citerefentry> and 357 <citerefentry><refentrytitle>systemd.time</refentrytitle> 358 <manvolnum>5</manvolnum></citerefentry> for details. 359 ''; 360 }; 361 362 }; 363 364 365 pathOptions = commonUnitOptions // { 366 367 pathConfig = mkOption { 368 default = {}; 369 example = { PathChanged = "/some/path"; Unit = "changedpath.service"; }; 370 type = types.attrsOf unitOption; 371 description = '' 372 Each attribute in this set specifies an option in the 373 <literal>[Path]</literal> section of the unit. See 374 <citerefentry><refentrytitle>systemd.path</refentrytitle> 375 <manvolnum>5</manvolnum></citerefentry> for details. 376 ''; 377 }; 378 379 }; 380 381 382 mountOptions = commonUnitOptions // { 383 384 what = mkOption { 385 example = "/dev/sda1"; 386 type = types.str; 387 description = "Absolute path of device node, file or other resource. (Mandatory)"; 388 }; 389 390 where = mkOption { 391 example = "/mnt"; 392 type = types.str; 393 description = '' 394 Absolute path of a directory of the mount point. 395 Will be created if it doesn't exist. (Mandatory) 396 ''; 397 }; 398 399 type = mkOption { 400 default = ""; 401 example = "ext4"; 402 type = types.str; 403 description = "File system type."; 404 }; 405 406 options = mkOption { 407 default = ""; 408 example = "noatime"; 409 type = types.commas; 410 description = "Options used to mount the file system."; 411 }; 412 413 mountConfig = mkOption { 414 default = {}; 415 example = { DirectoryMode = "0775"; }; 416 type = types.attrsOf unitOption; 417 description = '' 418 Each attribute in this set specifies an option in the 419 <literal>[Mount]</literal> section of the unit. See 420 <citerefentry><refentrytitle>systemd.mount</refentrytitle> 421 <manvolnum>5</manvolnum></citerefentry> for details. 422 ''; 423 }; 424 }; 425 426 automountOptions = commonUnitOptions // { 427 428 where = mkOption { 429 example = "/mnt"; 430 type = types.str; 431 description = '' 432 Absolute path of a directory of the mount point. 433 Will be created if it doesn't exist. (Mandatory) 434 ''; 435 }; 436 437 automountConfig = mkOption { 438 default = {}; 439 example = { DirectoryMode = "0775"; }; 440 type = types.attrsOf unitOption; 441 description = '' 442 Each attribute in this set specifies an option in the 443 <literal>[Automount]</literal> section of the unit. See 444 <citerefentry><refentrytitle>systemd.automount</refentrytitle> 445 <manvolnum>5</manvolnum></citerefentry> for details. 446 ''; 447 }; 448 }; 449 450 targetOptions = commonUnitOptions; 451 452}