Merge pull request #121021 from pennae/container-sigterm
nixos/nix-containers: use SIGTERM to stop containers
This commit is contained in:
commit
44a0debca7
@ -35,6 +35,9 @@ let
|
||||
''
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
|
||||
# Exit early if we're asked to shut down.
|
||||
trap "exit 0" SIGRTMIN+3
|
||||
|
||||
# Initialise the container side of the veth pair.
|
||||
if [ -n "$HOST_ADDRESS" ] || [ -n "$HOST_ADDRESS6" ] ||
|
||||
[ -n "$LOCAL_ADDRESS" ] || [ -n "$LOCAL_ADDRESS6" ] ||
|
||||
@ -60,8 +63,12 @@ let
|
||||
|
||||
${concatStringsSep "\n" (mapAttrsToList renderExtraVeth cfg.extraVeths)}
|
||||
|
||||
# Start the regular stage 1 script.
|
||||
exec "$1"
|
||||
# Start the regular stage 2 script.
|
||||
# We source instead of exec to not lose an early stop signal, which is
|
||||
# also the only _reliable_ shutdown signal we have since early stop
|
||||
# does not execute ExecStop* commands.
|
||||
set +e
|
||||
. "$1"
|
||||
''
|
||||
);
|
||||
|
||||
@ -127,12 +134,16 @@ let
|
||||
''}
|
||||
|
||||
# Run systemd-nspawn without startup notification (we'll
|
||||
# wait for the container systemd to signal readiness).
|
||||
# wait for the container systemd to signal readiness)
|
||||
# Kill signal handling means systemd-nspawn will pass a system-halt signal
|
||||
# to the container systemd when it receives SIGTERM for container shutdown;
|
||||
# containerInit and stage2 have to handle this as well.
|
||||
exec ${config.systemd.package}/bin/systemd-nspawn \
|
||||
--keep-unit \
|
||||
-M "$INSTANCE" -D "$root" $extraFlags \
|
||||
$EXTRA_NSPAWN_FLAGS \
|
||||
--notify-ready=yes \
|
||||
--kill-signal=SIGRTMIN+3 \
|
||||
--bind-ro=/nix/store \
|
||||
--bind-ro=/nix/var/nix/db \
|
||||
--bind-ro=/nix/var/nix/daemon-socket \
|
||||
@ -259,13 +270,10 @@ let
|
||||
Slice = "machine.slice";
|
||||
Delegate = true;
|
||||
|
||||
# Hack: we don't want to kill systemd-nspawn, since we call
|
||||
# "machinectl poweroff" in preStop to shut down the
|
||||
# container cleanly. But systemd requires sending a signal
|
||||
# (at least if we want remaining processes to be killed
|
||||
# after the timeout). So send an ignored signal.
|
||||
# We rely on systemd-nspawn turning a SIGTERM to itself into a shutdown
|
||||
# signal (SIGRTMIN+3) for the inner container.
|
||||
KillMode = "mixed";
|
||||
KillSignal = "WINCH";
|
||||
KillSignal = "TERM";
|
||||
|
||||
DevicePolicy = "closed";
|
||||
DeviceAllow = map (d: "${d.node} ${d.modifier}") cfg.allowedDevices;
|
||||
@ -747,8 +755,6 @@ in
|
||||
|
||||
postStart = postStartScript dummyConfig;
|
||||
|
||||
preStop = "machinectl poweroff $INSTANCE";
|
||||
|
||||
restartIfChanged = false;
|
||||
|
||||
serviceConfig = serviceDirectives dummyConfig;
|
||||
|
@ -111,6 +111,26 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
|
||||
machine.succeed(f"nixos-container stop {id1}")
|
||||
machine.succeed(f"nixos-container start {id1}")
|
||||
|
||||
# clear serial backlog for next tests
|
||||
machine.succeed("logger eat console backlog 3ea46eb2-7f82-4f70-b810-3f00e3dd4c4d")
|
||||
machine.wait_for_console_text(
|
||||
"eat console backlog 3ea46eb2-7f82-4f70-b810-3f00e3dd4c4d"
|
||||
)
|
||||
|
||||
with subtest("Stop a container early"):
|
||||
machine.succeed(f"nixos-container stop {id1}")
|
||||
machine.succeed(f"nixos-container start {id1} &")
|
||||
machine.wait_for_console_text("Stage 2")
|
||||
machine.succeed(f"nixos-container stop {id1}")
|
||||
machine.wait_for_console_text(f"Container {id1} exited successfully")
|
||||
machine.succeed(f"nixos-container start {id1}")
|
||||
|
||||
with subtest("Stop a container without machined (regression test for #109695)"):
|
||||
machine.systemctl("stop systemd-machined")
|
||||
machine.succeed(f"nixos-container stop {id1}")
|
||||
machine.wait_for_console_text(f"Container {id1} has been shut down")
|
||||
machine.succeed(f"nixos-container start {id1}")
|
||||
|
||||
with subtest("tmpfiles are present"):
|
||||
machine.log("creating container tmpfiles")
|
||||
machine.succeed(
|
||||
|
Loading…
Reference in New Issue
Block a user