at 23.11-beta 23 kB view raw
1{ config, lib, pkgs, utils, ... }: 2 3with utils; 4with systemdUtils.unitOptions; 5with lib; 6 7let 8 9 cfg = config.systemd; 10 11 inherit (systemdUtils.lib) 12 generateUnits 13 targetToUnit 14 serviceToUnit 15 socketToUnit 16 timerToUnit 17 pathToUnit 18 mountToUnit 19 automountToUnit 20 sliceToUnit; 21 22 upstreamSystemUnits = 23 [ # Targets. 24 "basic.target" 25 "sysinit.target" 26 "sockets.target" 27 "exit.target" 28 "graphical.target" 29 "multi-user.target" 30 "network.target" 31 "network-pre.target" 32 "network-online.target" 33 "nss-lookup.target" 34 "nss-user-lookup.target" 35 "time-sync.target" 36 ] ++ optionals cfg.package.withCryptsetup [ 37 "cryptsetup.target" 38 "cryptsetup-pre.target" 39 "remote-cryptsetup.target" 40 ] ++ [ 41 "sigpwr.target" 42 "timers.target" 43 "paths.target" 44 "rpcbind.target" 45 46 # Rescue mode. 47 "rescue.target" 48 "rescue.service" 49 50 # Udev. 51 "systemd-tmpfiles-setup-dev-early.service" 52 "systemd-udevd-control.socket" 53 "systemd-udevd-kernel.socket" 54 "systemd-udevd.service" 55 "systemd-udev-settle.service" 56 ] ++ (optional (!config.boot.isContainer) "systemd-udev-trigger.service") ++ [ 57 # hwdb.bin is managed by NixOS 58 # "systemd-hwdb-update.service" 59 60 # Consoles. 61 "getty.target" 62 "getty-pre.target" 63 "getty@.service" 64 "serial-getty@.service" 65 "console-getty.service" 66 "container-getty@.service" 67 "systemd-vconsole-setup.service" 68 69 # Hardware (started by udev when a relevant device is plugged in). 70 "sound.target" 71 "bluetooth.target" 72 "printer.target" 73 "smartcard.target" 74 75 # Kernel module loading. 76 "systemd-modules-load.service" 77 "kmod-static-nodes.service" 78 "modprobe@.service" 79 80 # Filesystems. 81 "systemd-fsck@.service" 82 "systemd-fsck-root.service" 83 "systemd-growfs@.service" 84 "systemd-growfs-root.service" 85 "systemd-remount-fs.service" 86 "systemd-pstore.service" 87 "local-fs.target" 88 "local-fs-pre.target" 89 "remote-fs.target" 90 "remote-fs-pre.target" 91 "swap.target" 92 "dev-hugepages.mount" 93 "dev-mqueue.mount" 94 "sys-fs-fuse-connections.mount" 95 ] ++ (optional (!config.boot.isContainer) "sys-kernel-config.mount") ++ [ 96 "sys-kernel-debug.mount" 97 98 # Maintaining state across reboots. 99 "systemd-random-seed.service" 100 "systemd-backlight@.service" 101 "systemd-rfkill.service" 102 "systemd-rfkill.socket" 103 104 # Hibernate / suspend. 105 "hibernate.target" 106 "suspend.target" 107 "suspend-then-hibernate.target" 108 "sleep.target" 109 "hybrid-sleep.target" 110 "systemd-hibernate.service" 111 "systemd-hybrid-sleep.service" 112 "systemd-suspend.service" 113 "systemd-suspend-then-hibernate.service" 114 115 # Reboot stuff. 116 "reboot.target" 117 "systemd-reboot.service" 118 "poweroff.target" 119 "systemd-poweroff.service" 120 "halt.target" 121 "systemd-halt.service" 122 "shutdown.target" 123 "umount.target" 124 "final.target" 125 "kexec.target" 126 "systemd-kexec.service" 127 ] ++ lib.optional cfg.package.withUtmp "systemd-update-utmp.service" ++ [ 128 129 # Password entry. 130 "systemd-ask-password-console.path" 131 "systemd-ask-password-console.service" 132 "systemd-ask-password-wall.path" 133 "systemd-ask-password-wall.service" 134 135 # Slices / containers. 136 "slices.target" 137 ] ++ optionals cfg.package.withImportd [ 138 "systemd-importd.service" 139 ] ++ optionals cfg.package.withMachined [ 140 "machine.slice" 141 "machines.target" 142 "systemd-machined.service" 143 ] ++ [ 144 "systemd-nspawn@.service" 145 146 # Misc. 147 "systemd-sysctl.service" 148 ] ++ optionals cfg.package.withTimedated [ 149 "dbus-org.freedesktop.timedate1.service" 150 "systemd-timedated.service" 151 ] ++ optionals cfg.package.withLocaled [ 152 "dbus-org.freedesktop.locale1.service" 153 "systemd-localed.service" 154 ] ++ optionals cfg.package.withHostnamed [ 155 "dbus-org.freedesktop.hostname1.service" 156 "systemd-hostnamed.service" 157 ] ++ optionals cfg.package.withPortabled [ 158 "dbus-org.freedesktop.portable1.service" 159 "systemd-portabled.service" 160 ] ++ [ 161 "systemd-exit.service" 162 "systemd-update-done.service" 163 ] ++ cfg.additionalUpstreamSystemUnits; 164 165 upstreamSystemWants = 166 [ "sysinit.target.wants" 167 "sockets.target.wants" 168 "local-fs.target.wants" 169 "multi-user.target.wants" 170 "timers.target.wants" 171 ]; 172 173 proxy_env = config.networking.proxy.envVars; 174 175in 176 177{ 178 ###### interface 179 180 options = { 181 182 systemd.package = mkOption { 183 default = pkgs.systemd; 184 defaultText = literalExpression "pkgs.systemd"; 185 type = types.package; 186 description = lib.mdDoc "The systemd package."; 187 }; 188 189 systemd.units = mkOption { 190 description = lib.mdDoc "Definition of systemd units."; 191 default = {}; 192 type = systemdUtils.types.units; 193 }; 194 195 systemd.packages = mkOption { 196 default = []; 197 type = types.listOf types.package; 198 example = literalExpression "[ pkgs.systemd-cryptsetup-generator ]"; 199 description = lib.mdDoc "Packages providing systemd units and hooks."; 200 }; 201 202 systemd.targets = mkOption { 203 default = {}; 204 type = systemdUtils.types.targets; 205 description = lib.mdDoc "Definition of systemd target units."; 206 }; 207 208 systemd.services = mkOption { 209 default = {}; 210 type = systemdUtils.types.services; 211 description = lib.mdDoc "Definition of systemd service units."; 212 }; 213 214 systemd.sockets = mkOption { 215 default = {}; 216 type = systemdUtils.types.sockets; 217 description = lib.mdDoc "Definition of systemd socket units."; 218 }; 219 220 systemd.timers = mkOption { 221 default = {}; 222 type = systemdUtils.types.timers; 223 description = lib.mdDoc "Definition of systemd timer units."; 224 }; 225 226 systemd.paths = mkOption { 227 default = {}; 228 type = systemdUtils.types.paths; 229 description = lib.mdDoc "Definition of systemd path units."; 230 }; 231 232 systemd.mounts = mkOption { 233 default = []; 234 type = systemdUtils.types.mounts; 235 description = lib.mdDoc '' 236 Definition of systemd mount units. 237 This is a list instead of an attrSet, because systemd mandates the names to be derived from 238 the 'where' attribute. 239 ''; 240 }; 241 242 systemd.automounts = mkOption { 243 default = []; 244 type = systemdUtils.types.automounts; 245 description = lib.mdDoc '' 246 Definition of systemd automount units. 247 This is a list instead of an attrSet, because systemd mandates the names to be derived from 248 the 'where' attribute. 249 ''; 250 }; 251 252 systemd.slices = mkOption { 253 default = {}; 254 type = systemdUtils.types.slices; 255 description = lib.mdDoc "Definition of slice configurations."; 256 }; 257 258 systemd.generators = mkOption { 259 type = types.attrsOf types.path; 260 default = {}; 261 example = { systemd-gpt-auto-generator = "/dev/null"; }; 262 description = lib.mdDoc '' 263 Definition of systemd generators. 264 For each `NAME = VALUE` pair of the attrSet, a link is generated from 265 `/etc/systemd/system-generators/NAME` to `VALUE`. 266 ''; 267 }; 268 269 systemd.shutdown = mkOption { 270 type = types.attrsOf types.path; 271 default = {}; 272 description = lib.mdDoc '' 273 Definition of systemd shutdown executables. 274 For each `NAME = VALUE` pair of the attrSet, a link is generated from 275 `/etc/systemd/system-shutdown/NAME` to `VALUE`. 276 ''; 277 }; 278 279 systemd.defaultUnit = mkOption { 280 default = "multi-user.target"; 281 type = types.str; 282 description = lib.mdDoc "Default unit started when the system boots."; 283 }; 284 285 systemd.ctrlAltDelUnit = mkOption { 286 default = "reboot.target"; 287 type = types.str; 288 example = "poweroff.target"; 289 description = lib.mdDoc '' 290 Target that should be started when Ctrl-Alt-Delete is pressed. 291 ''; 292 }; 293 294 systemd.globalEnvironment = mkOption { 295 type = with types; attrsOf (nullOr (oneOf [ str path package ])); 296 default = {}; 297 example = { TZ = "CET"; }; 298 description = lib.mdDoc '' 299 Environment variables passed to *all* systemd units. 300 ''; 301 }; 302 303 systemd.managerEnvironment = mkOption { 304 type = with types; attrsOf (nullOr (oneOf [ str path package ])); 305 default = {}; 306 example = { SYSTEMD_LOG_LEVEL = "debug"; }; 307 description = lib.mdDoc '' 308 Environment variables of PID 1. These variables are 309 *not* passed to started units. 310 ''; 311 }; 312 313 systemd.enableCgroupAccounting = mkOption { 314 default = true; 315 type = types.bool; 316 description = lib.mdDoc '' 317 Whether to enable cgroup accounting. 318 ''; 319 }; 320 321 systemd.enableUnifiedCgroupHierarchy = mkOption { 322 default = true; 323 type = types.bool; 324 description = lib.mdDoc '' 325 Whether to enable the unified cgroup hierarchy (cgroupsv2). 326 ''; 327 }; 328 329 systemd.extraConfig = mkOption { 330 default = ""; 331 type = types.lines; 332 example = "DefaultLimitCORE=infinity"; 333 description = lib.mdDoc '' 334 Extra config options for systemd. See systemd-system.conf(5) man page 335 for available options. 336 ''; 337 }; 338 339 systemd.sleep.extraConfig = mkOption { 340 default = ""; 341 type = types.lines; 342 example = "HibernateDelaySec=1h"; 343 description = lib.mdDoc '' 344 Extra config options for systemd sleep state logic. 345 See sleep.conf.d(5) man page for available options. 346 ''; 347 }; 348 349 systemd.additionalUpstreamSystemUnits = mkOption { 350 default = [ ]; 351 type = types.listOf types.str; 352 example = [ "debug-shell.service" "systemd-quotacheck.service" ]; 353 description = lib.mdDoc '' 354 Additional units shipped with systemd that shall be enabled. 355 ''; 356 }; 357 358 systemd.suppressedSystemUnits = mkOption { 359 default = [ ]; 360 type = types.listOf types.str; 361 example = [ "systemd-backlight@.service" ]; 362 description = lib.mdDoc '' 363 A list of units to skip when generating system systemd configuration directory. This has 364 priority over upstream units, {option}`systemd.units`, and 365 {option}`systemd.additionalUpstreamSystemUnits`. The main purpose of this is to 366 prevent a upstream systemd unit from being added to the initrd with any modifications made to it 367 by other NixOS modules. 368 ''; 369 }; 370 371 systemd.watchdog.device = mkOption { 372 type = types.nullOr types.path; 373 default = null; 374 example = "/dev/watchdog"; 375 description = lib.mdDoc '' 376 The path to a hardware watchdog device which will be managed by systemd. 377 If not specified, systemd will default to /dev/watchdog. 378 ''; 379 }; 380 381 systemd.watchdog.runtimeTime = mkOption { 382 type = types.nullOr types.str; 383 default = null; 384 example = "30s"; 385 description = lib.mdDoc '' 386 The amount of time which can elapse before a watchdog hardware device 387 will automatically reboot the system. Valid time units include "ms", 388 "s", "min", "h", "d", and "w". 389 ''; 390 }; 391 392 systemd.watchdog.rebootTime = mkOption { 393 type = types.nullOr types.str; 394 default = null; 395 example = "10m"; 396 description = lib.mdDoc '' 397 The amount of time which can elapse after a reboot has been triggered 398 before a watchdog hardware device will automatically reboot the system. 399 Valid time units include "ms", "s", "min", "h", "d", and "w". If left 400 `null`, systemd will use its default of `10min`; see also {command}`man 401 5 systemd-system.conf`. 402 ''; 403 }; 404 405 systemd.watchdog.kexecTime = mkOption { 406 type = types.nullOr types.str; 407 default = null; 408 example = "10m"; 409 description = lib.mdDoc '' 410 The amount of time which can elapse when kexec is being executed before 411 a watchdog hardware device will automatically reboot the system. This 412 option should only be enabled if reloadTime is also enabled. Valid 413 time units include "ms", "s", "min", "h", "d", and "w". 414 ''; 415 }; 416 }; 417 418 419 ###### implementation 420 421 config = { 422 423 warnings = concatLists ( 424 mapAttrsToList 425 (name: service: 426 let 427 type = service.serviceConfig.Type or ""; 428 restart = service.serviceConfig.Restart or "no"; 429 hasDeprecated = builtins.hasAttr "StartLimitInterval" service.serviceConfig; 430 in 431 concatLists [ 432 (optional (type == "oneshot" && (restart == "always" || restart == "on-success")) 433 "Service '${name}.service' with 'Type=oneshot' cannot have 'Restart=always' or 'Restart=on-success'" 434 ) 435 (optional hasDeprecated 436 "Service '${name}.service' uses the attribute 'StartLimitInterval' in the Service section, which is deprecated. See https://github.com/NixOS/nixpkgs/issues/45786." 437 ) 438 (optional (service.reloadIfChanged && service.reloadTriggers != []) 439 "Service '${name}.service' has both 'reloadIfChanged' and 'reloadTriggers' set. This is probably not what you want, because 'reloadTriggers' behave the same whay as 'restartTriggers' if 'reloadIfChanged' is set." 440 ) 441 ] 442 ) 443 cfg.services 444 ); 445 446 system.build.units = cfg.units; 447 448 system.nssModules = [ cfg.package.out ]; 449 system.nssDatabases = { 450 hosts = (mkMerge [ 451 (mkOrder 400 ["mymachines"]) # 400 to ensure it comes before resolve (which is mkBefore'd) 452 (mkOrder 999 ["myhostname"]) # after files (which is 998), but before regular nss modules 453 ]); 454 passwd = (mkMerge [ 455 (mkAfter [ "systemd" ]) 456 ]); 457 group = (mkMerge [ 458 (mkAfter [ "[success=merge] systemd" ]) # need merge so that NSS won't stop at file-based groups 459 ]); 460 }; 461 462 environment.systemPackages = [ cfg.package ]; 463 464 environment.etc = let 465 # generate contents for /etc/systemd/system-${type} from attrset of links and packages 466 hooks = type: links: pkgs.runCommand "system-${type}" { 467 preferLocalBuild = true; 468 packages = cfg.packages; 469 } '' 470 set -e 471 mkdir -p $out 472 for package in $packages 473 do 474 for hook in $package/lib/systemd/system-${type}/* 475 do 476 ln -s $hook $out/ 477 done 478 done 479 ${concatStrings (mapAttrsToList (exec: target: "ln -s ${target} $out/${exec};\n") links)} 480 ''; 481 482 enabledUpstreamSystemUnits = filter (n: ! elem n cfg.suppressedSystemUnits) upstreamSystemUnits; 483 enabledUnits = filterAttrs (n: v: ! elem n cfg.suppressedSystemUnits) cfg.units; 484 485 in ({ 486 "systemd/system".source = generateUnits { 487 type = "system"; 488 units = enabledUnits; 489 upstreamUnits = enabledUpstreamSystemUnits; 490 upstreamWants = upstreamSystemWants; 491 }; 492 493 "systemd/system.conf".text = '' 494 [Manager] 495 ManagerEnvironment=${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "${n}=${lib.escapeShellArg v}") cfg.managerEnvironment)} 496 ${optionalString config.systemd.enableCgroupAccounting '' 497 DefaultCPUAccounting=yes 498 DefaultIOAccounting=yes 499 DefaultBlockIOAccounting=yes 500 DefaultIPAccounting=yes 501 ''} 502 DefaultLimitCORE=infinity 503 ${optionalString (config.systemd.watchdog.device != null) '' 504 WatchdogDevice=${config.systemd.watchdog.device} 505 ''} 506 ${optionalString (config.systemd.watchdog.runtimeTime != null) '' 507 RuntimeWatchdogSec=${config.systemd.watchdog.runtimeTime} 508 ''} 509 ${optionalString (config.systemd.watchdog.rebootTime != null) '' 510 RebootWatchdogSec=${config.systemd.watchdog.rebootTime} 511 ''} 512 ${optionalString (config.systemd.watchdog.kexecTime != null) '' 513 KExecWatchdogSec=${config.systemd.watchdog.kexecTime} 514 ''} 515 516 ${config.systemd.extraConfig} 517 ''; 518 519 "systemd/sleep.conf".text = '' 520 [Sleep] 521 ${config.systemd.sleep.extraConfig} 522 ''; 523 524 "systemd/system-generators" = { source = hooks "generators" cfg.generators; }; 525 "systemd/system-shutdown" = { source = hooks "shutdown" cfg.shutdown; }; 526 }); 527 528 services.dbus.enable = true; 529 530 users.users.systemd-network = { 531 uid = config.ids.uids.systemd-network; 532 group = "systemd-network"; 533 }; 534 users.groups.systemd-network.gid = config.ids.gids.systemd-network; 535 users.users.systemd-resolve = { 536 uid = config.ids.uids.systemd-resolve; 537 group = "systemd-resolve"; 538 }; 539 users.groups.systemd-resolve.gid = config.ids.gids.systemd-resolve; 540 541 # Target for ‘charon send-keys’ to hook into. 542 users.groups.keys.gid = config.ids.gids.keys; 543 544 systemd.targets.keys = 545 { description = "Security Keys"; 546 unitConfig.X-StopOnReconfiguration = true; 547 }; 548 549 systemd.units = 550 mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths 551 // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services 552 // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.slices 553 // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets 554 // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets 555 // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.timers 556 // listToAttrs (map 557 (v: let n = escapeSystemdPath v.where; 558 in nameValuePair "${n}.mount" (mountToUnit n v)) cfg.mounts) 559 // listToAttrs (map 560 (v: let n = escapeSystemdPath v.where; 561 in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts); 562 563 # Environment of PID 1 564 systemd.managerEnvironment = { 565 # Doesn't contain systemd itself - everything works so it seems to use the compiled-in value for its tools 566 # util-linux is needed for the main fsck utility wrapping the fs-specific ones 567 PATH = lib.makeBinPath (config.system.fsPackages ++ [cfg.package.util-linux]); 568 LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive"; 569 TZDIR = "/etc/zoneinfo"; 570 # If SYSTEMD_UNIT_PATH ends with an empty component (":"), the usual unit load path will be appended to the contents of the variable 571 SYSTEMD_UNIT_PATH = lib.mkIf (config.boot.extraSystemdUnitPaths != []) "${builtins.concatStringsSep ":" config.boot.extraSystemdUnitPaths}:"; 572 }; 573 574 575 system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled 576 [ "DEVTMPFS" "CGROUPS" "INOTIFY_USER" "SIGNALFD" "TIMERFD" "EPOLL" "NET" 577 "SYSFS" "PROC_FS" "FHANDLE" "CRYPTO_USER_API_HASH" "CRYPTO_HMAC" 578 "CRYPTO_SHA256" "DMIID" "AUTOFS_FS" "TMPFS_POSIX_ACL" 579 "TMPFS_XATTR" "SECCOMP" 580 ]; 581 582 # Generate timer units for all services that have a ‘startAt’ value. 583 systemd.timers = 584 mapAttrs (name: service: 585 { wantedBy = [ "timers.target" ]; 586 timerConfig.OnCalendar = service.startAt; 587 }) 588 (filterAttrs (name: service: service.enable && service.startAt != []) cfg.services); 589 590 # Some overrides to upstream units. 591 systemd.services."systemd-backlight@".restartIfChanged = false; 592 systemd.services."systemd-fsck@".restartIfChanged = false; 593 systemd.services."systemd-fsck@".path = [ pkgs.util-linux ] ++ config.system.fsPackages; 594 systemd.services."systemd-makefs@" = { 595 restartIfChanged = false; 596 path = [ pkgs.util-linux ] ++ config.system.fsPackages; 597 # Since there is no /etc/systemd/system/systemd-makefs@.service 598 # file, the units generated in /run/systemd/generator would 599 # override anything we put here. But by forcing the use of a 600 # drop-in in /etc, it does apply. 601 overrideStrategy = "asDropin"; 602 }; 603 systemd.services."systemd-mkswap@" = { 604 restartIfChanged = false; 605 path = [ pkgs.util-linux ]; 606 overrideStrategy = "asDropin"; 607 }; 608 systemd.services.systemd-random-seed.restartIfChanged = false; 609 systemd.services.systemd-remount-fs.restartIfChanged = false; 610 systemd.services.systemd-update-utmp.restartIfChanged = false; 611 systemd.services.systemd-udev-settle.restartIfChanged = false; # Causes long delays in nixos-rebuild 612 systemd.targets.local-fs.unitConfig.X-StopOnReconfiguration = true; 613 systemd.targets.remote-fs.unitConfig.X-StopOnReconfiguration = true; 614 systemd.targets.network-online.wantedBy = [ "multi-user.target" ]; 615 systemd.services.systemd-importd.environment = proxy_env; 616 systemd.services.systemd-pstore.wantedBy = [ "sysinit.target" ]; # see #81138 617 618 # NixOS has kernel modules in a different location, so override that here. 619 systemd.services.kmod-static-nodes.unitConfig.ConditionFileNotEmpty = [ 620 "" # required to unset the previous value! 621 "/run/booted-system/kernel-modules/lib/modules/%v/modules.devname" 622 ]; 623 624 # Don't bother with certain units in containers. 625 systemd.services.systemd-remount-fs.unitConfig.ConditionVirtualization = "!container"; 626 systemd.services.systemd-random-seed.unitConfig.ConditionVirtualization = "!container"; 627 628 # Increase numeric PID range (set directly instead of copying a one-line file from systemd) 629 # https://github.com/systemd/systemd/pull/12226 630 boot.kernel.sysctl."kernel.pid_max" = mkIf pkgs.stdenv.is64bit (lib.mkDefault 4194304); 631 632 boot.kernelParams = optional (!cfg.enableUnifiedCgroupHierarchy) "systemd.unified_cgroup_hierarchy=0"; 633 634 # Avoid potentially degraded system state due to 635 # "Userspace Out-Of-Memory (OOM) Killer was skipped because of a failed condition check (ConditionControlGroupController=v2)." 636 systemd.oomd.enable = mkIf (!cfg.enableUnifiedCgroupHierarchy) false; 637 638 services.logrotate.settings = { 639 "/var/log/btmp" = mapAttrs (_: mkDefault) { 640 frequency = "monthly"; 641 rotate = 1; 642 create = "0660 root ${config.users.groups.utmp.name}"; 643 minsize = "1M"; 644 }; 645 "/var/log/wtmp" = mapAttrs (_: mkDefault) { 646 frequency = "monthly"; 647 rotate = 1; 648 create = "0664 root ${config.users.groups.utmp.name}"; 649 minsize = "1M"; 650 }; 651 }; 652 }; 653 654 # FIXME: Remove these eventually. 655 imports = 656 [ (mkRenamedOptionModule [ "boot" "systemd" "sockets" ] [ "systemd" "sockets" ]) 657 (mkRenamedOptionModule [ "boot" "systemd" "targets" ] [ "systemd" "targets" ]) 658 (mkRenamedOptionModule [ "boot" "systemd" "services" ] [ "systemd" "services" ]) 659 (mkRenamedOptionModule [ "jobs" ] [ "systemd" "services" ]) 660 (mkRemovedOptionModule [ "systemd" "generator-packages" ] "Use systemd.packages instead.") 661 ]; 662}