nixos/systemd: Switch to ManagerEnvironment=
This accomplishes multiple things: - Allows us to start systemd without stage-2-init.sh. This was not possible before because the environment would have been wrong - `systemctl daemon-reexec` also changes the environment, giving us newer tools for the fs packages - Starts systemd in a fully clean environment, making everything more consistent and pure
This commit is contained in:
parent
d56076aa39
commit
a3e0698bf6
|
@ -167,10 +167,6 @@ exec 1>&$logOutFd 2>&$logErrFd
|
||||||
exec {logOutFd}>&- {logErrFd}>&-
|
exec {logOutFd}>&- {logErrFd}>&-
|
||||||
|
|
||||||
|
|
||||||
# Start systemd.
|
# Start systemd in a clean environment.
|
||||||
echo "starting systemd..."
|
echo "starting systemd..."
|
||||||
|
exec env - @systemdExecutable@ "$@"
|
||||||
PATH=/run/current-system/systemd/lib/systemd:@fsPackagesPath@ \
|
|
||||||
LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive @systemdUnitPathEnvVar@ \
|
|
||||||
TZDIR=/etc/zoneinfo \
|
|
||||||
exec @systemdExecutable@
|
|
||||||
|
|
|
@ -19,11 +19,6 @@ let
|
||||||
pkgs.coreutils
|
pkgs.coreutils
|
||||||
pkgs.util-linux
|
pkgs.util-linux
|
||||||
] ++ lib.optional useHostResolvConf pkgs.openresolv);
|
] ++ lib.optional useHostResolvConf pkgs.openresolv);
|
||||||
fsPackagesPath = lib.makeBinPath config.system.fsPackages;
|
|
||||||
systemdUnitPathEnvVar = lib.optionalString (config.boot.extraSystemdUnitPaths != [])
|
|
||||||
("SYSTEMD_UNIT_PATH="
|
|
||||||
+ builtins.concatStringsSep ":" config.boot.extraSystemdUnitPaths
|
|
||||||
+ ":"); # If SYSTEMD_UNIT_PATH ends with an empty component (":"), the usual unit load path will be appended to the contents of the variable
|
|
||||||
postBootCommands = pkgs.writeText "local-cmds"
|
postBootCommands = pkgs.writeText "local-cmds"
|
||||||
''
|
''
|
||||||
${config.boot.postBootCommands}
|
${config.boot.postBootCommands}
|
||||||
|
@ -78,12 +73,10 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
systemdExecutable = mkOption {
|
systemdExecutable = mkOption {
|
||||||
default = "systemd";
|
default = "/run/current-system/systemd/lib/systemd/systemd";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = ''
|
description = ''
|
||||||
The program to execute to start systemd. Typically
|
The program to execute to start systemd.
|
||||||
<literal>systemd</literal>, which will find systemd in the
|
|
||||||
PATH.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -302,6 +302,16 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
systemd.managerEnvironment = mkOption {
|
||||||
|
type = with types; attrsOf (nullOr (oneOf [ str path package ]));
|
||||||
|
default = {};
|
||||||
|
example = { SYSTEMD_LOG_LEVEL = "debug"; };
|
||||||
|
description = ''
|
||||||
|
Environment variables of PID 1. These variables are
|
||||||
|
<emphasis>not</emphasis> passed to started units.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
systemd.enableCgroupAccounting = mkOption {
|
systemd.enableCgroupAccounting = mkOption {
|
||||||
default = true;
|
default = true;
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
|
@ -470,11 +480,13 @@ in
|
||||||
|
|
||||||
enabledUpstreamSystemUnits = filter (n: ! elem n cfg.suppressedSystemUnits) upstreamSystemUnits;
|
enabledUpstreamSystemUnits = filter (n: ! elem n cfg.suppressedSystemUnits) upstreamSystemUnits;
|
||||||
enabledUnits = filterAttrs (n: v: ! elem n cfg.suppressedSystemUnits) cfg.units;
|
enabledUnits = filterAttrs (n: v: ! elem n cfg.suppressedSystemUnits) cfg.units;
|
||||||
|
|
||||||
in ({
|
in ({
|
||||||
"systemd/system".source = generateUnits "system" enabledUnits enabledUpstreamSystemUnits upstreamSystemWants;
|
"systemd/system".source = generateUnits "system" enabledUnits enabledUpstreamSystemUnits upstreamSystemWants;
|
||||||
|
|
||||||
"systemd/system.conf".text = ''
|
"systemd/system.conf".text = ''
|
||||||
[Manager]
|
[Manager]
|
||||||
|
ManagerEnvironment=${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "${n}=${lib.escapeShellArg v}") cfg.managerEnvironment)}
|
||||||
${optionalString config.systemd.enableCgroupAccounting ''
|
${optionalString config.systemd.enableCgroupAccounting ''
|
||||||
DefaultCPUAccounting=yes
|
DefaultCPUAccounting=yes
|
||||||
DefaultIOAccounting=yes
|
DefaultIOAccounting=yes
|
||||||
|
@ -542,6 +554,17 @@ in
|
||||||
(v: let n = escapeSystemdPath v.where;
|
(v: let n = escapeSystemdPath v.where;
|
||||||
in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts);
|
in nameValuePair "${n}.automount" (automountToUnit n v)) 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
|
||||||
|
PATH = lib.makeBinPath config.system.fsPackages;
|
||||||
|
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
|
system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled
|
||||||
[ "DEVTMPFS" "CGROUPS" "INOTIFY_USER" "SIGNALFD" "TIMERFD" "EPOLL" "NET"
|
[ "DEVTMPFS" "CGROUPS" "INOTIFY_USER" "SIGNALFD" "TIMERFD" "EPOLL" "NET"
|
||||||
"SYSFS" "PROC_FS" "FHANDLE" "CRYPTO_USER_API_HASH" "CRYPTO_HMAC"
|
"SYSFS" "PROC_FS" "FHANDLE" "CRYPTO_USER_API_HASH" "CRYPTO_HMAC"
|
||||||
|
|
|
@ -192,5 +192,9 @@ import ./make-test-python.nix ({ pkgs, ... }: {
|
||||||
with subtest("systemd per-unit accounting works"):
|
with subtest("systemd per-unit accounting works"):
|
||||||
assert "IP traffic received: 84B" in output_ping
|
assert "IP traffic received: 84B" in output_ping
|
||||||
assert "IP traffic sent: 84B" in output_ping
|
assert "IP traffic sent: 84B" in output_ping
|
||||||
|
|
||||||
|
with subtest("systemd environment is properly set"):
|
||||||
|
machine.systemctl("daemon-reexec") # Rewrites /proc/1/environ
|
||||||
|
machine.succeed("grep -q TZDIR=/etc/zoneinfo /proc/1/environ")
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue