From b3829a29324f3618b18a2a2917d5c98de31eb275 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Tue, 8 Oct 2024 17:52:22 +0200 Subject: [PATCH] libpod API: make wait endpoint better against rm races In the common scenario of podman-remote run --rm the API is required to attach + start + wait to get exit code. This has the problem that the wait call races against the container removal from the cleanup process so it may not get the exit code back. However we keep the exit code around for longer than the container so we can just look it up in the endpoint. Of course this only works when we get a full id as param but podman-remote will do that. Signed-off-by: Paul Holzinger --- libpod/runtime.go | 4 ++++ pkg/api/handlers/utils/containers.go | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/libpod/runtime.go b/libpod/runtime.go index 1aea7b4fe6..1daf2855b2 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -1393,3 +1393,7 @@ func (r *Runtime) SystemCheck(ctx context.Context, options entities.SystemCheckO return report, err } + +func (r *Runtime) GetContainerExitCode(id string) (int32, error) { + return r.state.GetContainerExitCode(id) +} diff --git a/pkg/api/handlers/utils/containers.go b/pkg/api/handlers/utils/containers.go index 62af4b45d1..07f8ca7f2f 100644 --- a/pkg/api/handlers/utils/containers.go +++ b/pkg/api/handlers/utils/containers.go @@ -130,6 +130,17 @@ func WaitContainerLibpod(w http.ResponseWriter, r *http.Request) { reports, err := containerEngine.ContainerWait(r.Context(), []string{name}, opts) if err != nil { if errors.Is(err, define.ErrNoSuchCtr) { + // Special case: In the common scenario of podman-remote run --rm + // the API is required to attach + start + wait to get exit code. + // This has the problem that the wait call races against the container + // removal from the cleanup process so it may not get the exit code back. + // However we keep the exit code around for longer than the container so + // we can just look it up here. Of course this only works when we get a + // full id as param but podman-remote will do that + if code, err := runtime.GetContainerExitCode(name); err == nil { + WriteResponse(w, http.StatusOK, strconv.Itoa(int(code))) + return + } ContainerNotFound(w, name, err) return }