mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-22 15:03:28 +00:00
nixos/switch-to-configuration: add sysinit-reactivation.target
This commit is contained in:
parent
8bc3b617dd
commit
e6b66f08a5
@ -37,7 +37,7 @@ of actions is always the same:
|
|||||||
- Forget about the failed state of units (`systemctl reset-failed`)
|
- Forget about the failed state of units (`systemctl reset-failed`)
|
||||||
- Reload systemd (`systemctl daemon-reload`)
|
- Reload systemd (`systemctl daemon-reload`)
|
||||||
- Reload systemd user instances (`systemctl --user daemon-reload`)
|
- Reload systemd user instances (`systemctl --user daemon-reload`)
|
||||||
- Set up tmpfiles (`systemd-tmpfiles --create`)
|
- Reactivate sysinit (`systemctl restart sysinit-reactivation.target`)
|
||||||
- Reload units (`systemctl reload`)
|
- Reload units (`systemctl reload`)
|
||||||
- Restart units (`systemctl restart`)
|
- Restart units (`systemctl restart`)
|
||||||
- Start units (`systemctl start`)
|
- Start units (`systemctl start`)
|
||||||
|
@ -889,9 +889,15 @@ while (my $f = <$list_active_users>) {
|
|||||||
|
|
||||||
close($list_active_users) || die("Unable to close the file handle to loginctl");
|
close($list_active_users) || die("Unable to close the file handle to loginctl");
|
||||||
|
|
||||||
# Set the new tmpfiles
|
# Restart sysinit-reactivation.target.
|
||||||
print STDERR "setting up tmpfiles\n";
|
# This target only exists to restart services ordered before sysinit.target. We
|
||||||
system("$new_systemd/bin/systemd-tmpfiles", "--create", "--remove", "--exclude-prefix=/dev") == 0 or $res = 3;
|
# cannot use X-StopOnReconfiguration to restart sysinit.target because then ALL
|
||||||
|
# services of the system would be restarted since all normal services have a
|
||||||
|
# default dependency on sysinit.target. sysinit-reactivation.target ensures
|
||||||
|
# that services ordered BEFORE sysinit.target get re-started in the correct
|
||||||
|
# order. Ordering between these services is respected.
|
||||||
|
print STDERR "restarting sysinit-reactivation.target\n";
|
||||||
|
system("$new_systemd/bin/systemctl", "restart", "sysinit-reactivation.target") == 0 or $res = 4;
|
||||||
|
|
||||||
# Before reloading we need to ensure that the units are still active. They may have been
|
# Before reloading we need to ensure that the units are still active. They may have been
|
||||||
# deactivated because one of their requirements got stopped. If they are inactive
|
# deactivated because one of their requirements got stopped. If they are inactive
|
||||||
|
@ -569,6 +569,13 @@ in
|
|||||||
unitConfig.X-StopOnReconfiguration = true;
|
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,
|
||||||
|
# when switching configurations.
|
||||||
|
systemd.targets.sysinit-reactivation = {
|
||||||
|
description = "Reactivate sysinit units";
|
||||||
|
};
|
||||||
|
|
||||||
systemd.units =
|
systemd.units =
|
||||||
mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths
|
mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths
|
||||||
// mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services
|
// mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services
|
||||||
|
@ -150,6 +150,41 @@ in
|
|||||||
"systemd-tmpfiles-setup.service"
|
"systemd-tmpfiles-setup.service"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# Allow systemd-tmpfiles to be restarted by switch-to-configuration. This
|
||||||
|
# service is not pulled into the normal boot process. It only exists for
|
||||||
|
# switch-to-configuration.
|
||||||
|
#
|
||||||
|
# This needs to be a separate unit because it does not execute
|
||||||
|
# systemd-tmpfiles with `--boot` as that is supposed to only be executed
|
||||||
|
# once at boot time.
|
||||||
|
#
|
||||||
|
# Keep this aligned with the upstream `systemd-tmpfiles-setup.service` unit.
|
||||||
|
systemd.services."systemd-tmpfiles-resetup" = {
|
||||||
|
description = "Re-setup tmpfiles on a system that is already running.";
|
||||||
|
|
||||||
|
requiredBy = [ "sysinit-reactivation.target" ];
|
||||||
|
after = [ "local-fs.target" "systemd-sysusers.service" "systemd-journald.service" ];
|
||||||
|
before = [ "sysinit-reactivation.target" "shutdown.target" ];
|
||||||
|
conflicts = [ "shutdown.target" ];
|
||||||
|
restartTriggers = [ config.environment.etc."tmpfiles.d".source ];
|
||||||
|
|
||||||
|
unitConfig.DefaultDependencies = false;
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStart = "systemd-tmpfiles --create --remove --exclude-prefix=/dev";
|
||||||
|
SuccessExitStatus = "DATAERR CANTCREAT";
|
||||||
|
ImportCredential = [
|
||||||
|
"tmpfiles.*"
|
||||||
|
"loging.motd"
|
||||||
|
"login.issue"
|
||||||
|
"network.hosts"
|
||||||
|
"ssh.authorized_keys.root"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
environment.etc = {
|
environment.etc = {
|
||||||
"tmpfiles.d".source = (pkgs.symlinkJoin {
|
"tmpfiles.d".source = (pkgs.symlinkJoin {
|
||||||
name = "tmpfiles.d";
|
name = "tmpfiles.d";
|
||||||
|
@ -819,6 +819,7 @@ in {
|
|||||||
syncthing-init = handleTest ./syncthing-init.nix {};
|
syncthing-init = handleTest ./syncthing-init.nix {};
|
||||||
syncthing-many-devices = handleTest ./syncthing-many-devices.nix {};
|
syncthing-many-devices = handleTest ./syncthing-many-devices.nix {};
|
||||||
syncthing-relay = handleTest ./syncthing-relay.nix {};
|
syncthing-relay = handleTest ./syncthing-relay.nix {};
|
||||||
|
sysinit-reactivation = runTest ./sysinit-reactivation.nix;
|
||||||
systemd = handleTest ./systemd.nix {};
|
systemd = handleTest ./systemd.nix {};
|
||||||
systemd-analyze = handleTest ./systemd-analyze.nix {};
|
systemd-analyze = handleTest ./systemd-analyze.nix {};
|
||||||
systemd-binfmt = handleTestOn ["x86_64-linux"] ./systemd-binfmt.nix {};
|
systemd-binfmt = handleTestOn ["x86_64-linux"] ./systemd-binfmt.nix {};
|
||||||
|
107
nixos/tests/sysinit-reactivation.nix
Normal file
107
nixos/tests/sysinit-reactivation.nix
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
# This runs to two scenarios but in one tests:
|
||||||
|
# - A post-sysinit service needs to be restarted AFTER tmpfiles was restarted.
|
||||||
|
# - A service needs to be restarted BEFORE tmpfiles is restarted
|
||||||
|
|
||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
makeGeneration = generation: {
|
||||||
|
"${generation}".configuration = {
|
||||||
|
systemd.services.pre-sysinit-before-tmpfiles.environment.USER =
|
||||||
|
lib.mkForce "${generation}-tmpfiles-user";
|
||||||
|
|
||||||
|
systemd.services.pre-sysinit-after-tmpfiles.environment = {
|
||||||
|
NEEDED_PATH = lib.mkForce "/run/${generation}-needed-by-pre-sysinit-after-tmpfiles";
|
||||||
|
PATH_TO_CREATE = lib.mkForce "/run/${generation}-needed-by-post-sysinit";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.post-sysinit.environment = {
|
||||||
|
NEEDED_PATH = lib.mkForce "/run/${generation}-needed-by-post-sysinit";
|
||||||
|
PATH_TO_CREATE = lib.mkForce "/run/${generation}-created-by-post-sysinit";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.settings.test = lib.mkForce {
|
||||||
|
"/run/${generation}-needed-by-pre-sysinit-after-tmpfiles".f.user =
|
||||||
|
"${generation}-tmpfiles-user";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
name = "sysinit-reactivation";
|
||||||
|
|
||||||
|
meta.maintainers = with lib.maintainers; [ nikstur ];
|
||||||
|
|
||||||
|
nodes.machine = { config, lib, pkgs, ... }: {
|
||||||
|
systemd.services.pre-sysinit-before-tmpfiles = {
|
||||||
|
wantedBy = [ "sysinit.target" ];
|
||||||
|
requiredBy = [ "sysinit-reactivation.target" ];
|
||||||
|
before = [ "systemd-tmpfiles-setup.service" "systemd-tmpfiles-resetup.service" ];
|
||||||
|
unitConfig.DefaultDependencies = false;
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
serviceConfig.RemainAfterExit = true;
|
||||||
|
environment.USER = "tmpfiles-user";
|
||||||
|
script = "${pkgs.shadow}/bin/useradd $USER";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.pre-sysinit-after-tmpfiles = {
|
||||||
|
wantedBy = [ "sysinit.target" ];
|
||||||
|
requiredBy = [ "sysinit-reactivation.target" ];
|
||||||
|
after = [ "systemd-tmpfiles-setup.service" "systemd-tmpfiles-resetup.service" ];
|
||||||
|
unitConfig.DefaultDependencies = false;
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
serviceConfig.RemainAfterExit = true;
|
||||||
|
environment = {
|
||||||
|
NEEDED_PATH = "/run/needed-by-pre-sysinit-after-tmpfiles";
|
||||||
|
PATH_TO_CREATE = "/run/needed-by-post-sysinit";
|
||||||
|
};
|
||||||
|
script = ''
|
||||||
|
if [[ -e $NEEDED_PATH ]]; then
|
||||||
|
touch $PATH_TO_CREATE
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.post-sysinit = {
|
||||||
|
wantedBy = [ "default.target" ];
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
serviceConfig.RemainAfterExit = true;
|
||||||
|
environment = {
|
||||||
|
NEEDED_PATH = "/run/needed-by-post-sysinit";
|
||||||
|
PATH_TO_CREATE = "/run/created-by-post-sysinit";
|
||||||
|
};
|
||||||
|
script = ''
|
||||||
|
if [[ -e $NEEDED_PATH ]]; then
|
||||||
|
touch $PATH_TO_CREATE
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.settings.test = {
|
||||||
|
"/run/needed-by-pre-sysinit-after-tmpfiles".f.user =
|
||||||
|
"tmpfiles-user";
|
||||||
|
};
|
||||||
|
|
||||||
|
specialisation = lib.mkMerge [
|
||||||
|
(makeGeneration "second")
|
||||||
|
(makeGeneration "third")
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = { nodes, ... }: ''
|
||||||
|
def switch(generation):
|
||||||
|
toplevel = "${nodes.machine.system.build.toplevel}";
|
||||||
|
machine.succeed(f"{toplevel}/specialisation/{generation}/bin/switch-to-configuration switch")
|
||||||
|
|
||||||
|
machine.wait_for_unit("default.target")
|
||||||
|
machine.succeed("test -e /run/created-by-post-sysinit")
|
||||||
|
|
||||||
|
switch("second")
|
||||||
|
machine.succeed("test -e /run/second-created-by-post-sysinit")
|
||||||
|
|
||||||
|
switch("third")
|
||||||
|
machine.succeed("test -e /run/third-created-by-post-sysinit")
|
||||||
|
'';
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user