From 08407834a5275793d152571d679c7cda9997379b Mon Sep 17 00:00:00 2001 From: moncho Date: Fri, 13 May 2016 21:09:15 +0200 Subject: [PATCH 1/3] Update engine-api --- Godeps/Godeps.json | 58 +++++++++---------- .../docker/engine-api/client/image_build.go | 16 ----- .../docker/engine-api/client/image_pull.go | 2 +- .../docker/engine-api/client/image_push.go | 2 +- .../docker/engine-api/client/image_search.go | 11 +++- .../docker/engine-api/client/request.go | 13 +++-- .../docker/engine-api/types/client.go | 1 + .../engine-api/types/container/host_config.go | 31 ++++++++-- .../docker/engine-api/types/events/events.go | 2 + .../engine-api/types/registry/registry.go | 4 +- 10 files changed, 79 insertions(+), 61 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index ee2a8ce4..49f6a30f 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,7 +1,7 @@ { "ImportPath": "github.com/moncho/dry", "GoVersion": "go1.6", - "GodepVersion": "v62", + "GodepVersion": "v65", "Packages": [ "github.com/moncho/dry" ], @@ -33,73 +33,73 @@ }, { "ImportPath": "github.com/docker/engine-api/client", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/engine-api/client/transport", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/engine-api/client/transport/cancellable", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/engine-api/types", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/engine-api/types/blkiodev", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/engine-api/types/container", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/engine-api/types/events", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/engine-api/types/filters", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/engine-api/types/network", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/engine-api/types/reference", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/engine-api/types/registry", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/engine-api/types/strslice", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/engine-api/types/time", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/engine-api/types/versions", - "Comment": "v0.2.2-264-g009426d", - "Rev": "009426d98aa84d199210a897dbb60bfee541877d" + "Comment": "v0.3.1-93-ge374c4f", + "Rev": "e374c4fb5b121a8fd4295ec5eb91a8068c6304f4" }, { "ImportPath": "github.com/docker/go-connections/nat", diff --git a/vendor/github.com/docker/engine-api/client/image_build.go b/vendor/github.com/docker/engine-api/client/image_build.go index 4165c4e9..0ceb88cf 100644 --- a/vendor/github.com/docker/engine-api/client/image_build.go +++ b/vendor/github.com/docker/engine-api/client/image_build.go @@ -8,7 +8,6 @@ import ( "net/url" "regexp" "strconv" - "strings" "golang.org/x/net/context" @@ -118,18 +117,3 @@ func getDockerOS(serverHeader string) string { } return osType } - -// convertKVStringsToMap converts ["key=value"] to {"key":"value"} -func convertKVStringsToMap(values []string) map[string]string { - result := make(map[string]string, len(values)) - for _, value := range values { - kv := strings.SplitN(value, "=", 2) - if len(kv) == 1 { - result[kv[0]] = "" - } else { - result[kv[0]] = kv[1] - } - } - - return result -} diff --git a/vendor/github.com/docker/engine-api/client/image_pull.go b/vendor/github.com/docker/engine-api/client/image_pull.go index 9287604a..e2c49ec5 100644 --- a/vendor/github.com/docker/engine-api/client/image_pull.go +++ b/vendor/github.com/docker/engine-api/client/image_pull.go @@ -32,7 +32,7 @@ func (cli *Client) ImagePull(ctx context.Context, ref string, options types.Imag } resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth) - if resp.statusCode == http.StatusUnauthorized { + if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil { newAuthHeader, privilegeErr := options.PrivilegeFunc() if privilegeErr != nil { return nil, privilegeErr diff --git a/vendor/github.com/docker/engine-api/client/image_push.go b/vendor/github.com/docker/engine-api/client/image_push.go index 9c837a76..89191ee3 100644 --- a/vendor/github.com/docker/engine-api/client/image_push.go +++ b/vendor/github.com/docker/engine-api/client/image_push.go @@ -35,7 +35,7 @@ func (cli *Client) ImagePush(ctx context.Context, ref string, options types.Imag query.Set("tag", tag) resp, err := cli.tryImagePush(ctx, distributionRef.Name(), query, options.RegistryAuth) - if resp.statusCode == http.StatusUnauthorized { + if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil { newAuthHeader, privilegeErr := options.PrivilegeFunc() if privilegeErr != nil { return nil, privilegeErr diff --git a/vendor/github.com/docker/engine-api/client/image_search.go b/vendor/github.com/docker/engine-api/client/image_search.go index 3528bda6..312e5b1e 100644 --- a/vendor/github.com/docker/engine-api/client/image_search.go +++ b/vendor/github.com/docker/engine-api/client/image_search.go @@ -6,6 +6,7 @@ import ( "net/url" "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/filters" "github.com/docker/engine-api/types/registry" "golang.org/x/net/context" ) @@ -17,8 +18,16 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options types.I query := url.Values{} query.Set("term", term) + if options.Filters.Len() > 0 { + filterJSON, err := filters.ToParam(options.Filters) + if err != nil { + return results, err + } + query.Set("filters", filterJSON) + } + resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth) - if resp.statusCode == http.StatusUnauthorized { + if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil { newAuthHeader, privilegeErr := options.PrivilegeFunc() if privilegeErr != nil { return results, privilegeErr diff --git a/vendor/github.com/docker/engine-api/client/request.go b/vendor/github.com/docker/engine-api/client/request.go index cdbb0975..5b283a4f 100644 --- a/vendor/github.com/docker/engine-api/client/request.go +++ b/vendor/github.com/docker/engine-api/client/request.go @@ -85,6 +85,10 @@ func (cli *Client) sendClientRequest(ctx context.Context, method, path string, q } req, err := cli.newRequest(method, path, query, body, headers) + if err != nil { + return serverResp, err + } + if cli.proto == "unix" || cli.proto == "npipe" { // For local communications, it doesn't matter what the host is. We just // need a valid and meaningful host name. (See #189) @@ -98,10 +102,6 @@ func (cli *Client) sendClientRequest(ctx context.Context, method, path string, q } resp, err := cancellable.Do(ctx, cli.transport, req) - if resp != nil { - serverResp.statusCode = resp.StatusCode - } - if err != nil { if isTimeout(err) || strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "dial unix") { return serverResp, ErrConnectionFailed @@ -110,6 +110,7 @@ func (cli *Client) sendClientRequest(ctx context.Context, method, path string, q if !cli.transport.Secure() && strings.Contains(err.Error(), "malformed HTTP response") { return serverResp, fmt.Errorf("%v.\n* Are you trying to connect to a TLS-enabled daemon without TLS?", err) } + if cli.transport.Secure() && strings.Contains(err.Error(), "remote error: bad certificate") { return serverResp, fmt.Errorf("The server probably has client authentication (--tlsverify) enabled. Please check your TLS client certification settings: %v", err) } @@ -117,6 +118,10 @@ func (cli *Client) sendClientRequest(ctx context.Context, method, path string, q return serverResp, fmt.Errorf("An error occurred trying to connect: %v", err) } + if resp != nil { + serverResp.statusCode = resp.StatusCode + } + if serverResp.statusCode < 200 || serverResp.statusCode >= 400 { body, err := ioutil.ReadAll(resp.Body) if err != nil { diff --git a/vendor/github.com/docker/engine-api/types/client.go b/vendor/github.com/docker/engine-api/types/client.go index 8218b174..fa3b2cfb 100644 --- a/vendor/github.com/docker/engine-api/types/client.go +++ b/vendor/github.com/docker/engine-api/types/client.go @@ -206,6 +206,7 @@ type ImageRemoveOptions struct { type ImageSearchOptions struct { RegistryAuth string PrivilegeFunc RequestPrivilegeFunc + Filters filters.Args } // ImageTagOptions holds parameters to tag an image diff --git a/vendor/github.com/docker/engine-api/types/container/host_config.go b/vendor/github.com/docker/engine-api/types/container/host_config.go index 39f6a225..531408c9 100644 --- a/vendor/github.com/docker/engine-api/types/container/host_config.go +++ b/vendor/github.com/docker/engine-api/types/container/host_config.go @@ -136,30 +136,49 @@ func (n UTSMode) Valid() bool { return true } -// PidMode represents the pid stack of the container. +// PidMode represents the pid namespace of the container. type PidMode string -// IsPrivate indicates whether the container uses its private pid stack. +// IsPrivate indicates whether the container uses its own new pid namespace. func (n PidMode) IsPrivate() bool { - return !(n.IsHost()) + return !(n.IsHost() || n.IsContainer()) } -// IsHost indicates whether the container uses the host's pid stack. +// IsHost indicates whether the container uses the host's pid namespace. func (n PidMode) IsHost() bool { return n == "host" } -// Valid indicates whether the pid stack is valid. +// IsContainer indicates whether the container uses a container's pid namespace. +func (n PidMode) IsContainer() bool { + parts := strings.SplitN(string(n), ":", 2) + return len(parts) > 1 && parts[0] == "container" +} + +// Valid indicates whether the pid namespace is valid. func (n PidMode) Valid() bool { parts := strings.Split(string(n), ":") switch mode := parts[0]; mode { case "", "host": + case "container": + if len(parts) != 2 || parts[1] == "" { + return false + } default: return false } return true } +// Container returns the name of the container whose pid namespace is going to be used. +func (n PidMode) Container() string { + parts := strings.SplitN(string(n), ":", 2) + if len(parts) > 1 { + return parts[1] + } + return "" +} + // DeviceMapping represents the device mapping between the host and the container. type DeviceMapping struct { PathOnHost string @@ -176,7 +195,7 @@ type RestartPolicy struct { // IsNone indicates whether the container has the "no" restart policy. // This means the container will not automatically restart when exiting. func (rp *RestartPolicy) IsNone() bool { - return rp.Name == "no" + return rp.Name == "no" || rp.Name == "" } // IsAlways indicates whether the container has the "always" restart policy. diff --git a/vendor/github.com/docker/engine-api/types/events/events.go b/vendor/github.com/docker/engine-api/types/events/events.go index c5987aaf..bbb72500 100644 --- a/vendor/github.com/docker/engine-api/types/events/events.go +++ b/vendor/github.com/docker/engine-api/types/events/events.go @@ -9,6 +9,8 @@ const ( VolumeEventType = "volume" // NetworkEventType is the event type that networks generate NetworkEventType = "network" + // DaemonEventType is the event type that daemon generate + DaemonEventType = "daemon" ) // Actor describes something that generates events, diff --git a/vendor/github.com/docker/engine-api/types/registry/registry.go b/vendor/github.com/docker/engine-api/types/registry/registry.go index 8a6fe70e..d2aca6f0 100644 --- a/vendor/github.com/docker/engine-api/types/registry/registry.go +++ b/vendor/github.com/docker/engine-api/types/registry/registry.go @@ -78,12 +78,10 @@ type IndexInfo struct { type SearchResult struct { // StarCount indicates the number of stars this repository has StarCount int `json:"star_count"` - // IsOfficial indicates whether the result is an official repository or not + // IsOfficial is true if the result is from an official repository. IsOfficial bool `json:"is_official"` // Name is the name of the repository Name string `json:"name"` - // IsTrusted indicates whether the result is trusted - IsTrusted bool `json:"is_trusted"` // IsAutomated indicates whether the result is automated IsAutomated bool `json:"is_automated"` // Description is a textual description of the repository From 10a348ad83d62bc14aeb7f795287130d2cac0b60 Mon Sep 17 00:00:00 2001 From: moncho Date: Fri, 13 May 2016 21:10:08 +0200 Subject: [PATCH 2/3] Add check for empty stats to avoid panics --- appui/stats.go | 5 ++++- docker/stats.go | 12 +++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/appui/stats.go b/appui/stats.go index 3487e1cd..8af7e158 100644 --- a/appui/stats.go +++ b/appui/stats.go @@ -26,7 +26,10 @@ func NewDockerStatsRenderer(stats *drydocker.Stats) ui.Renderer { //Render container stats func (r *statsRenderer) Render() string { s := r.stats - processList := r.stats.ProcessList + if s == nil { + return "" + } + processList := s.ProcessList buf := bytes.NewBufferString("") io.WriteString(buf, "\n") diff --git a/docker/stats.go b/docker/stats.go index 310273b2..c984c25c 100644 --- a/docker/stats.go +++ b/docker/stats.go @@ -17,7 +17,8 @@ func StatsChannel(daemon *DockerDaemon, container types.Container, streamStats b go func() { cli := daemon.client - responseBody, err := cli.ContainerStats(context.Background(), container.Names[0], streamStats) + ctx, cancel := context.WithCancel(context.Background()) + responseBody, err := cli.ContainerStats(ctx, container.Names[0], streamStats) defer responseBody.Close() defer close(stats) if err != nil { @@ -37,9 +38,14 @@ func StatsChannel(daemon *DockerDaemon, container types.Container, streamStats b if err := dec.Decode(&statsJSON); err != nil { return } - top, _ := daemon.Top(container.ID) - stats <- buildStats(container, statsJSON, &top) + if statsJSON != nil { + top, _ := daemon.Top(container.ID) + stats <- buildStats(container, statsJSON, &top) + } + case <-ctx.Done(): + return case <-done: + cancel() return } } From 76b3f7e50fc94b254f5bc30da12db36c0e0b1654 Mon Sep 17 00:00:00 2001 From: moncho Date: Fri, 13 May 2016 21:26:32 +0200 Subject: [PATCH 3/3] Add a default timeout of 10 seconds to any Docker command This will help dry to be more responsive when connected to slow-answering Docker daemons. --- docker/docker.go | 95 ++++++++++++++++++++++++++++++++++++++---------- docker/events.go | 7 +++- 2 files changed, 82 insertions(+), 20 deletions(-) diff --git a/docker/docker.go b/docker/docker.go index e1e0409b..82d88a80 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -7,6 +7,7 @@ import ( "strings" "sync" "sync/atomic" + "time" dockerAPI "github.com/docker/engine-api/client" dockerTypes "github.com/docker/engine-api/types" @@ -20,7 +21,9 @@ const ( DefaultDockerHost = "unix:///var/run/docker.sock" //timeout in seconds for docker operations - defaultTimeout = 10 + defaultTimeout = 10 * time.Second + //container operations timeout, docker api interprets the value as seconds + containerOpTimeout = 10 ) //DockerDaemon knows how to talk to the Docker daemon @@ -86,7 +89,8 @@ func (daemon *DockerDaemon) Events() (<-chan dockerEvents.Message, chan<- struct options := dockerTypes.EventsOptions{ //Since: time.Now().String(), } - events, err := daemon.client.Events(context.Background(), options) + ctx, cancel := context.WithCancel(context.Background()) + events, err := daemon.client.Events(ctx, options) if err != nil { return nil, nil, err @@ -95,10 +99,13 @@ func (daemon *DockerDaemon) Events() (<-chan dockerEvents.Message, chan<- struct done := make(chan struct{}) go func() { - go decodeEvents(events, + decodeEvents( + ctx, + events, streamEvents(eventC), logEvents(daemon.eventLog)) <-done + cancel() close(eventC) events.Close() }() @@ -113,7 +120,11 @@ func (daemon *DockerDaemon) EventLog() *EventLog { //History returns image history func (daemon *DockerDaemon) History(id string) ([]dockerTypes.ImageHistory, error) { - return daemon.client.ImageHistory(context.Background(), id) + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + + return daemon.client.ImageHistory( + ctx, id) } //ImageAt returns the Image found at the given @@ -143,17 +154,26 @@ func (daemon *DockerDaemon) ImagesCount() int { //Info returns system-wide information about the Docker server. func (daemon *DockerDaemon) Info() (dockerTypes.Info, error) { - return daemon.client.Info(context.Background()) + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + + return daemon.client.Info(ctx) } //Inspect the container with the given id func (daemon *DockerDaemon) Inspect(id string) (dockerTypes.ContainerJSON, error) { - return daemon.client.ContainerInspect(context.Background(), id) + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + + return daemon.client.ContainerInspect(ctx, id) } //InspectImage the image with the name func (daemon *DockerDaemon) InspectImage(name string) (dockerTypes.ImageInspect, error) { - inspect, _, err := daemon.client.ImageInspectWithRaw(context.Background(), name, true) + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + + inspect, _, err := daemon.client.ImageInspectWithRaw(ctx, name, true) return inspect, err } @@ -164,8 +184,12 @@ func (daemon *DockerDaemon) IsContainerRunning(id string) bool { //Kill the container with the given id func (daemon *DockerDaemon) Kill(id string) error { + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + //TODO Sends the right signal - return daemon.client.ContainerKill(context.Background(), id, "") + + return daemon.client.ContainerKill(ctx, id, "") } //Logs shows the logs of the container with the given id @@ -177,8 +201,10 @@ func (daemon *DockerDaemon) Logs(id string) io.ReadCloser { Follow: true, Details: false, } + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) - reader, _ := daemon.client.ContainerLogs(context.Background(), id, options) + reader, _ := daemon.client.ContainerLogs(ctx, id, options) return reader } @@ -208,7 +234,11 @@ func (daemon *DockerDaemon) NetworksCount() int { //NetworkInspect returns network detailed information func (daemon *DockerDaemon) NetworkInspect(id string) (dockerTypes.NetworkResource, error) { - return daemon.client.NetworkInspect(context.Background(), id) + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + + return daemon.client.NetworkInspect( + ctx, id) } //Ok is true if connecting to the Docker daemon went fine @@ -218,8 +248,11 @@ func (daemon *DockerDaemon) Ok() (bool, error) { //RestartContainer restarts the container with the given id func (daemon *DockerDaemon) RestartContainer(id string) error { + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + //fixme: timeout to start a container - return daemon.client.ContainerRestart(context.Background(), id, defaultTimeout) + return daemon.client.ContainerRestart(ctx, id, containerOpTimeout) } //Rm removes the container with the given id @@ -229,7 +262,10 @@ func (daemon *DockerDaemon) Rm(id string) error { RemoveLinks: false, Force: true, } - return daemon.client.ContainerRemove(context.Background(), id, opts) + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + + return daemon.client.ContainerRemove(ctx, id, opts) } //Refresh the container list @@ -311,7 +347,10 @@ func (daemon *DockerDaemon) Rmi(name string, force bool) ([]dockerTypes.ImageDel options := dockerTypes.ImageRemoveOptions{ Force: force, } - return daemon.client.ImageRemove(context.Background(), name, options) + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + + return daemon.client.ImageRemove(ctx, name, options) } //Stats shows resource usage statistics of the container with the given id @@ -321,7 +360,10 @@ func (daemon *DockerDaemon) Stats(id string) (<-chan *Stats, chan<- struct{}) { //StopContainer stops the container with the given id func (daemon *DockerDaemon) StopContainer(id string) error { - return daemon.client.ContainerStop(context.Background(), id, defaultTimeout) + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + + return daemon.client.ContainerStop(ctx, id, containerOpTimeout) } //Sort the list of containers by the given mode @@ -347,13 +389,19 @@ func (daemon *DockerDaemon) SortNetworks(sortMode SortNetworksMode) { //Top returns Top information for the given container func (daemon *DockerDaemon) Top(id string) (dockerTypes.ContainerProcessList, error) { - return daemon.client.ContainerTop(context.Background(), id, nil) + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + + return daemon.client.ContainerTop(ctx, id, nil) } //Version returns version information about the Docker Engine func (daemon *DockerDaemon) Version() (*dockerTypes.Version, error) { if daemon.version == nil { - v, err := daemon.client.ServerVersion(context.Background()) + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + + v, err := daemon.client.ServerVersion(ctx) if err == nil { daemon.version = &v return daemon.version, nil @@ -364,7 +412,10 @@ func (daemon *DockerDaemon) Version() (*dockerTypes.Version, error) { } func containers(client dockerAPI.APIClient, allContainers bool) ([]dockerTypes.Container, map[string]dockerTypes.Container, error) { - containers, err := client.ContainerList(context.Background(), dockerTypes.ContainerListOptions{All: allContainers, Size: true}) + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + + containers, err := client.ContainerList(ctx, dockerTypes.ContainerListOptions{All: allContainers, Size: true}) if err == nil { var cmap = make(map[string]dockerTypes.Container) @@ -377,13 +428,19 @@ func containers(client dockerAPI.APIClient, allContainers bool) ([]dockerTypes.C } func images(client dockerAPI.APIClient) ([]dockerTypes.Image, error) { + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + opts := dockerTypes.ImageListOptions{ All: false} - return client.ImageList(context.Background(), opts) + return client.ImageList(ctx, opts) } func networks(client dockerAPI.APIClient) ([]dockerTypes.NetworkResource, error) { - return client.NetworkList(context.Background(), dockerTypes.NetworkListOptions{}) + //TODO use cancel function + ctx, _ := context.WithTimeout(context.Background(), defaultTimeout) + + return client.NetworkList(ctx, dockerTypes.NetworkListOptions{}) } //GetBool returns false if the given string looks like you mean diff --git a/docker/events.go b/docker/events.go index f3297b18..67c41153 100644 --- a/docker/events.go +++ b/docker/events.go @@ -5,6 +5,8 @@ import ( "errors" "io" + "golang.org/x/net/context" + "github.com/docker/engine-api/types/events" ) @@ -33,7 +35,10 @@ func logEvents(log *EventLog) eventProcessor { type eventProcessor func(event events.Message, err error) error -func decodeEvents(input io.Reader, processors ...eventProcessor) error { +func decodeEvents( + ctx context.Context, + input io.Reader, + processors ...eventProcessor) error { dec := json.NewDecoder(input) for { var event events.Message