at 18.09-beta 15 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 39 (e.g. <literal>serial-getty@ttyS0</literal>) from being 40 started. Note that <literal>enable=true</literal> does not 41 make a unit start by default at boot; if you want that, see 42 <literal>wantedBy</literal>. 43 ''; 44 }; 45 46 requiredBy = mkOption { 47 default = []; 48 type = types.listOf types.str; 49 description = '' 50 Units that require (i.e. depend on and need to go down with) 51 this unit. The discussion under <literal>wantedBy</literal> 52 applies here as well: inverse <literal>.requires</literal> 53 symlinks are established. 54 ''; 55 }; 56 57 wantedBy = mkOption { 58 default = []; 59 type = types.listOf types.str; 60 description = '' 61 Units that want (i.e. depend on) this unit. The standard way 62 to make a unit start by default at boot is to set this option 63 to <literal>[ "multi-user.target" ]</literal>. That's despite 64 the fact that the systemd.unit(5) manpage says this option 65 goes in the <literal>[Install]</literal> section that controls 66 the behaviour of <literal>systemctl enable</literal>. Since 67 such a process is stateful and thus contrary to the design of 68 NixOS, setting this option instead causes the equivalent 69 inverse <literal>.wants</literal> symlink to be present, 70 establishing the same desired relationship in a stateless way. 71 ''; 72 }; 73 74 aliases = mkOption { 75 default = []; 76 type = types.listOf types.str; 77 description = "Aliases of that unit."; 78 }; 79 80 }; 81 82 concreteUnitOptions = sharedOptions // { 83 84 text = mkOption { 85 type = types.nullOr types.str; 86 default = null; 87 description = "Text of this systemd unit."; 88 }; 89 90 unit = mkOption { 91 internal = true; 92 description = "The generated unit."; 93 }; 94 95 }; 96 97 commonUnitOptions = sharedOptions // { 98 99 description = mkOption { 100 default = ""; 101 type = types.str; 102 description = "Description of this unit used in systemd messages and progress indicators."; 103 }; 104 105 documentation = mkOption { 106 default = []; 107 type = types.listOf types.str; 108 description = "A list of URIs referencing documentation for this unit or its configuration."; 109 }; 110 111 requires = mkOption { 112 default = []; 113 type = types.listOf types.str; 114 description = '' 115 Start the specified units when this unit is started, and stop 116 this unit when the specified units are stopped or fail. 117 ''; 118 }; 119 120 wants = mkOption { 121 default = []; 122 type = types.listOf types.str; 123 description = '' 124 Start the specified units when this unit is started. 125 ''; 126 }; 127 128 after = mkOption { 129 default = []; 130 type = types.listOf types.str; 131 description = '' 132 If the specified units are started at the same time as 133 this unit, delay this unit until they have started. 134 ''; 135 }; 136 137 before = mkOption { 138 default = []; 139 type = types.listOf types.str; 140 description = '' 141 If the specified units are started at the same time as 142 this unit, delay them until this unit has started. 143 ''; 144 }; 145 146 bindsTo = mkOption { 147 default = []; 148 type = types.listOf types.str; 149 description = '' 150 Like requires, but in addition, if the specified units 151 unexpectedly disappear, this unit will be stopped as well. 152 ''; 153 }; 154 155 partOf = mkOption { 156 default = []; 157 type = types.listOf types.str; 158 description = '' 159 If the specified units are stopped or restarted, then this 160 unit is stopped or restarted as well. 161 ''; 162 }; 163 164 conflicts = mkOption { 165 default = []; 166 type = types.listOf types.str; 167 description = '' 168 If the specified units are started, then this unit is stopped 169 and vice versa. 170 ''; 171 }; 172 173 requisite = mkOption { 174 default = []; 175 type = types.listOf types.str; 176 description = '' 177 Similar to requires. However if the units listed are not started, 178 they will not be started and the transaction will fail. 179 ''; 180 }; 181 182 unitConfig = mkOption { 183 default = {}; 184 example = { RequiresMountsFor = "/data"; }; 185 type = types.attrsOf unitOption; 186 description = '' 187 Each attribute in this set specifies an option in the 188 <literal>[Unit]</literal> section of the unit. See 189 <citerefentry><refentrytitle>systemd.unit</refentrytitle> 190 <manvolnum>5</manvolnum></citerefentry> for details. 191 ''; 192 }; 193 194 restartTriggers = mkOption { 195 default = []; 196 type = types.listOf types.unspecified; 197 description = '' 198 An arbitrary list of items such as derivations. If any item 199 in the list changes between reconfigurations, the service will 200 be restarted. 201 ''; 202 }; 203 204 onFailure = mkOption { 205 default = []; 206 type = types.listOf types.str; 207 description = '' 208 A list of one or more units that are activated when 209 this unit enters the "failed" state. 210 ''; 211 }; 212 213 }; 214 215 216 serviceOptions = commonUnitOptions // { 217 218 environment = mkOption { 219 default = {}; 220 type = with types; attrsOf (nullOr (either str (either path package))); 221 example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; }; 222 description = "Environment variables passed to the service's processes."; 223 }; 224 225 path = mkOption { 226 default = []; 227 apply = ps: "${makeBinPath ps}:${makeSearchPathOutput "bin" "sbin" ps}"; 228 description = '' 229 Packages added to the service's <envar>PATH</envar> 230 environment variable. Both the <filename>bin</filename> 231 and <filename>sbin</filename> subdirectories of each 232 package are added. 233 ''; 234 }; 235 236 serviceConfig = mkOption { 237 default = {}; 238 example = 239 { StartLimitInterval = 10; 240 RestartSec = 5; 241 }; 242 type = types.addCheck (types.attrsOf unitOption) checkService; 243 description = '' 244 Each attribute in this set specifies an option in the 245 <literal>[Service]</literal> section of the unit. See 246 <citerefentry><refentrytitle>systemd.service</refentrytitle> 247 <manvolnum>5</manvolnum></citerefentry> for details. 248 ''; 249 }; 250 251 script = mkOption { 252 type = types.lines; 253 default = ""; 254 description = "Shell commands executed as the service's main process."; 255 }; 256 257 scriptArgs = mkOption { 258 type = types.str; 259 default = ""; 260 description = "Arguments passed to the main process script."; 261 }; 262 263 preStart = mkOption { 264 type = types.lines; 265 default = ""; 266 description = '' 267 Shell commands executed before the service's main process 268 is started. 269 ''; 270 }; 271 272 postStart = mkOption { 273 type = types.lines; 274 default = ""; 275 description = '' 276 Shell commands executed after the service's main process 277 is started. 278 ''; 279 }; 280 281 reload = mkOption { 282 type = types.lines; 283 default = ""; 284 description = '' 285 Shell commands executed when the service's main process 286 is reloaded. 287 ''; 288 }; 289 290 preStop = mkOption { 291 type = types.lines; 292 default = ""; 293 description = '' 294 Shell commands executed to stop the service. 295 ''; 296 }; 297 298 postStop = mkOption { 299 type = types.lines; 300 default = ""; 301 description = '' 302 Shell commands executed after the service's main process 303 has exited. 304 ''; 305 }; 306 307 restartIfChanged = mkOption { 308 type = types.bool; 309 default = true; 310 description = '' 311 Whether the service should be restarted during a NixOS 312 configuration switch if its definition has changed. 313 ''; 314 }; 315 316 reloadIfChanged = mkOption { 317 type = types.bool; 318 default = false; 319 description = '' 320 Whether the service should be reloaded during a NixOS 321 configuration switch if its definition has changed. If 322 enabled, the value of <option>restartIfChanged</option> is 323 ignored. 324 ''; 325 }; 326 327 stopIfChanged = mkOption { 328 type = types.bool; 329 default = true; 330 description = '' 331 If set, a changed unit is restarted by calling 332 <command>systemctl stop</command> in the old configuration, 333 then <command>systemctl start</command> in the new one. 334 Otherwise, it is restarted in a single step using 335 <command>systemctl restart</command> in the new configuration. 336 The latter is less correct because it runs the 337 <literal>ExecStop</literal> commands from the new 338 configuration. 339 ''; 340 }; 341 342 startAt = mkOption { 343 type = with types; either str (listOf str); 344 default = []; 345 example = "Sun 14:00:00"; 346 description = '' 347 Automatically start this unit at the given date/time, which 348 must be in the format described in 349 <citerefentry><refentrytitle>systemd.time</refentrytitle> 350 <manvolnum>7</manvolnum></citerefentry>. This is equivalent 351 to adding a corresponding timer unit with 352 <option>OnCalendar</option> set to the value given here. 353 ''; 354 apply = v: if isList v then v else [ v ]; 355 }; 356 357 }; 358 359 360 socketOptions = commonUnitOptions // { 361 362 listenStreams = mkOption { 363 default = []; 364 type = types.listOf types.str; 365 example = [ "0.0.0.0:993" "/run/my-socket" ]; 366 description = '' 367 For each item in this list, a <literal>ListenStream</literal> 368 option in the <literal>[Socket]</literal> section will be created. 369 ''; 370 }; 371 372 socketConfig = mkOption { 373 default = {}; 374 example = { ListenStream = "/run/my-socket"; }; 375 type = types.attrsOf unitOption; 376 description = '' 377 Each attribute in this set specifies an option in the 378 <literal>[Socket]</literal> section of the unit. See 379 <citerefentry><refentrytitle>systemd.socket</refentrytitle> 380 <manvolnum>5</manvolnum></citerefentry> for details. 381 ''; 382 }; 383 384 }; 385 386 387 timerOptions = commonUnitOptions // { 388 389 timerConfig = mkOption { 390 default = {}; 391 example = { OnCalendar = "Sun 14:00:00"; Unit = "foo.service"; }; 392 type = types.attrsOf unitOption; 393 description = '' 394 Each attribute in this set specifies an option in the 395 <literal>[Timer]</literal> section of the unit. See 396 <citerefentry><refentrytitle>systemd.timer</refentrytitle> 397 <manvolnum>7</manvolnum></citerefentry> and 398 <citerefentry><refentrytitle>systemd.time</refentrytitle> 399 <manvolnum>7</manvolnum></citerefentry> for details. 400 ''; 401 }; 402 403 }; 404 405 406 pathOptions = commonUnitOptions // { 407 408 pathConfig = mkOption { 409 default = {}; 410 example = { PathChanged = "/some/path"; Unit = "changedpath.service"; }; 411 type = types.attrsOf unitOption; 412 description = '' 413 Each attribute in this set specifies an option in the 414 <literal>[Path]</literal> section of the unit. See 415 <citerefentry><refentrytitle>systemd.path</refentrytitle> 416 <manvolnum>5</manvolnum></citerefentry> for details. 417 ''; 418 }; 419 420 }; 421 422 423 mountOptions = commonUnitOptions // { 424 425 what = mkOption { 426 example = "/dev/sda1"; 427 type = types.str; 428 description = "Absolute path of device node, file or other resource. (Mandatory)"; 429 }; 430 431 where = mkOption { 432 example = "/mnt"; 433 type = types.str; 434 description = '' 435 Absolute path of a directory of the mount point. 436 Will be created if it doesn't exist. (Mandatory) 437 ''; 438 }; 439 440 type = mkOption { 441 default = ""; 442 example = "ext4"; 443 type = types.str; 444 description = "File system type."; 445 }; 446 447 options = mkOption { 448 default = ""; 449 example = "noatime"; 450 type = types.commas; 451 description = "Options used to mount the file system."; 452 }; 453 454 mountConfig = mkOption { 455 default = {}; 456 example = { DirectoryMode = "0775"; }; 457 type = types.attrsOf unitOption; 458 description = '' 459 Each attribute in this set specifies an option in the 460 <literal>[Mount]</literal> section of the unit. See 461 <citerefentry><refentrytitle>systemd.mount</refentrytitle> 462 <manvolnum>5</manvolnum></citerefentry> for details. 463 ''; 464 }; 465 }; 466 467 automountOptions = commonUnitOptions // { 468 469 where = mkOption { 470 example = "/mnt"; 471 type = types.str; 472 description = '' 473 Absolute path of a directory of the mount point. 474 Will be created if it doesn't exist. (Mandatory) 475 ''; 476 }; 477 478 automountConfig = mkOption { 479 default = {}; 480 example = { DirectoryMode = "0775"; }; 481 type = types.attrsOf unitOption; 482 description = '' 483 Each attribute in this set specifies an option in the 484 <literal>[Automount]</literal> section of the unit. See 485 <citerefentry><refentrytitle>systemd.automount</refentrytitle> 486 <manvolnum>5</manvolnum></citerefentry> for details. 487 ''; 488 }; 489 }; 490 491 targetOptions = commonUnitOptions; 492 493 sliceOptions = commonUnitOptions // { 494 495 sliceConfig = mkOption { 496 default = {}; 497 example = { MemoryMax = "2G"; }; 498 type = types.attrsOf unitOption; 499 description = '' 500 Each attribute in this set specifies an option in the 501 <literal>[Slice]</literal> section of the unit. See 502 <citerefentry><refentrytitle>systemd.slice</refentrytitle> 503 <manvolnum>5</manvolnum></citerefentry> for details. 504 ''; 505 }; 506 507 }; 508 509}