From 1541ce56cf2d8784f570903a0ac5ea871dc029f5 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Fri, 10 Feb 2023 11:33:09 +0100 Subject: [PATCH] kube play: set service container as main PID when possible Commit 4fa307f14923 fixed a number of issues in the sdnotify proxies. Whenever a container runs with a custom sdnotify policy, the proxies need to keep running which in turn required Podman to run and wait for the service container to stop. Improve on that behavior and set the service container as the main PID (instead of Podman) when no container needs sdnotify. Fixes: #17345 Signed-off-by: Valentin Rothberg --- pkg/domain/infra/abi/play.go | 35 +++++++++++++++++++++++++++++------ test/system/250-systemd.bats | 7 ++++--- test/system/252-quadlet.bats | 3 ++- test/system/260-sdnotify.bats | 10 ++++++++-- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index 1ec71f9b5c..b47ccba48b 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -314,14 +314,37 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options return nil, fmt.Errorf("YAML document does not contain any supported kube kind") } + // If we started containers along with a service container, we are + // running inside a systemd unit and need to set the main PID. if options.ServiceContainer && ranContainers { - message := fmt.Sprintf("MAINPID=%d\n%s", os.Getpid(), daemon.SdNotifyReady) - if err := notifyproxy.SendMessage("", message); err != nil { - return nil, err - } + switch len(notifyProxies) { + case 0: // Optimization for containers/podman/issues/17345 + // No container needs sdnotify, so we can mark the + // service container's conmon as the main PID and + // return early. + data, err := serviceContainer.Inspect(false) + if err != nil { + return nil, err + } + message := fmt.Sprintf("MAINPID=%d\n%s", data.State.ConmonPid, daemon.SdNotifyReady) + if err := notifyproxy.SendMessage("", message); err != nil { + return nil, err + } + default: + // At least one container has a custom sdnotify policy, + // so we need to let the sdnotify proxies run for the + // lifetime of the service container. That means, we + // need to wait for the service container to stop. + // Podman will hence be marked as the main PID. That + // comes at the cost of keeping Podman running. + message := fmt.Sprintf("MAINPID=%d\n%s", os.Getpid(), daemon.SdNotifyReady) + if err := notifyproxy.SendMessage("", message); err != nil { + return nil, err + } - if _, err := serviceContainer.Wait(ctx); err != nil { - return nil, fmt.Errorf("waiting for service container: %w", err) + if _, err := serviceContainer.Wait(ctx); err != nil { + return nil, fmt.Errorf("waiting for service container: %w", err) + } } } diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats index d345765464..b3d8f82af0 100644 --- a/test/system/250-systemd.bats +++ b/test/system/250-systemd.bats @@ -399,7 +399,7 @@ EOF # Make sure that Podman is the service's MainPID run systemctl show --property=MainPID --value $service_name - is "$(