github.com/ssdev-go/moby@v17.12.1-ce-rc2+incompatible/client/events.go (about) 1 package client 2 3 import ( 4 "encoding/json" 5 "net/url" 6 "time" 7 8 "golang.org/x/net/context" 9 10 "github.com/docker/docker/api/types" 11 "github.com/docker/docker/api/types/events" 12 "github.com/docker/docker/api/types/filters" 13 timetypes "github.com/docker/docker/api/types/time" 14 ) 15 16 // Events returns a stream of events in the daemon. It's up to the caller to close the stream 17 // by cancelling the context. Once the stream has been completely read an io.EOF error will 18 // be sent over the error channel. If an error is sent all processing will be stopped. It's up 19 // to the caller to reopen the stream in the event of an error by reinvoking this method. 20 func (cli *Client) Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error) { 21 22 messages := make(chan events.Message) 23 errs := make(chan error, 1) 24 25 started := make(chan struct{}) 26 go func() { 27 defer close(errs) 28 29 query, err := buildEventsQueryParams(cli.version, options) 30 if err != nil { 31 close(started) 32 errs <- err 33 return 34 } 35 36 resp, err := cli.get(ctx, "/events", query, nil) 37 if err != nil { 38 close(started) 39 errs <- err 40 return 41 } 42 defer resp.body.Close() 43 44 decoder := json.NewDecoder(resp.body) 45 46 close(started) 47 for { 48 select { 49 case <-ctx.Done(): 50 errs <- ctx.Err() 51 return 52 default: 53 var event events.Message 54 if err := decoder.Decode(&event); err != nil { 55 errs <- err 56 return 57 } 58 59 select { 60 case messages <- event: 61 case <-ctx.Done(): 62 errs <- ctx.Err() 63 return 64 } 65 } 66 } 67 }() 68 <-started 69 70 return messages, errs 71 } 72 73 func buildEventsQueryParams(cliVersion string, options types.EventsOptions) (url.Values, error) { 74 query := url.Values{} 75 ref := time.Now() 76 77 if options.Since != "" { 78 ts, err := timetypes.GetTimestamp(options.Since, ref) 79 if err != nil { 80 return nil, err 81 } 82 query.Set("since", ts) 83 } 84 85 if options.Until != "" { 86 ts, err := timetypes.GetTimestamp(options.Until, ref) 87 if err != nil { 88 return nil, err 89 } 90 query.Set("until", ts) 91 } 92 93 if options.Filters.Len() > 0 { 94 filterJSON, err := filters.ToParamWithVersion(cliVersion, options.Filters) 95 if err != nil { 96 return nil, err 97 } 98 query.Set("filters", filterJSON) 99 } 100 101 return query, nil 102 }