Skip to content

Commit 1541ce5

Browse files
committed
kube play: set service container as main PID when possible
Commit 4fa307f 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 <[email protected]>
1 parent 15caef9 commit 1541ce5

File tree

4 files changed

+43
-12
lines changed

4 files changed

+43
-12
lines changed

pkg/domain/infra/abi/play.go

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -314,14 +314,37 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options
314314
return nil, fmt.Errorf("YAML document does not contain any supported kube kind")
315315
}
316316

317+
// If we started containers along with a service container, we are
318+
// running inside a systemd unit and need to set the main PID.
317319
if options.ServiceContainer && ranContainers {
318-
message := fmt.Sprintf("MAINPID=%d\n%s", os.Getpid(), daemon.SdNotifyReady)
319-
if err := notifyproxy.SendMessage("", message); err != nil {
320-
return nil, err
321-
}
320+
switch len(notifyProxies) {
321+
case 0: // Optimization for containers/podman/issues/17345
322+
// No container needs sdnotify, so we can mark the
323+
// service container's conmon as the main PID and
324+
// return early.
325+
data, err := serviceContainer.Inspect(false)
326+
if err != nil {
327+
return nil, err
328+
}
329+
message := fmt.Sprintf("MAINPID=%d\n%s", data.State.ConmonPid, daemon.SdNotifyReady)
330+
if err := notifyproxy.SendMessage("", message); err != nil {
331+
return nil, err
332+
}
333+
default:
334+
// At least one container has a custom sdnotify policy,
335+
// so we need to let the sdnotify proxies run for the
336+
// lifetime of the service container. That means, we
337+
// need to wait for the service container to stop.
338+
// Podman will hence be marked as the main PID. That
339+
// comes at the cost of keeping Podman running.
340+
message := fmt.Sprintf("MAINPID=%d\n%s", os.Getpid(), daemon.SdNotifyReady)
341+
if err := notifyproxy.SendMessage("", message); err != nil {
342+
return nil, err
343+
}
322344

323-
if _, err := serviceContainer.Wait(ctx); err != nil {
324-
return nil, fmt.Errorf("waiting for service container: %w", err)
345+
if _, err := serviceContainer.Wait(ctx); err != nil {
346+
return nil, fmt.Errorf("waiting for service container: %w", err)
347+
}
325348
}
326349
}
327350

test/system/250-systemd.bats

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ EOF
399399

400400
# Make sure that Podman is the service's MainPID
401401
run systemctl show --property=MainPID --value $service_name
402-
is "$(</proc/$output/comm)" "podman" "podman is the service mainPID"
402+
is "$(</proc/$output/comm)" "conmon" "podman is the service mainPID"
403403

404404
# The name of the service container is predictable: the first 12 characters
405405
# of the hash of the YAML file followed by the "-service" suffix
@@ -433,12 +433,13 @@ EOF
433433
run_podman pod kill test_pod
434434
for i in {0..20}; do
435435
run systemctl is-active $service_name
436-
if [[ $output == "inactive" ]]; then
436+
if [[ $output == "failed" ]]; then
437437
break
438438
fi
439439
sleep 0.5
440440
done
441-
is "$output" "inactive" "systemd service transitioned to 'inactive' state: $service_name"
441+
# The service is marked as failed as the service container exits non-zero.
442+
is "$output" "failed" "systemd service transitioned to 'inactive' state: $service_name"
442443

443444
# Now stop and start the service again.
444445
systemctl stop $service_name

test/system/252-quadlet.bats

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,8 @@ EOF
420420
run_podman container inspect --format "{{.State.Status}}" test_pod-test
421421
is "$output" "running" "container should be started by systemd and hence be running"
422422

423-
service_cleanup $QUADLET_SERVICE_NAME inactive
423+
# The service is marked as failed as the service container exits non-zero.
424+
service_cleanup $QUADLET_SERVICE_NAME failed
424425
run_podman rmi $(pause_image)
425426
}
426427

test/system/260-sdnotify.bats

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,14 @@ EOF
218218
_start_socat
219219
wait_for_file $_SOCAT_LOG
220220

221-
# Will run until all containers have stopped.
222221
run_podman play kube --service-container=true --log-driver journald $yaml_source
222+
223+
# The service container is the main PID since no container has a custom
224+
# sdnotify policy.
225+
run_podman container inspect $service_container --format "{{.State.ConmonPid}}"
226+
main_pid="$output"
227+
228+
# Will run until all containers have stopped.
223229
run_podman container wait $service_container test_pod-test
224230

225231
# Make sure the containers have the correct policy.
@@ -233,7 +239,7 @@ ignore"
233239
echo "$output"
234240

235241
# The "with policies" test below checks the MAINPID.
236-
is "$output" "MAINPID=.*
242+
is "$output" "MAINPID=$main_pid
237243
READY=1" "sdnotify sent MAINPID and READY"
238244

239245
_stop_socat

0 commit comments

Comments
 (0)