lol

Merge pull request #297726 from r-vdp/systemd-unit-names

systemd: add a name option to all systemd units

authored by

Florian Klink and committed by
GitHub
5a2d4496 0219cfd0

+124 -63
+55 -20
nixos/lib/systemd-lib.nix
··· 1 - { config, lib, pkgs }: 1 + { config, lib, pkgs, utils }: 2 2 3 3 let 4 4 inherit (lib) ··· 396 396 }; 397 397 }; 398 398 399 - serviceConfig = { config, ... }: { 400 - config.environment.PATH = mkIf (config.path != []) "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}"; 399 + serviceConfig = { name, config, ... }: { 400 + config = { 401 + name = "${name}.service"; 402 + environment.PATH = mkIf (config.path != []) "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}"; 403 + }; 404 + }; 405 + 406 + pathConfig = { name, config, ... }: { 407 + config = { 408 + name = "${name}.path"; 409 + }; 410 + }; 411 + 412 + socketConfig = { name, config, ... }: { 413 + config = { 414 + name = "${name}.socket"; 415 + }; 416 + }; 417 + 418 + sliceConfig = { name, config, ... }: { 419 + config = { 420 + name = "${name}.slice"; 421 + }; 422 + }; 423 + 424 + targetConfig = { name, config, ... }: { 425 + config = { 426 + name = "${name}.target"; 427 + }; 428 + }; 429 + 430 + timerConfig = { name, config, ... }: { 431 + config = { 432 + name = "${name}.timer"; 433 + }; 401 434 }; 402 435 403 436 stage2ServiceConfig = { ··· 416 449 417 450 mountConfig = { config, ... }: { 418 451 config = { 452 + name = "${utils.escapeSystemdPath config.where}.mount"; 419 453 mountConfig = 420 454 { What = config.what; 421 455 Where = config.where; ··· 429 463 430 464 automountConfig = { config, ... }: { 431 465 config = { 466 + name = "${utils.escapeSystemdPath config.where}.automount"; 432 467 automountConfig = 433 468 { Where = config.where; 434 469 }; ··· 444 479 WantedBy=${concatStringsSep " " def.wantedBy} 445 480 ''; 446 481 447 - targetToUnit = name: def: 448 - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; 482 + targetToUnit = def: 483 + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; 449 484 text = 450 485 '' 451 486 [Unit] ··· 453 488 ''; 454 489 }; 455 490 456 - serviceToUnit = name: def: 457 - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; 491 + serviceToUnit = def: 492 + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; 458 493 text = commonUnitText def ('' 459 494 [Service] 460 495 '' + (let env = cfg.globalEnvironment // def.environment; ··· 463 498 "Environment=${toJSON "${n}=${env.${n}}"}\n"; 464 499 # systemd max line length is now 1MiB 465 500 # https://github.com/systemd/systemd/commit/e6dde451a51dc5aaa7f4d98d39b8fe735f73d2af 466 - in if stringLength s >= 1048576 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${name}.service’ is too long." else s) (attrNames env)) 501 + in if stringLength s >= 1048576 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${def.name}.service’ is too long." else s) (attrNames env)) 467 502 + (if def ? reloadIfChanged && def.reloadIfChanged then '' 468 503 X-ReloadIfChanged=true 469 504 '' else if (def ? restartIfChanged && !def.restartIfChanged) then '' ··· 474 509 '' + attrsToSection def.serviceConfig); 475 510 }; 476 511 477 - socketToUnit = name: def: 478 - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; 512 + socketToUnit = def: 513 + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; 479 514 text = commonUnitText def '' 480 515 [Socket] 481 516 ${attrsToSection def.socketConfig} ··· 484 519 ''; 485 520 }; 486 521 487 - timerToUnit = name: def: 488 - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; 522 + timerToUnit = def: 523 + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; 489 524 text = commonUnitText def '' 490 525 [Timer] 491 526 ${attrsToSection def.timerConfig} 492 527 ''; 493 528 }; 494 529 495 - pathToUnit = name: def: 496 - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; 530 + pathToUnit = def: 531 + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; 497 532 text = commonUnitText def '' 498 533 [Path] 499 534 ${attrsToSection def.pathConfig} 500 535 ''; 501 536 }; 502 537 503 - mountToUnit = name: def: 504 - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; 538 + mountToUnit = def: 539 + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; 505 540 text = commonUnitText def '' 506 541 [Mount] 507 542 ${attrsToSection def.mountConfig} 508 543 ''; 509 544 }; 510 545 511 - automountToUnit = name: def: 512 - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; 546 + automountToUnit = def: 547 + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; 513 548 text = commonUnitText def '' 514 549 [Automount] 515 550 ${attrsToSection def.automountConfig} 516 551 ''; 517 552 }; 518 553 519 - sliceToUnit = name: def: 520 - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; 554 + sliceToUnit = def: 555 + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; 521 556 text = commonUnitText def '' 522 557 [Slice] 523 558 ${attrsToSection def.sliceConfig}
+20 -12
nixos/lib/systemd-types.nix
··· 5 5 automountConfig 6 6 makeUnit 7 7 mountConfig 8 + pathConfig 9 + sliceConfig 10 + socketConfig 8 11 stage1ServiceConfig 9 12 stage2ServiceConfig 13 + targetConfig 14 + timerConfig 10 15 unitConfig 11 16 ; 12 17 ··· 48 53 ; 49 54 in 50 55 51 - rec { 56 + { 52 57 units = attrsOf (submodule ({ name, config, ... }: { 53 58 options = concreteUnitOptions; 54 - config = { unit = mkDefault (makeUnit name config); }; 59 + config = { 60 + name = mkDefault name; 61 + unit = mkDefault (makeUnit name config); 62 + }; 55 63 })); 56 64 57 65 services = attrsOf (submodule [ stage2ServiceOptions unitConfig stage2ServiceConfig ]); 58 66 initrdServices = attrsOf (submodule [ stage1ServiceOptions unitConfig stage1ServiceConfig ]); 59 67 60 - targets = attrsOf (submodule [ stage2CommonUnitOptions unitConfig ]); 61 - initrdTargets = attrsOf (submodule [ stage1CommonUnitOptions unitConfig ]); 68 + targets = attrsOf (submodule [ stage2CommonUnitOptions unitConfig targetConfig ]); 69 + initrdTargets = attrsOf (submodule [ stage1CommonUnitOptions unitConfig targetConfig ]); 62 70 63 - sockets = attrsOf (submodule [ stage2SocketOptions unitConfig ]); 64 - initrdSockets = attrsOf (submodule [ stage1SocketOptions unitConfig ]); 71 + sockets = attrsOf (submodule [ stage2SocketOptions unitConfig socketConfig]); 72 + initrdSockets = attrsOf (submodule [ stage1SocketOptions unitConfig socketConfig ]); 65 73 66 - timers = attrsOf (submodule [ stage2TimerOptions unitConfig ]); 67 - initrdTimers = attrsOf (submodule [ stage1TimerOptions unitConfig ]); 74 + timers = attrsOf (submodule [ stage2TimerOptions unitConfig timerConfig ]); 75 + initrdTimers = attrsOf (submodule [ stage1TimerOptions unitConfig timerConfig ]); 68 76 69 - paths = attrsOf (submodule [ stage2PathOptions unitConfig ]); 70 - initrdPaths = attrsOf (submodule [ stage1PathOptions unitConfig ]); 77 + paths = attrsOf (submodule [ stage2PathOptions unitConfig pathConfig ]); 78 + initrdPaths = attrsOf (submodule [ stage1PathOptions unitConfig pathConfig ]); 71 79 72 - slices = attrsOf (submodule [ stage2SliceOptions unitConfig ]); 73 - initrdSlices = attrsOf (submodule [ stage1SliceOptions unitConfig ]); 80 + slices = attrsOf (submodule [ stage2SliceOptions unitConfig sliceConfig ]); 81 + initrdSlices = attrsOf (submodule [ stage1SliceOptions unitConfig sliceConfig ]); 74 82 75 83 mounts = listOf (submodule [ stage2MountOptions unitConfig mountConfig ]); 76 84 initrdMounts = listOf (submodule [ stage1MountOptions unitConfig mountConfig ]);
+8
nixos/lib/systemd-unit-options.nix
··· 65 65 ''; 66 66 }; 67 67 68 + name = lib.mkOption { 69 + type = lib.types.str; 70 + description = '' 71 + The name of this systemd unit, including its extension. 72 + This can be used to refer to this unit from other systemd units. 73 + ''; 74 + }; 75 + 68 76 overrideStrategy = mkOption { 69 77 default = "asDropinIfExists"; 70 78 type = types.enum [ "asDropinIfExists" "asDropin" ];
+5 -3
nixos/lib/utils.nix
··· 35 35 inherit (lib.strings) toJSON normalizePath escapeC; 36 36 in 37 37 38 - rec { 38 + let 39 + utils = rec { 39 40 40 41 # Copy configuration files to avoid having the entire sources in the system closure 41 42 copyFile = filePath: pkgs.runCommand (builtins.unsafeDiscardStringContext (baseNameOf filePath)) {} '' ··· 262 263 filter (x: !(elem (getName x) namesToRemove)) packages; 263 264 264 265 systemdUtils = { 265 - lib = import ./systemd-lib.nix { inherit lib config pkgs; }; 266 + lib = import ./systemd-lib.nix { inherit lib config pkgs utils; }; 266 267 unitOptions = import ./systemd-unit-options.nix { inherit lib systemdUtils; }; 267 268 types = import ./systemd-types.nix { inherit lib systemdUtils pkgs; }; 268 269 network = { 269 270 units = import ./systemd-network-units.nix { inherit lib systemdUtils; }; 270 271 }; 271 272 }; 272 - } 273 + }; 274 + in utils
+11 -12
nixos/modules/system/boot/systemd.nix
··· 595 595 }; 596 596 597 597 systemd.units = 598 - mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths 599 - // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services 600 - // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.slices 601 - // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets 602 - // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets 603 - // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.timers 604 - // listToAttrs (map 605 - (v: let n = escapeSystemdPath v.where; 606 - in nameValuePair "${n}.mount" (mountToUnit n v)) cfg.mounts) 607 - // listToAttrs (map 608 - (v: let n = escapeSystemdPath v.where; 609 - in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts); 598 + let 599 + withName = cfgToUnit: cfg: lib.nameValuePair cfg.name (cfgToUnit cfg); 600 + in 601 + mapAttrs' (_: withName pathToUnit) cfg.paths 602 + // mapAttrs' (_: withName serviceToUnit) cfg.services 603 + // mapAttrs' (_: withName sliceToUnit) cfg.slices 604 + // mapAttrs' (_: withName socketToUnit) cfg.sockets 605 + // mapAttrs' (_: withName targetToUnit) cfg.targets 606 + // mapAttrs' (_: withName timerToUnit) cfg.timers 607 + // listToAttrs (map (withName mountToUnit) cfg.mounts) 608 + // listToAttrs (map (withName automountToUnit) cfg.automounts); 610 609 611 610 # Environment of PID 1 612 611 systemd.managerEnvironment = {
+8 -8
nixos/modules/system/boot/systemd/initrd.nix
··· 490 490 491 491 targets.initrd.aliases = ["default.target"]; 492 492 units = 493 - mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths 494 - // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services 495 - // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.slices 496 - // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets 497 - // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets 498 - // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.timers 493 + mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit v)) cfg.paths 494 + // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit v)) cfg.services 495 + // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit v)) cfg.slices 496 + // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit v)) cfg.sockets 497 + // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit v)) cfg.targets 498 + // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit v)) cfg.timers 499 499 // listToAttrs (map 500 500 (v: let n = escapeSystemdPath v.where; 501 - in nameValuePair "${n}.mount" (mountToUnit n v)) cfg.mounts) 501 + in nameValuePair "${n}.mount" (mountToUnit v)) cfg.mounts) 502 502 // listToAttrs (map 503 503 (v: let n = escapeSystemdPath v.where; 504 - in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts); 504 + in nameValuePair "${n}.automount" (automountToUnit v)) cfg.automounts); 505 505 506 506 # make sure all the /dev nodes are set up 507 507 services.systemd-tmpfiles-setup-dev.wantedBy = ["sysinit.target"];
+6 -6
nixos/modules/system/boot/systemd/user.nix
··· 175 175 }; 176 176 177 177 systemd.user.units = 178 - mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths 179 - // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services 180 - // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.slices 181 - // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets 182 - // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets 183 - // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.timers; 178 + mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit v)) cfg.paths 179 + // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit v)) cfg.services 180 + // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit v)) cfg.slices 181 + // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit v)) cfg.sockets 182 + // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit v)) cfg.targets 183 + // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit v)) cfg.timers; 184 184 185 185 # Generate timer units for all services that have a ‘startAt’ value. 186 186 systemd.user.timers =
+11 -2
nixos/tests/systemd.nix
··· 1 1 import ./make-test-python.nix ({ pkgs, ... }: { 2 2 name = "systemd"; 3 3 4 - nodes.machine = { lib, ... }: { 4 + nodes.machine = { config, lib, ... }: { 5 5 imports = [ common/user-account.nix common/x11.nix ]; 6 6 7 7 virtualisation.emptyDiskImages = [ 512 512 ]; ··· 38 38 script = "true"; 39 39 }; 40 40 41 + systemd.services.testDependency1 = { 42 + description = "Test Dependency 1"; 43 + wantedBy = [ config.systemd.services."testservice1".name ]; 44 + serviceConfig.Type = "oneshot"; 45 + script = '' 46 + true 47 + ''; 48 + }; 49 + 41 50 systemd.services.testservice1 = { 42 51 description = "Test Service 1"; 43 - wantedBy = [ "multi-user.target" ]; 52 + wantedBy = [ config.systemd.targets.multi-user.name ]; 44 53 serviceConfig.Type = "oneshot"; 45 54 script = '' 46 55 if [ "$XXX_SYSTEM" = foo ]; then