Skip to content

Commit

Permalink
libpod API: make wait endpoint better against rm races
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
Luap99 committed Oct 8, 2024
1 parent 3215d51 commit b3829a2
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 0 deletions.
4 changes: 4 additions & 0 deletions libpod/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
11 changes: 11 additions & 0 deletions pkg/api/handlers/utils/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down

0 comments on commit b3829a2

Please sign in to comment.