11package container
22
33import (
4- "fmt"
54 "strconv"
65
76 "golang.org/x/net/context"
@@ -11,11 +10,10 @@ import (
1110 "github.com/docker/docker/api/types/events"
1211 "github.com/docker/docker/api/types/filters"
1312 "github.com/docker/docker/cli/command"
14- "github.com/docker/docker/cli/command/system"
1513 clientapi "github.com/docker/docker/client"
1614)
1715
18- func waitExitOrRemoved (dockerCli * command.DockerCli , ctx context.Context , containerID string , waitRemove bool ) ( chan int , error ) {
16+ func waitExitOrRemoved (dockerCli * command.DockerCli , ctx context.Context , containerID string , waitRemove bool ) chan int {
1917 if len (containerID ) == 0 {
2018 // containerID can never be empty
2119 panic ("Internal Error: waitExitOrRemoved needs a containerID as parameter" )
@@ -24,11 +22,7 @@ func waitExitOrRemoved(dockerCli *command.DockerCli, ctx context.Context, contai
2422 statusChan := make (chan int )
2523 exitCode := 125
2624
27- eventProcessor := func (e events.Message , err error ) error {
28- if err != nil {
29- statusChan <- exitCode
30- return fmt .Errorf ("failed to decode event: %v" , err )
31- }
25+ eventProcessor := func (e events.Message ) bool {
3226
3327 stopProcessing := false
3428 switch e .Status {
@@ -53,11 +47,10 @@ func waitExitOrRemoved(dockerCli *command.DockerCli, ctx context.Context, contai
5347
5448 if stopProcessing {
5549 statusChan <- exitCode
56- // stop the loop processing
57- return fmt .Errorf ("done" )
50+ return true
5851 }
5952
60- return nil
53+ return false
6154 }
6255
6356 // Get events via Events API
@@ -67,14 +60,29 @@ func waitExitOrRemoved(dockerCli *command.DockerCli, ctx context.Context, contai
6760 options := types.EventsOptions {
6861 Filters : f ,
6962 }
70- resBody , err := dockerCli .Client ().Events (ctx , options )
71- if err != nil {
72- return nil , fmt .Errorf ("can't get events from daemon: %v" , err )
73- }
7463
75- go system .DecodeEvents (resBody , eventProcessor )
64+ eventCtx , cancel := context .WithCancel (ctx )
65+ eventq , errq := dockerCli .Client ().Events (eventCtx , options )
66+
67+ go func () {
68+ defer cancel ()
69+
70+ for {
71+ select {
72+ case evt := <- eventq :
73+ if eventProcessor (evt ) {
74+ return
75+ }
76+
77+ case err := <- errq :
78+ logrus .Errorf ("error getting events from daemon: %v" , err )
79+ statusChan <- exitCode
80+ return
81+ }
82+ }
83+ }()
7684
77- return statusChan , nil
85+ return statusChan
7886}
7987
8088// getExitCode performs an inspect on the container. It returns
0 commit comments