at 16.09-beta 13 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 onFailure = mkOption { 174 default = []; 175 type = types.listOf types.str; 176 description = '' 177 A list of one or more units that are activated when 178 this unit enters the "failed" state. 179 ''; 180 }; 181 182 }; 183 184 185 serviceOptions = commonUnitOptions // { 186 187 environment = mkOption { 188 default = {}; 189 type = types.attrs; # FIXME 190 example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; }; 191 description = "Environment variables passed to the service's processes."; 192 }; 193 194 path = mkOption { 195 default = []; 196 apply = ps: "${makeBinPath ps}:${makeSearchPathOutput "bin" "sbin" ps}"; 197 description = '' 198 Packages added to the service's <envar>PATH</envar> 199 environment variable. Both the <filename>bin</filename> 200 and <filename>sbin</filename> subdirectories of each 201 package are added. 202 ''; 203 }; 204 205 serviceConfig = mkOption { 206 default = {}; 207 example = 208 { StartLimitInterval = 10; 209 RestartSec = 5; 210 }; 211 type = types.addCheck (types.attrsOf unitOption) checkService; 212 description = '' 213 Each attribute in this set specifies an option in the 214 <literal>[Service]</literal> section of the unit. See 215 <citerefentry><refentrytitle>systemd.service</refentrytitle> 216 <manvolnum>5</manvolnum></citerefentry> for details. 217 ''; 218 }; 219 220 script = mkOption { 221 type = types.lines; 222 default = ""; 223 description = "Shell commands executed as the service's main process."; 224 }; 225 226 scriptArgs = mkOption { 227 type = types.str; 228 default = ""; 229 description = "Arguments passed to the main process script."; 230 }; 231 232 preStart = mkOption { 233 type = types.lines; 234 default = ""; 235 description = '' 236 Shell commands executed before the service's main process 237 is started. 238 ''; 239 }; 240 241 postStart = mkOption { 242 type = types.lines; 243 default = ""; 244 description = '' 245 Shell commands executed after the service's main process 246 is started. 247 ''; 248 }; 249 250 reload = mkOption { 251 type = types.lines; 252 default = ""; 253 description = '' 254 Shell commands executed when the service's main process 255 is reloaded. 256 ''; 257 }; 258 259 preStop = mkOption { 260 type = types.lines; 261 default = ""; 262 description = '' 263 Shell commands executed to stop the service. 264 ''; 265 }; 266 267 postStop = mkOption { 268 type = types.lines; 269 default = ""; 270 description = '' 271 Shell commands executed after the service's main process 272 has exited. 273 ''; 274 }; 275 276 restartIfChanged = mkOption { 277 type = types.bool; 278 default = true; 279 description = '' 280 Whether the service should be restarted during a NixOS 281 configuration switch if its definition has changed. 282 ''; 283 }; 284 285 reloadIfChanged = mkOption { 286 type = types.bool; 287 default = false; 288 description = '' 289 Whether the service should be reloaded during a NixOS 290 configuration switch if its definition has changed. If 291 enabled, the value of <option>restartIfChanged</option> is 292 ignored. 293 ''; 294 }; 295 296 stopIfChanged = mkOption { 297 type = types.bool; 298 default = true; 299 description = '' 300 If set, a changed unit is restarted by calling 301 <command>systemctl stop</command> in the old configuration, 302 then <command>systemctl start</command> in the new one. 303 Otherwise, it is restarted in a single step using 304 <command>systemctl restart</command> in the new configuration. 305 The latter is less correct because it runs the 306 <literal>ExecStop</literal> commands from the new 307 configuration. 308 ''; 309 }; 310 311 startAt = mkOption { 312 type = with types; either str (listOf str); 313 default = ""; 314 example = "Sun 14:00:00"; 315 description = '' 316 Automatically start this unit at the given date/time, which 317 must be in the format described in 318 <citerefentry><refentrytitle>systemd.time</refentrytitle> 319 <manvolnum>5</manvolnum></citerefentry>. This is equivalent 320 to adding a corresponding timer unit with 321 <option>OnCalendar</option> set to the value given here. 322 ''; 323 }; 324 325 }; 326 327 328 socketOptions = commonUnitOptions // { 329 330 listenStreams = mkOption { 331 default = []; 332 type = types.listOf types.str; 333 example = [ "0.0.0.0:993" "/run/my-socket" ]; 334 description = '' 335 For each item in this list, a <literal>ListenStream</literal> 336 option in the <literal>[Socket]</literal> section will be created. 337 ''; 338 }; 339 340 socketConfig = mkOption { 341 default = {}; 342 example = { ListenStream = "/run/my-socket"; }; 343 type = types.attrsOf unitOption; 344 description = '' 345 Each attribute in this set specifies an option in the 346 <literal>[Socket]</literal> section of the unit. See 347 <citerefentry><refentrytitle>systemd.socket</refentrytitle> 348 <manvolnum>5</manvolnum></citerefentry> for details. 349 ''; 350 }; 351 352 }; 353 354 355 timerOptions = commonUnitOptions // { 356 357 timerConfig = mkOption { 358 default = {}; 359 example = { OnCalendar = "Sun 14:00:00"; Unit = "foo.service"; }; 360 type = types.attrsOf unitOption; 361 description = '' 362 Each attribute in this set specifies an option in the 363 <literal>[Timer]</literal> section of the unit. See 364 <citerefentry><refentrytitle>systemd.timer</refentrytitle> 365 <manvolnum>5</manvolnum></citerefentry> and 366 <citerefentry><refentrytitle>systemd.time</refentrytitle> 367 <manvolnum>5</manvolnum></citerefentry> for details. 368 ''; 369 }; 370 371 }; 372 373 374 pathOptions = commonUnitOptions // { 375 376 pathConfig = mkOption { 377 default = {}; 378 example = { PathChanged = "/some/path"; Unit = "changedpath.service"; }; 379 type = types.attrsOf unitOption; 380 description = '' 381 Each attribute in this set specifies an option in the 382 <literal>[Path]</literal> section of the unit. See 383 <citerefentry><refentrytitle>systemd.path</refentrytitle> 384 <manvolnum>5</manvolnum></citerefentry> for details. 385 ''; 386 }; 387 388 }; 389 390 391 mountOptions = commonUnitOptions // { 392 393 what = mkOption { 394 example = "/dev/sda1"; 395 type = types.str; 396 description = "Absolute path of device node, file or other resource. (Mandatory)"; 397 }; 398 399 where = mkOption { 400 example = "/mnt"; 401 type = types.str; 402 description = '' 403 Absolute path of a directory of the mount point. 404 Will be created if it doesn't exist. (Mandatory) 405 ''; 406 }; 407 408 type = mkOption { 409 default = ""; 410 example = "ext4"; 411 type = types.str; 412 description = "File system type."; 413 }; 414 415 options = mkOption { 416 default = ""; 417 example = "noatime"; 418 type = types.commas; 419 description = "Options used to mount the file system."; 420 }; 421 422 mountConfig = mkOption { 423 default = {}; 424 example = { DirectoryMode = "0775"; }; 425 type = types.attrsOf unitOption; 426 description = '' 427 Each attribute in this set specifies an option in the 428 <literal>[Mount]</literal> section of the unit. See 429 <citerefentry><refentrytitle>systemd.mount</refentrytitle> 430 <manvolnum>5</manvolnum></citerefentry> for details. 431 ''; 432 }; 433 }; 434 435 automountOptions = commonUnitOptions // { 436 437 where = mkOption { 438 example = "/mnt"; 439 type = types.str; 440 description = '' 441 Absolute path of a directory of the mount point. 442 Will be created if it doesn't exist. (Mandatory) 443 ''; 444 }; 445 446 automountConfig = mkOption { 447 default = {}; 448 example = { DirectoryMode = "0775"; }; 449 type = types.attrsOf unitOption; 450 description = '' 451 Each attribute in this set specifies an option in the 452 <literal>[Automount]</literal> section of the unit. See 453 <citerefentry><refentrytitle>systemd.automount</refentrytitle> 454 <manvolnum>5</manvolnum></citerefentry> for details. 455 ''; 456 }; 457 }; 458 459 targetOptions = commonUnitOptions; 460 461}