Merge remote-tracking branch 'upstream/staging-next' into staging
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
utils,
|
||||
...
|
||||
}:
|
||||
|
||||
with utils;
|
||||
with systemdUtils.unitOptions;
|
||||
@@ -17,10 +23,12 @@ let
|
||||
pathToUnit
|
||||
mountToUnit
|
||||
automountToUnit
|
||||
sliceToUnit;
|
||||
sliceToUnit
|
||||
;
|
||||
|
||||
upstreamSystemUnits =
|
||||
[ # Targets.
|
||||
[
|
||||
# Targets.
|
||||
"basic.target"
|
||||
"sysinit.target"
|
||||
"sockets.target"
|
||||
@@ -34,11 +42,13 @@ let
|
||||
"nss-user-lookup.target"
|
||||
"time-sync.target"
|
||||
"first-boot-complete.target"
|
||||
] ++ optionals cfg.package.withCryptsetup [
|
||||
]
|
||||
++ optionals cfg.package.withCryptsetup [
|
||||
"cryptsetup.target"
|
||||
"cryptsetup-pre.target"
|
||||
"remote-cryptsetup.target"
|
||||
] ++ [
|
||||
]
|
||||
++ [
|
||||
"sigpwr.target"
|
||||
"timers.target"
|
||||
"paths.target"
|
||||
@@ -56,7 +66,9 @@ let
|
||||
"systemd-udevd-kernel.socket"
|
||||
"systemd-udevd.service"
|
||||
"systemd-udev-settle.service"
|
||||
] ++ (optional (!config.boot.isContainer) "systemd-udev-trigger.service") ++ [
|
||||
]
|
||||
++ (optional (!config.boot.isContainer) "systemd-udev-trigger.service")
|
||||
++ [
|
||||
# hwdb.bin is managed by NixOS
|
||||
# "systemd-hwdb-update.service"
|
||||
|
||||
@@ -86,13 +98,17 @@ let
|
||||
"dev-hugepages.mount"
|
||||
"dev-mqueue.mount"
|
||||
"sys-fs-fuse-connections.mount"
|
||||
] ++ (optional (!config.boot.isContainer) "sys-kernel-config.mount") ++ [
|
||||
]
|
||||
++ (optional (!config.boot.isContainer) "sys-kernel-config.mount")
|
||||
++ [
|
||||
"sys-kernel-debug.mount"
|
||||
"sys-kernel-tracing.mount"
|
||||
|
||||
# Maintaining state across reboots.
|
||||
"systemd-random-seed.service"
|
||||
] ++ (optional cfg.package.withBootloader "systemd-boot-random-seed.service") ++ [
|
||||
]
|
||||
++ (optional cfg.package.withBootloader "systemd-boot-random-seed.service")
|
||||
++ [
|
||||
"systemd-backlight@.service"
|
||||
"systemd-rfkill.service"
|
||||
"systemd-rfkill.socket"
|
||||
@@ -104,7 +120,9 @@ let
|
||||
"sleep.target"
|
||||
"hybrid-sleep.target"
|
||||
"systemd-hibernate.service"
|
||||
] ++ (lib.optional cfg.package.withEfi "systemd-hibernate-clear.service") ++ [
|
||||
]
|
||||
++ (lib.optional cfg.package.withEfi "systemd-hibernate-clear.service")
|
||||
++ [
|
||||
"systemd-hybrid-sleep.service"
|
||||
"systemd-suspend.service"
|
||||
"systemd-suspend-then-hibernate.service"
|
||||
@@ -121,7 +139,9 @@ let
|
||||
"final.target"
|
||||
"kexec.target"
|
||||
"systemd-kexec.service"
|
||||
] ++ lib.optional cfg.package.withUtmp "systemd-update-utmp.service" ++ [
|
||||
]
|
||||
++ lib.optional cfg.package.withUtmp "systemd-update-utmp.service"
|
||||
++ [
|
||||
|
||||
# Password entry.
|
||||
"systemd-ask-password-console.path"
|
||||
@@ -130,56 +150,69 @@ let
|
||||
"systemd-ask-password-wall.service"
|
||||
|
||||
# Varlink APIs
|
||||
] ++ lib.optionals cfg.package.withBootloader [
|
||||
]
|
||||
++ lib.optionals cfg.package.withBootloader [
|
||||
"systemd-bootctl@.service"
|
||||
"systemd-bootctl.socket"
|
||||
] ++ [
|
||||
]
|
||||
++ [
|
||||
"systemd-creds@.service"
|
||||
"systemd-creds.socket"
|
||||
] ++ lib.optional cfg.package.withTpm2Units [
|
||||
]
|
||||
++ lib.optional cfg.package.withTpm2Units [
|
||||
"systemd-pcrlock@.service"
|
||||
"systemd-pcrlock.socket"
|
||||
] ++ [
|
||||
]
|
||||
++ [
|
||||
|
||||
# Slices / containers.
|
||||
"slices.target"
|
||||
] ++ optionals cfg.package.withImportd [
|
||||
]
|
||||
++ optionals cfg.package.withImportd [
|
||||
"systemd-importd.service"
|
||||
] ++ optionals cfg.package.withMachined [
|
||||
]
|
||||
++ optionals cfg.package.withMachined [
|
||||
"machine.slice"
|
||||
"machines.target"
|
||||
"systemd-machined.service"
|
||||
] ++ [
|
||||
]
|
||||
++ [
|
||||
"systemd-nspawn@.service"
|
||||
|
||||
# Misc.
|
||||
"systemd-sysctl.service"
|
||||
"systemd-machine-id-commit.service"
|
||||
] ++ optionals cfg.package.withTimedated [
|
||||
]
|
||||
++ optionals cfg.package.withTimedated [
|
||||
"dbus-org.freedesktop.timedate1.service"
|
||||
"systemd-timedated.service"
|
||||
] ++ optionals cfg.package.withLocaled [
|
||||
]
|
||||
++ optionals cfg.package.withLocaled [
|
||||
"dbus-org.freedesktop.locale1.service"
|
||||
"systemd-localed.service"
|
||||
] ++ optionals cfg.package.withHostnamed [
|
||||
]
|
||||
++ optionals cfg.package.withHostnamed [
|
||||
"dbus-org.freedesktop.hostname1.service"
|
||||
"systemd-hostnamed.service"
|
||||
"systemd-hostnamed.socket"
|
||||
] ++ optionals cfg.package.withPortabled [
|
||||
]
|
||||
++ optionals cfg.package.withPortabled [
|
||||
"dbus-org.freedesktop.portable1.service"
|
||||
"systemd-portabled.service"
|
||||
] ++ [
|
||||
]
|
||||
++ [
|
||||
"systemd-exit.service"
|
||||
"systemd-update-done.service"
|
||||
] ++ cfg.additionalUpstreamSystemUnits;
|
||||
]
|
||||
++ cfg.additionalUpstreamSystemUnits;
|
||||
|
||||
upstreamSystemWants =
|
||||
[ "sysinit.target.wants"
|
||||
"sockets.target.wants"
|
||||
"local-fs.target.wants"
|
||||
"multi-user.target.wants"
|
||||
"timers.target.wants"
|
||||
];
|
||||
upstreamSystemWants = [
|
||||
"sysinit.target.wants"
|
||||
"sockets.target.wants"
|
||||
"local-fs.target.wants"
|
||||
"multi-user.target.wants"
|
||||
"timers.target.wants"
|
||||
];
|
||||
|
||||
proxy_env = config.networking.proxy.envVars;
|
||||
|
||||
@@ -190,55 +223,57 @@ in
|
||||
|
||||
options.systemd = {
|
||||
|
||||
package = mkPackageOption pkgs "systemd" {};
|
||||
package = mkPackageOption pkgs "systemd" { };
|
||||
|
||||
enableStrictShellChecks = mkEnableOption "" // { description = "Whether to run shellcheck on the generated scripts for systemd units."; };
|
||||
enableStrictShellChecks = mkEnableOption "" // {
|
||||
description = "Whether to run shellcheck on the generated scripts for systemd units.";
|
||||
};
|
||||
|
||||
units = mkOption {
|
||||
description = "Definition of systemd units; see {manpage}`systemd.unit(5)`.";
|
||||
default = {};
|
||||
default = { };
|
||||
type = systemdUtils.types.units;
|
||||
};
|
||||
|
||||
packages = mkOption {
|
||||
default = [];
|
||||
default = [ ];
|
||||
type = types.listOf types.package;
|
||||
example = literalExpression "[ pkgs.systemd-cryptsetup-generator ]";
|
||||
description = "Packages providing systemd units and hooks.";
|
||||
};
|
||||
|
||||
targets = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = systemdUtils.types.targets;
|
||||
description = "Definition of systemd target units; see {manpage}`systemd.target(5)`";
|
||||
};
|
||||
|
||||
services = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = systemdUtils.types.services;
|
||||
description = "Definition of systemd service units; see {manpage}`systemd.service(5)`.";
|
||||
};
|
||||
|
||||
sockets = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = systemdUtils.types.sockets;
|
||||
description = "Definition of systemd socket units; see {manpage}`systemd.socket(5)`.";
|
||||
};
|
||||
|
||||
timers = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = systemdUtils.types.timers;
|
||||
description = "Definition of systemd timer units; see {manpage}`systemd.timer(5)`.";
|
||||
};
|
||||
|
||||
paths = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = systemdUtils.types.paths;
|
||||
description = "Definition of systemd path units; see {manpage}`systemd.path(5)`.";
|
||||
};
|
||||
|
||||
mounts = mkOption {
|
||||
default = [];
|
||||
default = [ ];
|
||||
type = systemdUtils.types.mounts;
|
||||
description = ''
|
||||
Definition of systemd mount units; see {manpage}`systemd.mount(5)`.
|
||||
@@ -249,7 +284,7 @@ in
|
||||
};
|
||||
|
||||
automounts = mkOption {
|
||||
default = [];
|
||||
default = [ ];
|
||||
type = systemdUtils.types.automounts;
|
||||
description = ''
|
||||
Definition of systemd automount units; see {manpage}`systemd.automount(5)`.
|
||||
@@ -260,15 +295,17 @@ in
|
||||
};
|
||||
|
||||
slices = mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = systemdUtils.types.slices;
|
||||
description = "Definition of slice configurations; see {manpage}`systemd.slice(5)`.";
|
||||
};
|
||||
|
||||
generators = mkOption {
|
||||
type = types.attrsOf types.path;
|
||||
default = {};
|
||||
example = { systemd-gpt-auto-generator = "/dev/null"; };
|
||||
default = { };
|
||||
example = {
|
||||
systemd-gpt-auto-generator = "/dev/null";
|
||||
};
|
||||
description = ''
|
||||
Definition of systemd generators; see {manpage}`systemd.generator(5)`.
|
||||
|
||||
@@ -279,7 +316,7 @@ in
|
||||
|
||||
shutdown = mkOption {
|
||||
type = types.attrsOf types.path;
|
||||
default = {};
|
||||
default = { };
|
||||
description = ''
|
||||
Definition of systemd shutdown executables.
|
||||
For each `NAME = VALUE` pair of the attrSet, a link is generated from
|
||||
@@ -306,18 +343,38 @@ in
|
||||
};
|
||||
|
||||
globalEnvironment = mkOption {
|
||||
type = with types; attrsOf (nullOr (oneOf [ str path package ]));
|
||||
default = {};
|
||||
example = { TZ = "CET"; };
|
||||
type =
|
||||
with types;
|
||||
attrsOf (
|
||||
nullOr (oneOf [
|
||||
str
|
||||
path
|
||||
package
|
||||
])
|
||||
);
|
||||
default = { };
|
||||
example = {
|
||||
TZ = "CET";
|
||||
};
|
||||
description = ''
|
||||
Environment variables passed to *all* systemd units.
|
||||
'';
|
||||
};
|
||||
|
||||
managerEnvironment = mkOption {
|
||||
type = with types; attrsOf (nullOr (oneOf [ str path package ]));
|
||||
default = {};
|
||||
example = { SYSTEMD_LOG_LEVEL = "debug"; };
|
||||
type =
|
||||
with types;
|
||||
attrsOf (
|
||||
nullOr (oneOf [
|
||||
str
|
||||
path
|
||||
package
|
||||
])
|
||||
);
|
||||
default = { };
|
||||
example = {
|
||||
SYSTEMD_LOG_LEVEL = "debug";
|
||||
};
|
||||
description = ''
|
||||
Environment variables of PID 1. These variables are
|
||||
*not* passed to started units.
|
||||
@@ -355,7 +412,10 @@ in
|
||||
additionalUpstreamSystemUnits = mkOption {
|
||||
default = [ ];
|
||||
type = types.listOf types.str;
|
||||
example = [ "debug-shell.service" "systemd-quotacheck.service" ];
|
||||
example = [
|
||||
"debug-shell.service"
|
||||
"systemd-quotacheck.service"
|
||||
];
|
||||
description = ''
|
||||
Additional units shipped with systemd that shall be enabled.
|
||||
'';
|
||||
@@ -428,154 +488,184 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = {
|
||||
|
||||
warnings = let
|
||||
mkOneNetOnlineWarn = typeStr: name: def: lib.optional
|
||||
(lib.elem "network-online.target" def.after && !(lib.elem "network-online.target" (def.wants ++ def.requires ++ def.bindsTo)))
|
||||
"${name}.${typeStr} is ordered after 'network-online.target' but doesn't depend on it";
|
||||
mkNetOnlineWarns = typeStr: defs: lib.concatLists (lib.mapAttrsToList (mkOneNetOnlineWarn typeStr) defs);
|
||||
mkMountNetOnlineWarns = typeStr: defs: lib.concatLists (map (m: mkOneNetOnlineWarn typeStr m.what m) defs);
|
||||
in concatLists (
|
||||
mapAttrsToList
|
||||
(name: service:
|
||||
warnings =
|
||||
let
|
||||
mkOneNetOnlineWarn =
|
||||
typeStr: name: def:
|
||||
lib.optional (
|
||||
lib.elem "network-online.target" def.after
|
||||
&& !(lib.elem "network-online.target" (def.wants ++ def.requires ++ def.bindsTo))
|
||||
) "${name}.${typeStr} is ordered after 'network-online.target' but doesn't depend on it";
|
||||
mkNetOnlineWarns =
|
||||
typeStr: defs: lib.concatLists (lib.mapAttrsToList (mkOneNetOnlineWarn typeStr) defs);
|
||||
mkMountNetOnlineWarns =
|
||||
typeStr: defs: lib.concatLists (map (m: mkOneNetOnlineWarn typeStr m.what m) defs);
|
||||
in
|
||||
concatLists (
|
||||
mapAttrsToList (
|
||||
name: service:
|
||||
let
|
||||
type = service.serviceConfig.Type or "";
|
||||
restart = service.serviceConfig.Restart or "no";
|
||||
hasDeprecated = builtins.hasAttr "StartLimitInterval" service.serviceConfig;
|
||||
in
|
||||
concatLists [
|
||||
(optional (type == "oneshot" && (restart == "always" || restart == "on-success"))
|
||||
"Service '${name}.service' with 'Type=oneshot' cannot have 'Restart=always' or 'Restart=on-success'"
|
||||
)
|
||||
(optional hasDeprecated
|
||||
"Service '${name}.service' uses the attribute 'StartLimitInterval' in the Service section, which is deprecated. See https://github.com/NixOS/nixpkgs/issues/45786."
|
||||
)
|
||||
(optional (service.reloadIfChanged && service.reloadTriggers != [])
|
||||
"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."
|
||||
)
|
||||
]
|
||||
)
|
||||
cfg.services
|
||||
)
|
||||
++ (mkNetOnlineWarns "target" cfg.targets)
|
||||
++ (mkNetOnlineWarns "service" cfg.services)
|
||||
++ (mkNetOnlineWarns "socket" cfg.sockets)
|
||||
++ (mkNetOnlineWarns "timer" cfg.timers)
|
||||
++ (mkNetOnlineWarns "path" cfg.paths)
|
||||
++ (mkMountNetOnlineWarns "mount" cfg.mounts)
|
||||
++ (mkMountNetOnlineWarns "automount" cfg.automounts)
|
||||
++ (mkNetOnlineWarns "slice" cfg.slices);
|
||||
concatLists [
|
||||
(optional (type == "oneshot" && (restart == "always" || restart == "on-success"))
|
||||
"Service '${name}.service' with 'Type=oneshot' cannot have 'Restart=always' or 'Restart=on-success'"
|
||||
)
|
||||
(optional hasDeprecated "Service '${name}.service' uses the attribute 'StartLimitInterval' in the Service section, which is deprecated. See https://github.com/NixOS/nixpkgs/issues/45786.")
|
||||
(optional (service.reloadIfChanged && service.reloadTriggers != [ ])
|
||||
"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."
|
||||
)
|
||||
]
|
||||
) cfg.services
|
||||
)
|
||||
++ (mkNetOnlineWarns "target" cfg.targets)
|
||||
++ (mkNetOnlineWarns "service" cfg.services)
|
||||
++ (mkNetOnlineWarns "socket" cfg.sockets)
|
||||
++ (mkNetOnlineWarns "timer" cfg.timers)
|
||||
++ (mkNetOnlineWarns "path" cfg.paths)
|
||||
++ (mkMountNetOnlineWarns "mount" cfg.mounts)
|
||||
++ (mkMountNetOnlineWarns "automount" cfg.automounts)
|
||||
++ (mkNetOnlineWarns "slice" cfg.slices);
|
||||
|
||||
assertions = concatLists (
|
||||
mapAttrsToList
|
||||
(name: service:
|
||||
map (message: {
|
||||
mapAttrsToList (
|
||||
name: service:
|
||||
map
|
||||
(message: {
|
||||
assertion = false;
|
||||
inherit message;
|
||||
}) (concatLists [
|
||||
(optional ((builtins.elem "network-interfaces.target" service.after) || (builtins.elem "network-interfaces.target" service.wants))
|
||||
})
|
||||
(concatLists [
|
||||
(optional
|
||||
(
|
||||
(builtins.elem "network-interfaces.target" service.after)
|
||||
|| (builtins.elem "network-interfaces.target" service.wants)
|
||||
)
|
||||
"Service '${name}.service' is using the deprecated target network-interfaces.target, which no longer exists. Using network.target is recommended instead."
|
||||
)
|
||||
])
|
||||
)
|
||||
cfg.services
|
||||
) cfg.services
|
||||
);
|
||||
|
||||
system.build.units = cfg.units;
|
||||
|
||||
system.nssModules = [ cfg.package.out ];
|
||||
system.nssDatabases = {
|
||||
hosts = (mkMerge [
|
||||
(mkOrder 400 ["mymachines"]) # 400 to ensure it comes before resolve (which is 501)
|
||||
(mkOrder 999 ["myhostname"]) # after files (which is 998), but before regular nss modules
|
||||
]);
|
||||
passwd = (mkMerge [
|
||||
(mkAfter [ "systemd" ])
|
||||
]);
|
||||
group = (mkMerge [
|
||||
(mkAfter [ "[success=merge] systemd" ]) # need merge so that NSS won't stop at file-based groups
|
||||
]);
|
||||
hosts = (
|
||||
mkMerge [
|
||||
(mkOrder 400 [ "mymachines" ]) # 400 to ensure it comes before resolve (which is 501)
|
||||
(mkOrder 999 [ "myhostname" ]) # after files (which is 998), but before regular nss modules
|
||||
]
|
||||
);
|
||||
passwd = (
|
||||
mkMerge [
|
||||
(mkAfter [ "systemd" ])
|
||||
]
|
||||
);
|
||||
group = (
|
||||
mkMerge [
|
||||
(mkAfter [ "[success=merge] systemd" ]) # need merge so that NSS won't stop at file-based groups
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
environment.etc = let
|
||||
# generate contents for /etc/systemd/${dir} from attrset of links and packages
|
||||
hooks = dir: links: pkgs.runCommand "${dir}" {
|
||||
preferLocalBuild = true;
|
||||
packages = cfg.packages;
|
||||
} ''
|
||||
set -e
|
||||
mkdir -p $out
|
||||
for package in $packages
|
||||
do
|
||||
for hook in $package/lib/systemd/${dir}/*
|
||||
do
|
||||
ln -s $hook $out/
|
||||
done
|
||||
done
|
||||
${concatStrings (mapAttrsToList (exec: target: "ln -s ${target} $out/${exec};\n") links)}
|
||||
'';
|
||||
environment.etc =
|
||||
let
|
||||
# generate contents for /etc/systemd/${dir} from attrset of links and packages
|
||||
hooks =
|
||||
dir: links:
|
||||
pkgs.runCommand "${dir}"
|
||||
{
|
||||
preferLocalBuild = true;
|
||||
packages = cfg.packages;
|
||||
}
|
||||
''
|
||||
set -e
|
||||
mkdir -p $out
|
||||
for package in $packages
|
||||
do
|
||||
for hook in $package/lib/systemd/${dir}/*
|
||||
do
|
||||
ln -s $hook $out/
|
||||
done
|
||||
done
|
||||
${concatStrings (mapAttrsToList (exec: target: "ln -s ${target} $out/${exec};\n") links)}
|
||||
'';
|
||||
|
||||
enabledUpstreamSystemUnits = filter (n: ! elem n cfg.suppressedSystemUnits) upstreamSystemUnits;
|
||||
enabledUnits = filterAttrs (n: v: ! elem n cfg.suppressedSystemUnits) cfg.units;
|
||||
enabledUpstreamSystemUnits = filter (n: !elem n cfg.suppressedSystemUnits) upstreamSystemUnits;
|
||||
enabledUnits = filterAttrs (n: v: !elem n cfg.suppressedSystemUnits) cfg.units;
|
||||
|
||||
in ({
|
||||
"systemd/system".source = generateUnits {
|
||||
type = "system";
|
||||
units = enabledUnits;
|
||||
upstreamUnits = enabledUpstreamSystemUnits;
|
||||
upstreamWants = upstreamSystemWants;
|
||||
};
|
||||
in
|
||||
({
|
||||
"systemd/system".source = generateUnits {
|
||||
type = "system";
|
||||
units = enabledUnits;
|
||||
upstreamUnits = enabledUpstreamSystemUnits;
|
||||
upstreamWants = upstreamSystemWants;
|
||||
};
|
||||
|
||||
"systemd/system.conf".text = ''
|
||||
[Manager]
|
||||
ManagerEnvironment=${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "${n}=${lib.escapeShellArg v}") cfg.managerEnvironment)}
|
||||
${optionalString cfg.enableCgroupAccounting ''
|
||||
DefaultCPUAccounting=yes
|
||||
DefaultIOAccounting=yes
|
||||
DefaultBlockIOAccounting=yes
|
||||
DefaultIPAccounting=yes
|
||||
''}
|
||||
DefaultLimitCORE=infinity
|
||||
${optionalString (cfg.watchdog.device != null) ''
|
||||
WatchdogDevice=${cfg.watchdog.device}
|
||||
''}
|
||||
${optionalString (cfg.watchdog.runtimeTime != null) ''
|
||||
RuntimeWatchdogSec=${cfg.watchdog.runtimeTime}
|
||||
''}
|
||||
${optionalString (cfg.watchdog.rebootTime != null) ''
|
||||
RebootWatchdogSec=${cfg.watchdog.rebootTime}
|
||||
''}
|
||||
${optionalString (cfg.watchdog.kexecTime != null) ''
|
||||
KExecWatchdogSec=${cfg.watchdog.kexecTime}
|
||||
''}
|
||||
"systemd/system.conf".text = ''
|
||||
[Manager]
|
||||
ManagerEnvironment=${
|
||||
lib.concatStringsSep " " (
|
||||
lib.mapAttrsToList (n: v: "${n}=${lib.escapeShellArg v}") cfg.managerEnvironment
|
||||
)
|
||||
}
|
||||
${optionalString cfg.enableCgroupAccounting ''
|
||||
DefaultCPUAccounting=yes
|
||||
DefaultIOAccounting=yes
|
||||
DefaultBlockIOAccounting=yes
|
||||
DefaultIPAccounting=yes
|
||||
''}
|
||||
DefaultLimitCORE=infinity
|
||||
${optionalString (cfg.watchdog.device != null) ''
|
||||
WatchdogDevice=${cfg.watchdog.device}
|
||||
''}
|
||||
${optionalString (cfg.watchdog.runtimeTime != null) ''
|
||||
RuntimeWatchdogSec=${cfg.watchdog.runtimeTime}
|
||||
''}
|
||||
${optionalString (cfg.watchdog.rebootTime != null) ''
|
||||
RebootWatchdogSec=${cfg.watchdog.rebootTime}
|
||||
''}
|
||||
${optionalString (cfg.watchdog.kexecTime != null) ''
|
||||
KExecWatchdogSec=${cfg.watchdog.kexecTime}
|
||||
''}
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
"systemd/sleep.conf".text = ''
|
||||
[Sleep]
|
||||
${cfg.sleep.extraConfig}
|
||||
'';
|
||||
"systemd/sleep.conf".text = ''
|
||||
[Sleep]
|
||||
${cfg.sleep.extraConfig}
|
||||
'';
|
||||
|
||||
"systemd/user-generators" = { source = hooks "user-generators" cfg.user.generators; };
|
||||
"systemd/system-generators" = { source = hooks "system-generators" cfg.generators; };
|
||||
"systemd/system-shutdown" = { source = hooks "system-shutdown" cfg.shutdown; };
|
||||
"systemd/user-generators" = {
|
||||
source = hooks "user-generators" cfg.user.generators;
|
||||
};
|
||||
"systemd/system-generators" = {
|
||||
source = hooks "system-generators" cfg.generators;
|
||||
};
|
||||
"systemd/system-shutdown" = {
|
||||
source = hooks "system-shutdown" cfg.shutdown;
|
||||
};
|
||||
|
||||
# Ignore all other preset files so systemd doesn't try to enable/disable
|
||||
# units during runtime.
|
||||
"systemd/system-preset/00-nixos.preset".text = ''
|
||||
ignore *
|
||||
'';
|
||||
"systemd/user-preset/00-nixos.preset".text = ''
|
||||
ignore *
|
||||
'';
|
||||
});
|
||||
# Ignore all other preset files so systemd doesn't try to enable/disable
|
||||
# units during runtime.
|
||||
"systemd/system-preset/00-nixos.preset".text = ''
|
||||
ignore *
|
||||
'';
|
||||
"systemd/user-preset/00-nixos.preset".text = ''
|
||||
ignore *
|
||||
'';
|
||||
});
|
||||
|
||||
services.dbus.enable = true;
|
||||
|
||||
@@ -593,10 +683,10 @@ in
|
||||
# Target for ‘charon send-keys’ to hook into.
|
||||
users.groups.keys.gid = config.ids.gids.keys;
|
||||
|
||||
systemd.targets.keys =
|
||||
{ description = "Security Keys";
|
||||
unitConfig.X-StopOnReconfiguration = true;
|
||||
};
|
||||
systemd.targets.keys = {
|
||||
description = "Security Keys";
|
||||
unitConfig.X-StopOnReconfiguration = true;
|
||||
};
|
||||
|
||||
# This target only exists so that services ordered before sysinit.target
|
||||
# are restarted in the correct order, notably BEFORE the other services,
|
||||
@@ -609,7 +699,7 @@ in
|
||||
let
|
||||
withName = cfgToUnit: cfg: lib.nameValuePair cfg.name (cfgToUnit cfg);
|
||||
in
|
||||
mapAttrs' (_: withName pathToUnit) cfg.paths
|
||||
mapAttrs' (_: withName pathToUnit) cfg.paths
|
||||
// mapAttrs' (_: withName serviceToUnit) cfg.services
|
||||
// mapAttrs' (_: withName sliceToUnit) cfg.slices
|
||||
// mapAttrs' (_: withName socketToUnit) cfg.sockets
|
||||
@@ -618,37 +708,50 @@ in
|
||||
// listToAttrs (map (withName mountToUnit) cfg.mounts)
|
||||
// listToAttrs (map (withName automountToUnit) cfg.automounts);
|
||||
|
||||
# Environment of PID 1
|
||||
systemd.managerEnvironment = {
|
||||
# Doesn't contain systemd itself - everything works so it seems to use the compiled-in value for its tools
|
||||
# util-linux is needed for the main fsck utility wrapping the fs-specific ones
|
||||
PATH = lib.makeBinPath (
|
||||
config.system.fsPackages
|
||||
++ [cfg.package.util-linux]
|
||||
# systemd-ssh-generator needs sshd in PATH
|
||||
++ lib.optional config.services.openssh.enable config.services.openssh.package
|
||||
);
|
||||
LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
|
||||
TZDIR = "/etc/zoneinfo";
|
||||
# If SYSTEMD_UNIT_PATH ends with an empty component (":"), the usual unit load path will be appended to the contents of the variable
|
||||
SYSTEMD_UNIT_PATH = lib.mkIf (config.boot.extraSystemdUnitPaths != []) "${builtins.concatStringsSep ":" config.boot.extraSystemdUnitPaths}:";
|
||||
};
|
||||
# Environment of PID 1
|
||||
systemd.managerEnvironment = {
|
||||
# Doesn't contain systemd itself - everything works so it seems to use the compiled-in value for its tools
|
||||
# util-linux is needed for the main fsck utility wrapping the fs-specific ones
|
||||
PATH = lib.makeBinPath (
|
||||
config.system.fsPackages
|
||||
++ [ cfg.package.util-linux ]
|
||||
# systemd-ssh-generator needs sshd in PATH
|
||||
++ lib.optional config.services.openssh.enable config.services.openssh.package
|
||||
);
|
||||
LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
|
||||
TZDIR = "/etc/zoneinfo";
|
||||
# If SYSTEMD_UNIT_PATH ends with an empty component (":"), the usual unit load path will be appended to the contents of the variable
|
||||
SYSTEMD_UNIT_PATH = lib.mkIf (
|
||||
config.boot.extraSystemdUnitPaths != [ ]
|
||||
) "${builtins.concatStringsSep ":" config.boot.extraSystemdUnitPaths}:";
|
||||
};
|
||||
|
||||
|
||||
system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled
|
||||
[ "DEVTMPFS" "CGROUPS" "INOTIFY_USER" "SIGNALFD" "TIMERFD" "EPOLL" "NET"
|
||||
"SYSFS" "PROC_FS" "FHANDLE" "CRYPTO_USER_API_HASH" "CRYPTO_HMAC"
|
||||
"CRYPTO_SHA256" "DMIID" "AUTOFS_FS" "TMPFS_POSIX_ACL"
|
||||
"TMPFS_XATTR" "SECCOMP"
|
||||
];
|
||||
system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled [
|
||||
"DEVTMPFS"
|
||||
"CGROUPS"
|
||||
"INOTIFY_USER"
|
||||
"SIGNALFD"
|
||||
"TIMERFD"
|
||||
"EPOLL"
|
||||
"NET"
|
||||
"SYSFS"
|
||||
"PROC_FS"
|
||||
"FHANDLE"
|
||||
"CRYPTO_USER_API_HASH"
|
||||
"CRYPTO_HMAC"
|
||||
"CRYPTO_SHA256"
|
||||
"DMIID"
|
||||
"AUTOFS_FS"
|
||||
"TMPFS_POSIX_ACL"
|
||||
"TMPFS_XATTR"
|
||||
"SECCOMP"
|
||||
];
|
||||
|
||||
# Generate timer units for all services that have a ‘startAt’ value.
|
||||
systemd.timers =
|
||||
mapAttrs (name: service:
|
||||
{ wantedBy = [ "timers.target" ];
|
||||
timerConfig.OnCalendar = service.startAt;
|
||||
})
|
||||
(filterAttrs (name: service: service.enable && service.startAt != []) cfg.services);
|
||||
systemd.timers = mapAttrs (name: service: {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig.OnCalendar = service.startAt;
|
||||
}) (filterAttrs (name: service: service.enable && service.startAt != [ ]) cfg.services);
|
||||
|
||||
# Some overrides to upstream units.
|
||||
systemd.services."systemd-backlight@".restartIfChanged = false;
|
||||
@@ -679,7 +782,7 @@ in
|
||||
|
||||
# NixOS has kernel modules in a different location, so override that here.
|
||||
systemd.services.kmod-static-nodes.unitConfig.ConditionFileNotEmpty = [
|
||||
"" # required to unset the previous value!
|
||||
"" # required to unset the previous value!
|
||||
"/run/booted-system/kernel-modules/lib/modules/%v/modules.devname"
|
||||
];
|
||||
|
||||
@@ -707,16 +810,16 @@ in
|
||||
};
|
||||
|
||||
# FIXME: Remove these eventually.
|
||||
imports =
|
||||
[ (mkRenamedOptionModule [ "boot" "systemd" "sockets" ] [ "systemd" "sockets" ])
|
||||
(mkRenamedOptionModule [ "boot" "systemd" "targets" ] [ "systemd" "targets" ])
|
||||
(mkRenamedOptionModule [ "boot" "systemd" "services" ] [ "systemd" "services" ])
|
||||
(mkRenamedOptionModule [ "jobs" ] [ "systemd" "services" ])
|
||||
(mkRemovedOptionModule [ "systemd" "generator-packages" ] "Use systemd.packages instead.")
|
||||
(mkRemovedOptionModule ["systemd" "enableUnifiedCgroupHierarchy"] ''
|
||||
In 256 support for cgroup v1 ('legacy' and 'hybrid' hierarchies) is now considered obsolete and systemd by default will refuse to boot under it.
|
||||
To forcibly reenable cgroup v1 support, you can set boot.kernelParams = [ "systemd.unified_cgroup_hierarchy=0" "SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1" ].
|
||||
NixOS does not officially support this configuration and might cause your system to be unbootable in future versions. You are on your own.
|
||||
'')
|
||||
];
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "boot" "systemd" "sockets" ] [ "systemd" "sockets" ])
|
||||
(mkRenamedOptionModule [ "boot" "systemd" "targets" ] [ "systemd" "targets" ])
|
||||
(mkRenamedOptionModule [ "boot" "systemd" "services" ] [ "systemd" "services" ])
|
||||
(mkRenamedOptionModule [ "jobs" ] [ "systemd" "services" ])
|
||||
(mkRemovedOptionModule [ "systemd" "generator-packages" ] "Use systemd.packages instead.")
|
||||
(mkRemovedOptionModule [ "systemd" "enableUnifiedCgroupHierarchy" ] ''
|
||||
In 256 support for cgroup v1 ('legacy' and 'hybrid' hierarchies) is now considered obsolete and systemd by default will refuse to boot under it.
|
||||
To forcibly reenable cgroup v1 support, you can set boot.kernelParams = [ "systemd.unified_cgroup_hierarchy=0" "SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1" ].
|
||||
NixOS does not officially support this configuration and might cause your system to be unbootable in future versions. You are on your own.
|
||||
'')
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user