diff options
author | OpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com> | 2021-05-10 14:31:40 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-10 14:31:40 -0400 |
commit | 57b642525b674f99835b1abf510d1beef7bc0a23 (patch) | |
tree | 2f76a5c4db19a5f107e427736eff0e40b4ea14e3 /pkg | |
parent | 02b09795286f5d801d318b539ed5529e6442dcec (diff) | |
parent | 66e38ca55d9a0079eb7d317b5a70c2623fc90d20 (diff) | |
download | podman-57b642525b674f99835b1abf510d1beef7bc0a23.tar.gz podman-57b642525b674f99835b1abf510d1beef7bc0a23.tar.bz2 podman-57b642525b674f99835b1abf510d1beef7bc0a23.zip |
Merge pull request #10271 from matejvasek/fix-wait-next-exit
fix: improved "containers/{name}/wait" endpoint
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/utils/containers.go | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/pkg/api/handlers/utils/containers.go b/pkg/api/handlers/utils/containers.go index c4c9cc2ea..6c708f74e 100644 --- a/pkg/api/handlers/utils/containers.go +++ b/pkg/api/handlers/utils/containers.go @@ -7,6 +7,7 @@ import ( "strconv" "time" + "github.com/containers/podman/v3/libpod/events" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/infra/abi" @@ -175,7 +176,7 @@ func waitDockerCondition(ctx context.Context, containerName string, interval tim var code int32 switch dockerCondition { case "next-exit": - code, err = waitNextExit(containerWait) + code, err = waitNextExit(ctx, containerName) case "removed": code, err = waitRemoved(containerWait) case "not-running", "": @@ -202,12 +203,32 @@ func waitRemoved(ctrWait containerWaitFn) (int32, error) { return code, err } -func waitNextExit(ctrWait containerWaitFn) (int32, error) { - _, err := ctrWait(define.ContainerStateRunning) - if err != nil { - return -1, err - } - return ctrWait(notRunningStates...) +func waitNextExit(ctx context.Context, containerName string) (int32, error) { + runtime := ctx.Value("runtime").(*libpod.Runtime) + containerEngine := &abi.ContainerEngine{Libpod: runtime} + eventChannel := make(chan *events.Event) + errChannel := make(chan error) + opts := entities.EventsOptions{ + EventChan: eventChannel, + Filter: []string{"event=died", fmt.Sprintf("container=%s", containerName)}, + Stream: true, + } + + // ctx is used to cancel event watching goroutine + ctx, cancel := context.WithCancel(ctx) + defer cancel() + go func() { + errChannel <- containerEngine.Events(ctx, opts) + }() + + evt, ok := <-eventChannel + if ok { + return int32(evt.ContainerExitCode), nil + } + // if ok == false then containerEngine.Events() has exited + // it may happen if request was canceled (e.g. client closed connection prematurely) or + // the server is in process of shutting down + return -1, <-errChannel } func waitNotRunning(ctrWait containerWaitFn) (int32, error) { |