Browse code

Vendor engine-api to fba5dc8

It plumbs net/context.Context through entire API, see docker/engine-api#140

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2016/03/17 04:19:13
Showing 53 changed files
... ...
@@ -24,7 +24,7 @@ clone git golang.org/x/net 47990a1ba55743e6ef1affd3a14e5bac8553615d https://gith
24 24
 clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://github.com/golang/sys.git
25 25
 clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3
26 26
 clone git github.com/docker/go-connections v0.2.0
27
-clone git github.com/docker/engine-api 9bab0d5b73872e53dfadfa055dcc519e57b09439
27
+clone git github.com/docker/engine-api 6de18e18540cda038b00e71a1f2946d779e83f87
28 28
 clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837
29 29
 clone git github.com/imdario/mergo 0.2.1
30 30
 
... ...
@@ -4,13 +4,14 @@ import (
4 4
 	"net/url"
5 5
 
6 6
 	"github.com/docker/engine-api/types"
7
+	"golang.org/x/net/context"
7 8
 )
8 9
 
9 10
 // ContainerAttach attaches a connection to a container in the server.
10 11
 // It returns a types.HijackedConnection with the hijacked connection
11 12
 // and the a reader to get output. It's up to the called to close
12 13
 // the hijacked connection by calling types.HijackedResponse.Close.
13
-func (cli *Client) ContainerAttach(options types.ContainerAttachOptions) (types.HijackedResponse, error) {
14
+func (cli *Client) ContainerAttach(ctx context.Context, options types.ContainerAttachOptions) (types.HijackedResponse, error) {
14 15
 	query := url.Values{}
15 16
 	if options.Stream {
16 17
 		query.Set("stream", "1")
... ...
@@ -29,5 +30,5 @@ func (cli *Client) ContainerAttach(options types.ContainerAttachOptions) (types.
29 29
 	}
30 30
 
31 31
 	headers := map[string][]string{"Content-Type": {"text/plain"}}
32
-	return cli.postHijacked("/containers/"+options.ContainerID+"/attach", query, nil, headers)
32
+	return cli.postHijacked(ctx, "/containers/"+options.ContainerID+"/attach", query, nil, headers)
33 33
 }
... ...
@@ -5,10 +5,11 @@ import (
5 5
 	"net/url"
6 6
 
7 7
 	"github.com/docker/engine-api/types"
8
+	"golang.org/x/net/context"
8 9
 )
9 10
 
10 11
 // ContainerCommit applies changes into a container and creates a new tagged image.
11
-func (cli *Client) ContainerCommit(options types.ContainerCommitOptions) (types.ContainerCommitResponse, error) {
12
+func (cli *Client) ContainerCommit(ctx context.Context, options types.ContainerCommitOptions) (types.ContainerCommitResponse, error) {
12 13
 	query := url.Values{}
13 14
 	query.Set("container", options.ContainerID)
14 15
 	query.Set("repo", options.RepositoryName)
... ...
@@ -23,7 +24,7 @@ func (cli *Client) ContainerCommit(options types.ContainerCommitOptions) (types.
23 23
 	}
24 24
 
25 25
 	var response types.ContainerCommitResponse
26
-	resp, err := cli.post("/commit", query, options.Config, nil)
26
+	resp, err := cli.post(ctx, "/commit", query, options.Config, nil)
27 27
 	if err != nil {
28 28
 		return response, err
29 29
 	}
... ...
@@ -16,12 +16,12 @@ import (
16 16
 )
17 17
 
18 18
 // ContainerStatPath returns Stat information about a path inside the container filesystem.
19
-func (cli *Client) ContainerStatPath(containerID, path string) (types.ContainerPathStat, error) {
19
+func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path string) (types.ContainerPathStat, error) {
20 20
 	query := url.Values{}
21 21
 	query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API.
22 22
 
23 23
 	urlStr := fmt.Sprintf("/containers/%s/archive", containerID)
24
-	response, err := cli.head(urlStr, query, nil)
24
+	response, err := cli.head(ctx, urlStr, query, nil)
25 25
 	if err != nil {
26 26
 		return types.ContainerPathStat{}, err
27 27
 	}
... ...
@@ -40,7 +40,7 @@ func (cli *Client) CopyToContainer(ctx context.Context, options types.CopyToCont
40 40
 
41 41
 	path := fmt.Sprintf("/containers/%s/archive", options.ContainerID)
42 42
 
43
-	response, err := cli.putRawWithContext(ctx, path, query, options.Content, nil)
43
+	response, err := cli.putRaw(ctx, path, query, options.Content, nil)
44 44
 	if err != nil {
45 45
 		return err
46 46
 	}
... ...
@@ -60,7 +60,7 @@ func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath s
60 60
 	query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API.
61 61
 
62 62
 	apiPath := fmt.Sprintf("/containers/%s/archive", containerID)
63
-	response, err := cli.getWithContext(ctx, apiPath, query, nil)
63
+	response, err := cli.get(ctx, apiPath, query, nil)
64 64
 	if err != nil {
65 65
 		return nil, types.ContainerPathStat{}, err
66 66
 	}
... ...
@@ -8,6 +8,7 @@ import (
8 8
 	"github.com/docker/engine-api/types"
9 9
 	"github.com/docker/engine-api/types/container"
10 10
 	"github.com/docker/engine-api/types/network"
11
+	"golang.org/x/net/context"
11 12
 )
12 13
 
13 14
 type configWrapper struct {
... ...
@@ -18,7 +19,7 @@ type configWrapper struct {
18 18
 
19 19
 // ContainerCreate creates a new container based in the given configuration.
20 20
 // It can be associated with a name, but it's not mandatory.
21
-func (cli *Client) ContainerCreate(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (types.ContainerCreateResponse, error) {
21
+func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (types.ContainerCreateResponse, error) {
22 22
 	var response types.ContainerCreateResponse
23 23
 	query := url.Values{}
24 24
 	if containerName != "" {
... ...
@@ -31,7 +32,7 @@ func (cli *Client) ContainerCreate(config *container.Config, hostConfig *contain
31 31
 		NetworkingConfig: networkingConfig,
32 32
 	}
33 33
 
34
-	serverResp, err := cli.post("/containers/create", query, body, nil)
34
+	serverResp, err := cli.post(ctx, "/containers/create", query, body, nil)
35 35
 	if err != nil {
36 36
 		if serverResp != nil && serverResp.statusCode == 404 && strings.Contains(err.Error(), "No such image") {
37 37
 			return response, imageNotFoundError{config.Image}
... ...
@@ -5,13 +5,14 @@ import (
5 5
 	"net/url"
6 6
 
7 7
 	"github.com/docker/engine-api/types"
8
+	"golang.org/x/net/context"
8 9
 )
9 10
 
10 11
 // ContainerDiff shows differences in a container filesystem since it was started.
11
-func (cli *Client) ContainerDiff(containerID string) ([]types.ContainerChange, error) {
12
+func (cli *Client) ContainerDiff(ctx context.Context, containerID string) ([]types.ContainerChange, error) {
12 13
 	var changes []types.ContainerChange
13 14
 
14
-	serverResp, err := cli.get("/containers/"+containerID+"/changes", url.Values{}, nil)
15
+	serverResp, err := cli.get(ctx, "/containers/"+containerID+"/changes", url.Values{}, nil)
15 16
 	if err != nil {
16 17
 		return changes, err
17 18
 	}
... ...
@@ -4,12 +4,13 @@ import (
4 4
 	"encoding/json"
5 5
 
6 6
 	"github.com/docker/engine-api/types"
7
+	"golang.org/x/net/context"
7 8
 )
8 9
 
9 10
 // ContainerExecCreate creates a new exec configuration to run an exec process.
10
-func (cli *Client) ContainerExecCreate(config types.ExecConfig) (types.ContainerExecCreateResponse, error) {
11
+func (cli *Client) ContainerExecCreate(ctx context.Context, config types.ExecConfig) (types.ContainerExecCreateResponse, error) {
11 12
 	var response types.ContainerExecCreateResponse
12
-	resp, err := cli.post("/containers/"+config.Container+"/exec", nil, config, nil)
13
+	resp, err := cli.post(ctx, "/containers/"+config.Container+"/exec", nil, config, nil)
13 14
 	if err != nil {
14 15
 		return response, err
15 16
 	}
... ...
@@ -19,8 +20,8 @@ func (cli *Client) ContainerExecCreate(config types.ExecConfig) (types.Container
19 19
 }
20 20
 
21 21
 // ContainerExecStart starts an exec process already create in the docker host.
22
-func (cli *Client) ContainerExecStart(execID string, config types.ExecStartCheck) error {
23
-	resp, err := cli.post("/exec/"+execID+"/start", nil, config, nil)
22
+func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error {
23
+	resp, err := cli.post(ctx, "/exec/"+execID+"/start", nil, config, nil)
24 24
 	ensureReaderClosed(resp)
25 25
 	return err
26 26
 }
... ...
@@ -29,15 +30,15 @@ func (cli *Client) ContainerExecStart(execID string, config types.ExecStartCheck
29 29
 // It returns a types.HijackedConnection with the hijacked connection
30 30
 // and the a reader to get output. It's up to the called to close
31 31
 // the hijacked connection by calling types.HijackedResponse.Close.
32
-func (cli *Client) ContainerExecAttach(execID string, config types.ExecConfig) (types.HijackedResponse, error) {
32
+func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config types.ExecConfig) (types.HijackedResponse, error) {
33 33
 	headers := map[string][]string{"Content-Type": {"application/json"}}
34
-	return cli.postHijacked("/exec/"+execID+"/start", nil, config, headers)
34
+	return cli.postHijacked(ctx, "/exec/"+execID+"/start", nil, config, headers)
35 35
 }
36 36
 
37 37
 // ContainerExecInspect returns information about a specific exec process on the docker host.
38
-func (cli *Client) ContainerExecInspect(execID string) (types.ContainerExecInspect, error) {
38
+func (cli *Client) ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error) {
39 39
 	var response types.ContainerExecInspect
40
-	resp, err := cli.get("/exec/"+execID+"/json", nil, nil)
40
+	resp, err := cli.get(ctx, "/exec/"+execID+"/json", nil, nil)
41 41
 	if err != nil {
42 42
 		return response, err
43 43
 	}
... ...
@@ -11,7 +11,7 @@ import (
11 11
 // and returns them as a io.ReadCloser. It's up to the caller
12 12
 // to close the stream.
13 13
 func (cli *Client) ContainerExport(ctx context.Context, containerID string) (io.ReadCloser, error) {
14
-	serverResp, err := cli.getWithContext(ctx, "/containers/"+containerID+"/export", url.Values{}, nil)
14
+	serverResp, err := cli.get(ctx, "/containers/"+containerID+"/export", url.Values{}, nil)
15 15
 	if err != nil {
16 16
 		return nil, err
17 17
 	}
... ...
@@ -8,11 +8,12 @@ import (
8 8
 	"net/url"
9 9
 
10 10
 	"github.com/docker/engine-api/types"
11
+	"golang.org/x/net/context"
11 12
 )
12 13
 
13 14
 // ContainerInspect returns the container information.
14
-func (cli *Client) ContainerInspect(containerID string) (types.ContainerJSON, error) {
15
-	serverResp, err := cli.get("/containers/"+containerID+"/json", nil, nil)
15
+func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) {
16
+	serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil)
16 17
 	if err != nil {
17 18
 		if serverResp.statusCode == http.StatusNotFound {
18 19
 			return types.ContainerJSON{}, containerNotFoundError{containerID}
... ...
@@ -27,12 +28,12 @@ func (cli *Client) ContainerInspect(containerID string) (types.ContainerJSON, er
27 27
 }
28 28
 
29 29
 // ContainerInspectWithRaw returns the container information and it's raw representation.
30
-func (cli *Client) ContainerInspectWithRaw(containerID string, getSize bool) (types.ContainerJSON, []byte, error) {
30
+func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool) (types.ContainerJSON, []byte, error) {
31 31
 	query := url.Values{}
32 32
 	if getSize {
33 33
 		query.Set("size", "1")
34 34
 	}
35
-	serverResp, err := cli.get("/containers/"+containerID+"/json", query, nil)
35
+	serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", query, nil)
36 36
 	if err != nil {
37 37
 		if serverResp.statusCode == http.StatusNotFound {
38 38
 			return types.ContainerJSON{}, nil, containerNotFoundError{containerID}
... ...
@@ -52,8 +53,8 @@ func (cli *Client) ContainerInspectWithRaw(containerID string, getSize bool) (ty
52 52
 	return response, body, err
53 53
 }
54 54
 
55
-func (cli *Client) containerInspectWithResponse(containerID string, query url.Values) (types.ContainerJSON, *serverResponse, error) {
56
-	serverResp, err := cli.get("/containers/"+containerID+"/json", nil, nil)
55
+func (cli *Client) containerInspectWithResponse(ctx context.Context, containerID string, query url.Values) (types.ContainerJSON, *serverResponse, error) {
56
+	serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil)
57 57
 	if err != nil {
58 58
 		return types.ContainerJSON{}, serverResp, err
59 59
 	}
... ...
@@ -1,13 +1,17 @@
1 1
 package client
2 2
 
3
-import "net/url"
3
+import (
4
+	"net/url"
5
+
6
+	"golang.org/x/net/context"
7
+)
4 8
 
5 9
 // ContainerKill terminates the container process but does not remove the container from the docker host.
6
-func (cli *Client) ContainerKill(containerID, signal string) error {
10
+func (cli *Client) ContainerKill(ctx context.Context, containerID, signal string) error {
7 11
 	query := url.Values{}
8 12
 	query.Set("signal", signal)
9 13
 
10
-	resp, err := cli.post("/containers/"+containerID+"/kill", query, nil, nil)
14
+	resp, err := cli.post(ctx, "/containers/"+containerID+"/kill", query, nil, nil)
11 15
 	ensureReaderClosed(resp)
12 16
 	return err
13 17
 }
... ...
@@ -7,10 +7,11 @@ import (
7 7
 
8 8
 	"github.com/docker/engine-api/types"
9 9
 	"github.com/docker/engine-api/types/filters"
10
+	"golang.org/x/net/context"
10 11
 )
11 12
 
12 13
 // ContainerList returns the list of containers in the docker host.
13
-func (cli *Client) ContainerList(options types.ContainerListOptions) ([]types.Container, error) {
14
+func (cli *Client) ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error) {
14 15
 	query := url.Values{}
15 16
 
16 17
 	if options.All {
... ...
@@ -42,7 +43,7 @@ func (cli *Client) ContainerList(options types.ContainerListOptions) ([]types.Co
42 42
 		query.Set("filters", filterJSON)
43 43
 	}
44 44
 
45
-	resp, err := cli.get("/containers/json", query, nil)
45
+	resp, err := cli.get(ctx, "/containers/json", query, nil)
46 46
 	if err != nil {
47 47
 		return nil, err
48 48
 	}
... ...
@@ -40,7 +40,7 @@ func (cli *Client) ContainerLogs(ctx context.Context, options types.ContainerLog
40 40
 	}
41 41
 	query.Set("tail", options.Tail)
42 42
 
43
-	resp, err := cli.getWithContext(ctx, "/containers/"+options.ContainerID+"/logs", query, nil)
43
+	resp, err := cli.get(ctx, "/containers/"+options.ContainerID+"/logs", query, nil)
44 44
 	if err != nil {
45 45
 		return nil, err
46 46
 	}
... ...
@@ -1,8 +1,10 @@
1 1
 package client
2 2
 
3
+import "golang.org/x/net/context"
4
+
3 5
 // ContainerPause pauses the main process of a given container without terminating it.
4
-func (cli *Client) ContainerPause(containerID string) error {
5
-	resp, err := cli.post("/containers/"+containerID+"/pause", nil, nil, nil)
6
+func (cli *Client) ContainerPause(ctx context.Context, containerID string) error {
7
+	resp, err := cli.post(ctx, "/containers/"+containerID+"/pause", nil, nil, nil)
6 8
 	ensureReaderClosed(resp)
7 9
 	return err
8 10
 }
... ...
@@ -4,10 +4,11 @@ import (
4 4
 	"net/url"
5 5
 
6 6
 	"github.com/docker/engine-api/types"
7
+	"golang.org/x/net/context"
7 8
 )
8 9
 
9 10
 // ContainerRemove kills and removes a container from the docker host.
10
-func (cli *Client) ContainerRemove(options types.ContainerRemoveOptions) error {
11
+func (cli *Client) ContainerRemove(ctx context.Context, options types.ContainerRemoveOptions) error {
11 12
 	query := url.Values{}
12 13
 	if options.RemoveVolumes {
13 14
 		query.Set("v", "1")
... ...
@@ -20,7 +21,7 @@ func (cli *Client) ContainerRemove(options types.ContainerRemoveOptions) error {
20 20
 		query.Set("force", "1")
21 21
 	}
22 22
 
23
-	resp, err := cli.delete("/containers/"+options.ContainerID, query, nil)
23
+	resp, err := cli.delete(ctx, "/containers/"+options.ContainerID, query, nil)
24 24
 	ensureReaderClosed(resp)
25 25
 	return err
26 26
 }
... ...
@@ -1,12 +1,16 @@
1 1
 package client
2 2
 
3
-import "net/url"
3
+import (
4
+	"net/url"
5
+
6
+	"golang.org/x/net/context"
7
+)
4 8
 
5 9
 // ContainerRename changes the name of a given container.
6
-func (cli *Client) ContainerRename(containerID, newContainerName string) error {
10
+func (cli *Client) ContainerRename(ctx context.Context, containerID, newContainerName string) error {
7 11
 	query := url.Values{}
8 12
 	query.Set("name", newContainerName)
9
-	resp, err := cli.post("/containers/"+containerID+"/rename", query, nil, nil)
13
+	resp, err := cli.post(ctx, "/containers/"+containerID+"/rename", query, nil, nil)
10 14
 	ensureReaderClosed(resp)
11 15
 	return err
12 16
 }
... ...
@@ -5,24 +5,25 @@ import (
5 5
 	"strconv"
6 6
 
7 7
 	"github.com/docker/engine-api/types"
8
+	"golang.org/x/net/context"
8 9
 )
9 10
 
10 11
 // ContainerResize changes the size of the tty for a container.
11
-func (cli *Client) ContainerResize(options types.ResizeOptions) error {
12
-	return cli.resize("/containers/"+options.ID, options.Height, options.Width)
12
+func (cli *Client) ContainerResize(ctx context.Context, options types.ResizeOptions) error {
13
+	return cli.resize(ctx, "/containers/"+options.ID, options.Height, options.Width)
13 14
 }
14 15
 
15 16
 // ContainerExecResize changes the size of the tty for an exec process running inside a container.
16
-func (cli *Client) ContainerExecResize(options types.ResizeOptions) error {
17
-	return cli.resize("/exec/"+options.ID, options.Height, options.Width)
17
+func (cli *Client) ContainerExecResize(ctx context.Context, options types.ResizeOptions) error {
18
+	return cli.resize(ctx, "/exec/"+options.ID, options.Height, options.Width)
18 19
 }
19 20
 
20
-func (cli *Client) resize(basePath string, height, width int) error {
21
+func (cli *Client) resize(ctx context.Context, basePath string, height, width int) error {
21 22
 	query := url.Values{}
22 23
 	query.Set("h", strconv.Itoa(height))
23 24
 	query.Set("w", strconv.Itoa(width))
24 25
 
25
-	resp, err := cli.post(basePath+"/resize", query, nil, nil)
26
+	resp, err := cli.post(ctx, basePath+"/resize", query, nil, nil)
26 27
 	ensureReaderClosed(resp)
27 28
 	return err
28 29
 }
... ...
@@ -3,15 +3,17 @@ package client
3 3
 import (
4 4
 	"net/url"
5 5
 	"strconv"
6
+
7
+	"golang.org/x/net/context"
6 8
 )
7 9
 
8 10
 // ContainerRestart stops and starts a container again.
9 11
 // It makes the daemon to wait for the container to be up again for
10 12
 // a specific amount of time, given the timeout.
11
-func (cli *Client) ContainerRestart(containerID string, timeout int) error {
13
+func (cli *Client) ContainerRestart(ctx context.Context, containerID string, timeout int) error {
12 14
 	query := url.Values{}
13 15
 	query.Set("t", strconv.Itoa(timeout))
14
-	resp, err := cli.post("/containers/"+containerID+"/restart", query, nil, nil)
16
+	resp, err := cli.post(ctx, "/containers/"+containerID+"/restart", query, nil, nil)
15 17
 	ensureReaderClosed(resp)
16 18
 	return err
17 19
 }
... ...
@@ -1,8 +1,10 @@
1 1
 package client
2 2
 
3
+import "golang.org/x/net/context"
4
+
3 5
 // ContainerStart sends a request to the docker daemon to start a container.
4
-func (cli *Client) ContainerStart(containerID string) error {
5
-	resp, err := cli.post("/containers/"+containerID+"/start", nil, nil, nil)
6
+func (cli *Client) ContainerStart(ctx context.Context, containerID string) error {
7
+	resp, err := cli.post(ctx, "/containers/"+containerID+"/start", nil, nil, nil)
6 8
 	ensureReaderClosed(resp)
7 9
 	return err
8 10
 }
... ...
@@ -16,7 +16,7 @@ func (cli *Client) ContainerStats(ctx context.Context, containerID string, strea
16 16
 		query.Set("stream", "1")
17 17
 	}
18 18
 
19
-	resp, err := cli.getWithContext(ctx, "/containers/"+containerID+"/stats", query, nil)
19
+	resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil)
20 20
 	if err != nil {
21 21
 		return nil, err
22 22
 	}
... ...
@@ -3,14 +3,16 @@ package client
3 3
 import (
4 4
 	"net/url"
5 5
 	"strconv"
6
+
7
+	"golang.org/x/net/context"
6 8
 )
7 9
 
8 10
 // ContainerStop stops a container without terminating the process.
9 11
 // The process is blocked until the container stops or the timeout expires.
10
-func (cli *Client) ContainerStop(containerID string, timeout int) error {
12
+func (cli *Client) ContainerStop(ctx context.Context, containerID string, timeout int) error {
11 13
 	query := url.Values{}
12 14
 	query.Set("t", strconv.Itoa(timeout))
13
-	resp, err := cli.post("/containers/"+containerID+"/stop", query, nil, nil)
15
+	resp, err := cli.post(ctx, "/containers/"+containerID+"/stop", query, nil, nil)
14 16
 	ensureReaderClosed(resp)
15 17
 	return err
16 18
 }
... ...
@@ -6,17 +6,18 @@ import (
6 6
 	"strings"
7 7
 
8 8
 	"github.com/docker/engine-api/types"
9
+	"golang.org/x/net/context"
9 10
 )
10 11
 
11 12
 // ContainerTop shows process information from within a container.
12
-func (cli *Client) ContainerTop(containerID string, arguments []string) (types.ContainerProcessList, error) {
13
+func (cli *Client) ContainerTop(ctx context.Context, containerID string, arguments []string) (types.ContainerProcessList, error) {
13 14
 	var response types.ContainerProcessList
14 15
 	query := url.Values{}
15 16
 	if len(arguments) > 0 {
16 17
 		query.Set("ps_args", strings.Join(arguments, " "))
17 18
 	}
18 19
 
19
-	resp, err := cli.get("/containers/"+containerID+"/top", query, nil)
20
+	resp, err := cli.get(ctx, "/containers/"+containerID+"/top", query, nil)
20 21
 	if err != nil {
21 22
 		return response, err
22 23
 	}
... ...
@@ -1,8 +1,10 @@
1 1
 package client
2 2
 
3
+import "golang.org/x/net/context"
4
+
3 5
 // ContainerUnpause resumes the process execution within a container
4
-func (cli *Client) ContainerUnpause(containerID string) error {
5
-	resp, err := cli.post("/containers/"+containerID+"/unpause", nil, nil, nil)
6
+func (cli *Client) ContainerUnpause(ctx context.Context, containerID string) error {
7
+	resp, err := cli.post(ctx, "/containers/"+containerID+"/unpause", nil, nil, nil)
6 8
 	ensureReaderClosed(resp)
7 9
 	return err
8 10
 }
... ...
@@ -2,11 +2,12 @@ package client
2 2
 
3 3
 import (
4 4
 	"github.com/docker/engine-api/types/container"
5
+	"golang.org/x/net/context"
5 6
 )
6 7
 
7 8
 // ContainerUpdate updates resources of a container
8
-func (cli *Client) ContainerUpdate(containerID string, updateConfig container.UpdateConfig) error {
9
-	resp, err := cli.post("/containers/"+containerID+"/update", nil, updateConfig, nil)
9
+func (cli *Client) ContainerUpdate(ctx context.Context, containerID string, updateConfig container.UpdateConfig) error {
10
+	resp, err := cli.post(ctx, "/containers/"+containerID+"/update", nil, updateConfig, nil)
10 11
 	ensureReaderClosed(resp)
11 12
 	return err
12 13
 }
... ...
@@ -11,7 +11,7 @@ import (
11 11
 // ContainerWait pauses execution util a container is exits.
12 12
 // It returns the API status code as response of its readiness.
13 13
 func (cli *Client) ContainerWait(ctx context.Context, containerID string) (int, error) {
14
-	resp, err := cli.postWithContext(ctx, "/containers/"+containerID+"/wait", nil, nil, nil)
14
+	resp, err := cli.post(ctx, "/containers/"+containerID+"/wait", nil, nil, nil)
15 15
 	if err != nil {
16 16
 		return -1, err
17 17
 	}
... ...
@@ -72,7 +72,7 @@ func (e volumeNotFoundError) Error() string {
72 72
 // IsErrVolumeNotFound returns true if the error is caused
73 73
 // when a volume is not found in the docker host.
74 74
 func IsErrVolumeNotFound(err error) bool {
75
-	_, ok := err.(networkNotFoundError)
75
+	_, ok := err.(volumeNotFoundError)
76 76
 	return ok
77 77
 }
78 78
 
... ...
@@ -40,7 +40,7 @@ func (cli *Client) Events(ctx context.Context, options types.EventsOptions) (io.
40 40
 		query.Set("filters", filterJSON)
41 41
 	}
42 42
 
43
-	serverResponse, err := cli.getWithContext(ctx, "/events", query, nil)
43
+	serverResponse, err := cli.get(ctx, "/events", query, nil)
44 44
 	if err != nil {
45 45
 		return nil, err
46 46
 	}
... ...
@@ -12,6 +12,7 @@ import (
12 12
 
13 13
 	"github.com/docker/engine-api/types"
14 14
 	"github.com/docker/go-connections/sockets"
15
+	"golang.org/x/net/context"
15 16
 )
16 17
 
17 18
 // tlsClientCon holds tls information and a dialed connection.
... ...
@@ -30,7 +31,7 @@ func (c *tlsClientCon) CloseWrite() error {
30 30
 }
31 31
 
32 32
 // postHijacked sends a POST request and hijacks the connection.
33
-func (cli *Client) postHijacked(path string, query url.Values, body interface{}, headers map[string][]string) (types.HijackedResponse, error) {
33
+func (cli *Client) postHijacked(ctx context.Context, path string, query url.Values, body interface{}, headers map[string][]string) (types.HijackedResponse, error) {
34 34
 	bodyEncoded, err := encodeData(body)
35 35
 	if err != nil {
36 36
 		return types.HijackedResponse{}, err
... ...
@@ -45,7 +46,8 @@ func (cli *Client) postHijacked(path string, query url.Values, body interface{},
45 45
 	req.Header.Set("Connection", "Upgrade")
46 46
 	req.Header.Set("Upgrade", "tcp")
47 47
 
48
-	conn, err := dial(cli.proto, cli.addr, cli.transport.TLSConfig())
48
+	tlsConfig := cli.transport.TLSConfig()
49
+	conn, err := dial(cli.proto, cli.addr, tlsConfig)
49 50
 	if err != nil {
50 51
 		if strings.Contains(err.Error(), "connection refused") {
51 52
 			return types.HijackedResponse{}, fmt.Errorf("Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?")
... ...
@@ -124,21 +126,6 @@ func tlsDialWithDialer(dialer *net.Dialer, network, addr string, config *tls.Con
124 124
 		tcpConn.SetKeepAlivePeriod(30 * time.Second)
125 125
 	}
126 126
 
127
-	colonPos := strings.LastIndex(addr, ":")
128
-	if colonPos == -1 {
129
-		colonPos = len(addr)
130
-	}
131
-	hostname := addr[:colonPos]
132
-
133
-	// If no ServerName is set, infer the ServerName
134
-	// from the hostname we're connecting to.
135
-	if config.ServerName == "" {
136
-		// Make a copy to avoid polluting argument or default.
137
-		c := *config
138
-		c.ServerName = hostname
139
-		config = &c
140
-	}
141
-
142 127
 	conn := tls.Client(rawConn, config)
143 128
 
144 129
 	if timeout == 0 {
... ...
@@ -24,5 +24,5 @@ func (cli *Client) ImageCreate(ctx context.Context, options types.ImageCreateOpt
24 24
 
25 25
 func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, registryAuth string) (*serverResponse, error) {
26 26
 	headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
27
-	return cli.postWithContext(ctx, "/images/create", query, nil, headers)
27
+	return cli.post(ctx, "/images/create", query, nil, headers)
28 28
 }
... ...
@@ -5,12 +5,13 @@ import (
5 5
 	"net/url"
6 6
 
7 7
 	"github.com/docker/engine-api/types"
8
+	"golang.org/x/net/context"
8 9
 )
9 10
 
10 11
 // ImageHistory returns the changes in an image in history format.
11
-func (cli *Client) ImageHistory(imageID string) ([]types.ImageHistory, error) {
12
+func (cli *Client) ImageHistory(ctx context.Context, imageID string) ([]types.ImageHistory, error) {
12 13
 	var history []types.ImageHistory
13
-	serverResp, err := cli.get("/images/"+imageID+"/history", url.Values{}, nil)
14
+	serverResp, err := cli.get(ctx, "/images/"+imageID+"/history", url.Values{}, nil)
14 15
 	if err != nil {
15 16
 		return history, err
16 17
 	}
... ...
@@ -8,15 +8,16 @@ import (
8 8
 	"net/url"
9 9
 
10 10
 	"github.com/docker/engine-api/types"
11
+	"golang.org/x/net/context"
11 12
 )
12 13
 
13 14
 // ImageInspectWithRaw returns the image information and it's raw representation.
14
-func (cli *Client) ImageInspectWithRaw(imageID string, getSize bool) (types.ImageInspect, []byte, error) {
15
+func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string, getSize bool) (types.ImageInspect, []byte, error) {
15 16
 	query := url.Values{}
16 17
 	if getSize {
17 18
 		query.Set("size", "1")
18 19
 	}
19
-	serverResp, err := cli.get("/images/"+imageID+"/json", query, nil)
20
+	serverResp, err := cli.get(ctx, "/images/"+imageID+"/json", query, nil)
20 21
 	if err != nil {
21 22
 		if serverResp.statusCode == http.StatusNotFound {
22 23
 			return types.ImageInspect{}, nil, imageNotFoundError{imageID}
... ...
@@ -6,10 +6,11 @@ import (
6 6
 
7 7
 	"github.com/docker/engine-api/types"
8 8
 	"github.com/docker/engine-api/types/filters"
9
+	"golang.org/x/net/context"
9 10
 )
10 11
 
11 12
 // ImageList returns a list of images in the docker host.
12
-func (cli *Client) ImageList(options types.ImageListOptions) ([]types.Image, error) {
13
+func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions) ([]types.Image, error) {
13 14
 	var images []types.Image
14 15
 	query := url.Values{}
15 16
 
... ...
@@ -28,7 +29,7 @@ func (cli *Client) ImageList(options types.ImageListOptions) ([]types.Image, err
28 28
 		query.Set("all", "1")
29 29
 	}
30 30
 
31
-	serverResp, err := cli.get("/images/json", query, nil)
31
+	serverResp, err := cli.get(ctx, "/images/json", query, nil)
32 32
 	if err != nil {
33 33
 		return images, err
34 34
 	}
... ...
@@ -34,5 +34,5 @@ func (cli *Client) ImagePush(ctx context.Context, options types.ImagePushOptions
34 34
 
35 35
 func (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.Values, registryAuth string) (*serverResponse, error) {
36 36
 	headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
37
-	return cli.postWithContext(ctx, "/images/"+imageID+"/push", query, nil, headers)
37
+	return cli.post(ctx, "/images/"+imageID+"/push", query, nil, headers)
38 38
 }
... ...
@@ -5,10 +5,11 @@ import (
5 5
 	"net/url"
6 6
 
7 7
 	"github.com/docker/engine-api/types"
8
+	"golang.org/x/net/context"
8 9
 )
9 10
 
10 11
 // ImageRemove removes an image from the docker host.
11
-func (cli *Client) ImageRemove(options types.ImageRemoveOptions) ([]types.ImageDelete, error) {
12
+func (cli *Client) ImageRemove(ctx context.Context, options types.ImageRemoveOptions) ([]types.ImageDelete, error) {
12 13
 	query := url.Values{}
13 14
 
14 15
 	if options.Force {
... ...
@@ -18,7 +19,7 @@ func (cli *Client) ImageRemove(options types.ImageRemoveOptions) ([]types.ImageD
18 18
 		query.Set("noprune", "1")
19 19
 	}
20 20
 
21
-	resp, err := cli.delete("/images/"+options.ImageID, query, nil)
21
+	resp, err := cli.delete(ctx, "/images/"+options.ImageID, query, nil)
22 22
 	if err != nil {
23 23
 		return nil, err
24 24
 	}
... ...
@@ -14,7 +14,7 @@ func (cli *Client) ImageSave(ctx context.Context, imageIDs []string) (io.ReadClo
14 14
 		"names": imageIDs,
15 15
 	}
16 16
 
17
-	resp, err := cli.getWithContext(ctx, "/images/get", query, nil)
17
+	resp, err := cli.get(ctx, "/images/get", query, nil)
18 18
 	if err != nil {
19 19
 		return nil, err
20 20
 	}
... ...
@@ -7,22 +7,23 @@ import (
7 7
 
8 8
 	"github.com/docker/engine-api/types"
9 9
 	"github.com/docker/engine-api/types/registry"
10
+	"golang.org/x/net/context"
10 11
 )
11 12
 
12 13
 // ImageSearch makes the docker host to search by a term in a remote registry.
13 14
 // The list of results is not sorted in any fashion.
14
-func (cli *Client) ImageSearch(options types.ImageSearchOptions, privilegeFunc RequestPrivilegeFunc) ([]registry.SearchResult, error) {
15
+func (cli *Client) ImageSearch(ctx context.Context, options types.ImageSearchOptions, privilegeFunc RequestPrivilegeFunc) ([]registry.SearchResult, error) {
15 16
 	var results []registry.SearchResult
16 17
 	query := url.Values{}
17 18
 	query.Set("term", options.Term)
18 19
 
19
-	resp, err := cli.tryImageSearch(query, options.RegistryAuth)
20
+	resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth)
20 21
 	if resp.statusCode == http.StatusUnauthorized {
21 22
 		newAuthHeader, privilegeErr := privilegeFunc()
22 23
 		if privilegeErr != nil {
23 24
 			return results, privilegeErr
24 25
 		}
25
-		resp, err = cli.tryImageSearch(query, newAuthHeader)
26
+		resp, err = cli.tryImageSearch(ctx, query, newAuthHeader)
26 27
 	}
27 28
 	if err != nil {
28 29
 		return results, err
... ...
@@ -33,7 +34,7 @@ func (cli *Client) ImageSearch(options types.ImageSearchOptions, privilegeFunc R
33 33
 	return results, err
34 34
 }
35 35
 
36
-func (cli *Client) tryImageSearch(query url.Values, registryAuth string) (*serverResponse, error) {
36
+func (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (*serverResponse, error) {
37 37
 	headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
38
-	return cli.get("/images/search", query, headers)
38
+	return cli.get(ctx, "/images/search", query, headers)
39 39
 }
... ...
@@ -4,10 +4,11 @@ import (
4 4
 	"net/url"
5 5
 
6 6
 	"github.com/docker/engine-api/types"
7
+	"golang.org/x/net/context"
7 8
 )
8 9
 
9 10
 // ImageTag tags an image in the docker host
10
-func (cli *Client) ImageTag(options types.ImageTagOptions) error {
11
+func (cli *Client) ImageTag(ctx context.Context, options types.ImageTagOptions) error {
11 12
 	query := url.Values{}
12 13
 	query.Set("repo", options.RepositoryName)
13 14
 	query.Set("tag", options.Tag)
... ...
@@ -15,7 +16,7 @@ func (cli *Client) ImageTag(options types.ImageTagOptions) error {
15 15
 		query.Set("force", "1")
16 16
 	}
17 17
 
18
-	resp, err := cli.post("/images/"+options.ImageID+"/tag", query, nil, nil)
18
+	resp, err := cli.post(ctx, "/images/"+options.ImageID+"/tag", query, nil, nil)
19 19
 	ensureReaderClosed(resp)
20 20
 	return err
21 21
 }
... ...
@@ -6,12 +6,13 @@ import (
6 6
 	"net/url"
7 7
 
8 8
 	"github.com/docker/engine-api/types"
9
+	"golang.org/x/net/context"
9 10
 )
10 11
 
11 12
 // Info returns information about the docker server.
12
-func (cli *Client) Info() (types.Info, error) {
13
+func (cli *Client) Info(ctx context.Context) (types.Info, error) {
13 14
 	var info types.Info
14
-	serverResp, err := cli.get("/info", url.Values{}, nil)
15
+	serverResp, err := cli.get(ctx, "/info", url.Values{}, nil)
15 16
 	if err != nil {
16 17
 		return info, err
17 18
 	}
... ...
@@ -15,63 +15,63 @@ import (
15 15
 // APIClient is an interface that clients that talk with a docker server must implement.
16 16
 type APIClient interface {
17 17
 	ClientVersion() string
18
-	ContainerAttach(options types.ContainerAttachOptions) (types.HijackedResponse, error)
19
-	ContainerCommit(options types.ContainerCommitOptions) (types.ContainerCommitResponse, error)
20
-	ContainerCreate(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (types.ContainerCreateResponse, error)
21
-	ContainerDiff(containerID string) ([]types.ContainerChange, error)
22
-	ContainerExecAttach(execID string, config types.ExecConfig) (types.HijackedResponse, error)
23
-	ContainerExecCreate(config types.ExecConfig) (types.ContainerExecCreateResponse, error)
24
-	ContainerExecInspect(execID string) (types.ContainerExecInspect, error)
25
-	ContainerExecResize(options types.ResizeOptions) error
26
-	ContainerExecStart(execID string, config types.ExecStartCheck) error
18
+	ContainerAttach(ctx context.Context, options types.ContainerAttachOptions) (types.HijackedResponse, error)
19
+	ContainerCommit(ctx context.Context, options types.ContainerCommitOptions) (types.ContainerCommitResponse, error)
20
+	ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (types.ContainerCreateResponse, error)
21
+	ContainerDiff(ctx context.Context, ontainerID string) ([]types.ContainerChange, error)
22
+	ContainerExecAttach(ctx context.Context, execID string, config types.ExecConfig) (types.HijackedResponse, error)
23
+	ContainerExecCreate(ctx context.Context, config types.ExecConfig) (types.ContainerExecCreateResponse, error)
24
+	ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error)
25
+	ContainerExecResize(ctx context.Context, options types.ResizeOptions) error
26
+	ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error
27 27
 	ContainerExport(ctx context.Context, containerID string) (io.ReadCloser, error)
28
-	ContainerInspect(containerID string) (types.ContainerJSON, error)
29
-	ContainerInspectWithRaw(containerID string, getSize bool) (types.ContainerJSON, []byte, error)
30
-	ContainerKill(containerID, signal string) error
31
-	ContainerList(options types.ContainerListOptions) ([]types.Container, error)
28
+	ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error)
29
+	ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool) (types.ContainerJSON, []byte, error)
30
+	ContainerKill(ctx context.Context, containerID, signal string) error
31
+	ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error)
32 32
 	ContainerLogs(ctx context.Context, options types.ContainerLogsOptions) (io.ReadCloser, error)
33
-	ContainerPause(containerID string) error
34
-	ContainerRemove(options types.ContainerRemoveOptions) error
35
-	ContainerRename(containerID, newContainerName string) error
36
-	ContainerResize(options types.ResizeOptions) error
37
-	ContainerRestart(containerID string, timeout int) error
38
-	ContainerStatPath(containerID, path string) (types.ContainerPathStat, error)
33
+	ContainerPause(ctx context.Context, containerID string) error
34
+	ContainerRemove(ctx context.Context, options types.ContainerRemoveOptions) error
35
+	ContainerRename(ctx context.Context, containerID, newContainerName string) error
36
+	ContainerResize(ctx context.Context, options types.ResizeOptions) error
37
+	ContainerRestart(ctx context.Context, containerID string, timeout int) error
38
+	ContainerStatPath(ctx context.Context, containerID, path string) (types.ContainerPathStat, error)
39 39
 	ContainerStats(ctx context.Context, containerID string, stream bool) (io.ReadCloser, error)
40
-	ContainerStart(containerID string) error
41
-	ContainerStop(containerID string, timeout int) error
42
-	ContainerTop(containerID string, arguments []string) (types.ContainerProcessList, error)
43
-	ContainerUnpause(containerID string) error
44
-	ContainerUpdate(containerID string, updateConfig container.UpdateConfig) error
40
+	ContainerStart(ctx context.Context, containerID string) error
41
+	ContainerStop(ctx context.Context, containerID string, timeout int) error
42
+	ContainerTop(ctx context.Context, containerID string, arguments []string) (types.ContainerProcessList, error)
43
+	ContainerUnpause(ctx context.Context, containerID string) error
44
+	ContainerUpdate(ctx context.Context, containerID string, updateConfig container.UpdateConfig) error
45 45
 	ContainerWait(ctx context.Context, containerID string) (int, error)
46 46
 	CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error)
47 47
 	CopyToContainer(ctx context.Context, options types.CopyToContainerOptions) error
48 48
 	Events(ctx context.Context, options types.EventsOptions) (io.ReadCloser, error)
49 49
 	ImageBuild(ctx context.Context, options types.ImageBuildOptions) (types.ImageBuildResponse, error)
50 50
 	ImageCreate(ctx context.Context, options types.ImageCreateOptions) (io.ReadCloser, error)
51
-	ImageHistory(imageID string) ([]types.ImageHistory, error)
51
+	ImageHistory(ctx context.Context, imageID string) ([]types.ImageHistory, error)
52 52
 	ImageImport(ctx context.Context, options types.ImageImportOptions) (io.ReadCloser, error)
53
-	ImageInspectWithRaw(imageID string, getSize bool) (types.ImageInspect, []byte, error)
54
-	ImageList(options types.ImageListOptions) ([]types.Image, error)
53
+	ImageInspectWithRaw(ctx context.Context, imageID string, getSize bool) (types.ImageInspect, []byte, error)
54
+	ImageList(ctx context.Context, options types.ImageListOptions) ([]types.Image, error)
55 55
 	ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error)
56 56
 	ImagePull(ctx context.Context, options types.ImagePullOptions, privilegeFunc RequestPrivilegeFunc) (io.ReadCloser, error)
57 57
 	ImagePush(ctx context.Context, options types.ImagePushOptions, privilegeFunc RequestPrivilegeFunc) (io.ReadCloser, error)
58
-	ImageRemove(options types.ImageRemoveOptions) ([]types.ImageDelete, error)
59
-	ImageSearch(options types.ImageSearchOptions, privilegeFunc RequestPrivilegeFunc) ([]registry.SearchResult, error)
58
+	ImageRemove(ctx context.Context, options types.ImageRemoveOptions) ([]types.ImageDelete, error)
59
+	ImageSearch(ctx context.Context, options types.ImageSearchOptions, privilegeFunc RequestPrivilegeFunc) ([]registry.SearchResult, error)
60 60
 	ImageSave(ctx context.Context, imageIDs []string) (io.ReadCloser, error)
61
-	ImageTag(options types.ImageTagOptions) error
62
-	Info() (types.Info, error)
63
-	NetworkConnect(networkID, containerID string, config *network.EndpointSettings) error
64
-	NetworkCreate(options types.NetworkCreate) (types.NetworkCreateResponse, error)
65
-	NetworkDisconnect(networkID, containerID string, force bool) error
66
-	NetworkInspect(networkID string) (types.NetworkResource, error)
67
-	NetworkList(options types.NetworkListOptions) ([]types.NetworkResource, error)
68
-	NetworkRemove(networkID string) error
69
-	RegistryLogin(auth types.AuthConfig) (types.AuthResponse, error)
70
-	ServerVersion() (types.Version, error)
71
-	VolumeCreate(options types.VolumeCreateRequest) (types.Volume, error)
72
-	VolumeInspect(volumeID string) (types.Volume, error)
73
-	VolumeList(filter filters.Args) (types.VolumesListResponse, error)
74
-	VolumeRemove(volumeID string) error
61
+	ImageTag(ctx context.Context, options types.ImageTagOptions) error
62
+	Info(ctx context.Context) (types.Info, error)
63
+	NetworkConnect(ctx context.Context, networkID, containerID string, config *network.EndpointSettings) error
64
+	NetworkCreate(ctx context.Context, options types.NetworkCreate) (types.NetworkCreateResponse, error)
65
+	NetworkDisconnect(ctx context.Context, networkID, containerID string, force bool) error
66
+	NetworkInspect(ctx context.Context, networkID string) (types.NetworkResource, error)
67
+	NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error)
68
+	NetworkRemove(ctx context.Context, networkID string) error
69
+	RegistryLogin(ctx context.Context, auth types.AuthConfig) (types.AuthResponse, error)
70
+	ServerVersion(ctx context.Context) (types.Version, error)
71
+	VolumeCreate(ctx context.Context, options types.VolumeCreateRequest) (types.Volume, error)
72
+	VolumeInspect(ctx context.Context, volumeID string) (types.Volume, error)
73
+	VolumeList(ctx context.Context, filter filters.Args) (types.VolumesListResponse, error)
74
+	VolumeRemove(ctx context.Context, volumeID string) error
75 75
 }
76 76
 
77 77
 // Ensure that Client always implements APIClient.
... ...
@@ -6,12 +6,13 @@ import (
6 6
 	"net/url"
7 7
 
8 8
 	"github.com/docker/engine-api/types"
9
+	"golang.org/x/net/context"
9 10
 )
10 11
 
11 12
 // RegistryLogin authenticates the docker server with a given docker registry.
12 13
 // It returns UnauthorizerError when the authentication fails.
13
-func (cli *Client) RegistryLogin(auth types.AuthConfig) (types.AuthResponse, error) {
14
-	resp, err := cli.post("/auth", url.Values{}, auth, nil)
14
+func (cli *Client) RegistryLogin(ctx context.Context, auth types.AuthConfig) (types.AuthResponse, error) {
15
+	resp, err := cli.post(ctx, "/auth", url.Values{}, auth, nil)
15 16
 
16 17
 	if resp != nil && resp.statusCode == http.StatusUnauthorized {
17 18
 		return types.AuthResponse{}, unauthorizedError{err}
... ...
@@ -3,15 +3,16 @@ package client
3 3
 import (
4 4
 	"github.com/docker/engine-api/types"
5 5
 	"github.com/docker/engine-api/types/network"
6
+	"golang.org/x/net/context"
6 7
 )
7 8
 
8 9
 // NetworkConnect connects a container to an existent network in the docker host.
9
-func (cli *Client) NetworkConnect(networkID, containerID string, config *network.EndpointSettings) error {
10
+func (cli *Client) NetworkConnect(ctx context.Context, networkID, containerID string, config *network.EndpointSettings) error {
10 11
 	nc := types.NetworkConnect{
11 12
 		Container:      containerID,
12 13
 		EndpointConfig: config,
13 14
 	}
14
-	resp, err := cli.post("/networks/"+networkID+"/connect", nil, nc, nil)
15
+	resp, err := cli.post(ctx, "/networks/"+networkID+"/connect", nil, nc, nil)
15 16
 	ensureReaderClosed(resp)
16 17
 	return err
17 18
 }
... ...
@@ -4,12 +4,13 @@ import (
4 4
 	"encoding/json"
5 5
 
6 6
 	"github.com/docker/engine-api/types"
7
+	"golang.org/x/net/context"
7 8
 )
8 9
 
9 10
 // NetworkCreate creates a new network in the docker host.
10
-func (cli *Client) NetworkCreate(options types.NetworkCreate) (types.NetworkCreateResponse, error) {
11
+func (cli *Client) NetworkCreate(ctx context.Context, options types.NetworkCreate) (types.NetworkCreateResponse, error) {
11 12
 	var response types.NetworkCreateResponse
12
-	serverResp, err := cli.post("/networks/create", nil, options, nil)
13
+	serverResp, err := cli.post(ctx, "/networks/create", nil, options, nil)
13 14
 	if err != nil {
14 15
 		return response, err
15 16
 	}
... ...
@@ -2,12 +2,13 @@ package client
2 2
 
3 3
 import (
4 4
 	"github.com/docker/engine-api/types"
5
+	"golang.org/x/net/context"
5 6
 )
6 7
 
7 8
 // NetworkDisconnect disconnects a container from an existent network in the docker host.
8
-func (cli *Client) NetworkDisconnect(networkID, containerID string, force bool) error {
9
+func (cli *Client) NetworkDisconnect(ctx context.Context, networkID, containerID string, force bool) error {
9 10
 	nd := types.NetworkDisconnect{Container: containerID, Force: force}
10
-	resp, err := cli.post("/networks/"+networkID+"/disconnect", nil, nd, nil)
11
+	resp, err := cli.post(ctx, "/networks/"+networkID+"/disconnect", nil, nd, nil)
11 12
 	ensureReaderClosed(resp)
12 13
 	return err
13 14
 }
... ...
@@ -5,12 +5,13 @@ import (
5 5
 	"net/http"
6 6
 
7 7
 	"github.com/docker/engine-api/types"
8
+	"golang.org/x/net/context"
8 9
 )
9 10
 
10 11
 // NetworkInspect returns the information for a specific network configured in the docker host.
11
-func (cli *Client) NetworkInspect(networkID string) (types.NetworkResource, error) {
12
+func (cli *Client) NetworkInspect(ctx context.Context, networkID string) (types.NetworkResource, error) {
12 13
 	var networkResource types.NetworkResource
13
-	resp, err := cli.get("/networks/"+networkID, nil, nil)
14
+	resp, err := cli.get(ctx, "/networks/"+networkID, nil, nil)
14 15
 	if err != nil {
15 16
 		if resp.statusCode == http.StatusNotFound {
16 17
 			return networkResource, networkNotFoundError{networkID}
... ...
@@ -6,10 +6,11 @@ import (
6 6
 
7 7
 	"github.com/docker/engine-api/types"
8 8
 	"github.com/docker/engine-api/types/filters"
9
+	"golang.org/x/net/context"
9 10
 )
10 11
 
11 12
 // NetworkList returns the list of networks configured in the docker host.
12
-func (cli *Client) NetworkList(options types.NetworkListOptions) ([]types.NetworkResource, error) {
13
+func (cli *Client) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
13 14
 	query := url.Values{}
14 15
 	if options.Filters.Len() > 0 {
15 16
 		filterJSON, err := filters.ToParam(options.Filters)
... ...
@@ -20,7 +21,7 @@ func (cli *Client) NetworkList(options types.NetworkListOptions) ([]types.Networ
20 20
 		query.Set("filters", filterJSON)
21 21
 	}
22 22
 	var networkResources []types.NetworkResource
23
-	resp, err := cli.get("/networks", query, nil)
23
+	resp, err := cli.get(ctx, "/networks", query, nil)
24 24
 	if err != nil {
25 25
 		return networkResources, err
26 26
 	}
... ...
@@ -1,8 +1,10 @@
1 1
 package client
2 2
 
3
+import "golang.org/x/net/context"
4
+
3 5
 // NetworkRemove removes an existent network from the docker host.
4
-func (cli *Client) NetworkRemove(networkID string) error {
5
-	resp, err := cli.delete("/networks/"+networkID, nil, nil)
6
+func (cli *Client) NetworkRemove(ctx context.Context, networkID string) error {
7
+	resp, err := cli.delete(ctx, "/networks/"+networkID, nil, nil)
6 8
 	ensureReaderClosed(resp)
7 9
 	return err
8 10
 }
... ...
@@ -11,7 +11,6 @@ import (
11 11
 	"strings"
12 12
 
13 13
 	"github.com/docker/engine-api/client/transport/cancellable"
14
-
15 14
 	"golang.org/x/net/context"
16 15
 )
17 16
 
... ...
@@ -23,57 +22,41 @@ type serverResponse struct {
23 23
 }
24 24
 
25 25
 // head sends an http request to the docker API using the method HEAD.
26
-func (cli *Client) head(path string, query url.Values, headers map[string][]string) (*serverResponse, error) {
27
-	return cli.sendRequest(context.Background(), "HEAD", path, query, nil, headers)
28
-}
29
-
30
-// get sends an http request to the docker API using the method GET.
31
-func (cli *Client) get(path string, query url.Values, headers map[string][]string) (*serverResponse, error) {
32
-	return cli.getWithContext(context.Background(), path, query, headers)
26
+func (cli *Client) head(ctx context.Context, path string, query url.Values, headers map[string][]string) (*serverResponse, error) {
27
+	return cli.sendRequest(ctx, "HEAD", path, query, nil, headers)
33 28
 }
34 29
 
35 30
 // getWithContext sends an http request to the docker API using the method GET with a specific go context.
36
-func (cli *Client) getWithContext(ctx context.Context, path string, query url.Values, headers map[string][]string) (*serverResponse, error) {
31
+func (cli *Client) get(ctx context.Context, path string, query url.Values, headers map[string][]string) (*serverResponse, error) {
37 32
 	return cli.sendRequest(ctx, "GET", path, query, nil, headers)
38 33
 }
39 34
 
40
-// post sends an http request to the docker API using the method POST.
41
-func (cli *Client) post(path string, query url.Values, body interface{}, headers map[string][]string) (*serverResponse, error) {
42
-	return cli.postWithContext(context.Background(), path, query, body, headers)
43
-}
44
-
45 35
 // postWithContext sends an http request to the docker API using the method POST with a specific go context.
46
-func (cli *Client) postWithContext(ctx context.Context, path string, query url.Values, body interface{}, headers map[string][]string) (*serverResponse, error) {
47
-	return cli.sendRequest(ctx, "POST", path, query, body, headers)
36
+func (cli *Client) post(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (*serverResponse, error) {
37
+	return cli.sendRequest(ctx, "POST", path, query, obj, headers)
48 38
 }
49 39
 
50
-// postRaw sends the raw input to the docker API using the method POST with a specific go context.
51 40
 func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (*serverResponse, error) {
52 41
 	return cli.sendClientRequest(ctx, "POST", path, query, body, headers)
53 42
 }
54 43
 
55 44
 // put sends an http request to the docker API using the method PUT.
56
-func (cli *Client) put(path string, query url.Values, body interface{}, headers map[string][]string) (*serverResponse, error) {
57
-	return cli.sendRequest(context.Background(), "PUT", path, query, body, headers)
58
-}
59
-
60
-// putRaw sends the raw input to the docker API using the method PUT.
61
-func (cli *Client) putRaw(path string, query url.Values, body io.Reader, headers map[string][]string) (*serverResponse, error) {
62
-	return cli.putRawWithContext(context.Background(), path, query, body, headers)
45
+func (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (*serverResponse, error) {
46
+	return cli.sendRequest(ctx, "PUT", path, query, obj, headers)
63 47
 }
64 48
 
65
-// putRawWithContext sends the raw input to the docker API using the method PUT with a specific go context.
66
-func (cli *Client) putRawWithContext(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (*serverResponse, error) {
49
+// put sends an http request to the docker API using the method PUT.
50
+func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (*serverResponse, error) {
67 51
 	return cli.sendClientRequest(ctx, "PUT", path, query, body, headers)
68 52
 }
69 53
 
70 54
 // delete sends an http request to the docker API using the method DELETE.
71
-func (cli *Client) delete(path string, query url.Values, headers map[string][]string) (*serverResponse, error) {
72
-	return cli.sendRequest(context.Background(), "DELETE", path, query, nil, headers)
55
+func (cli *Client) delete(ctx context.Context, path string, query url.Values, headers map[string][]string) (*serverResponse, error) {
56
+	return cli.sendRequest(ctx, "DELETE", path, query, nil, headers)
73 57
 }
74 58
 
75
-func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, body interface{}, headers map[string][]string) (*serverResponse, error) {
76
-	params, err := encodeData(body)
59
+func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, obj interface{}, headers map[string][]string) (*serverResponse, error) {
60
+	body, err := encodeData(obj)
77 61
 	if err != nil {
78 62
 		return nil, err
79 63
 	}
... ...
@@ -85,7 +68,7 @@ func (cli *Client) sendRequest(ctx context.Context, method, path string, query u
85 85
 		headers["Content-Type"] = []string{"application/json"}
86 86
 	}
87 87
 
88
-	return cli.sendClientRequest(ctx, method, path, query, params, headers)
88
+	return cli.sendClientRequest(ctx, method, path, query, body, headers)
89 89
 }
90 90
 
91 91
 func (cli *Client) sendClientRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers map[string][]string) (*serverResponse, error) {
... ...
@@ -4,6 +4,7 @@ package transport
4 4
 import (
5 5
 	"fmt"
6 6
 	"net/http"
7
+	"strings"
7 8
 
8 9
 	"github.com/docker/go-connections/sockets"
9 10
 )
... ...
@@ -34,6 +35,10 @@ func NewTransportWithHTTP(proto, addr string, client *http.Client) (Client, erro
34 34
 		}
35 35
 	}
36 36
 
37
+	if transport.TLSClientConfig != nil && transport.TLSClientConfig.ServerName == "" {
38
+		transport.TLSClientConfig.ServerName = hostname(addr)
39
+	}
40
+
37 41
 	return &apiTransport{
38 42
 		Client:    client,
39 43
 		tlsInfo:   &tlsInfo{transport.TLSClientConfig},
... ...
@@ -54,4 +59,12 @@ func defaultTransport(proto, addr string) *http.Transport {
54 54
 	return tr
55 55
 }
56 56
 
57
+func hostname(addr string) string {
58
+	colonPos := strings.LastIndex(addr, ":")
59
+	if colonPos == -1 {
60
+		return addr
61
+	}
62
+	return addr[:colonPos]
63
+}
64
+
57 65
 var _ Client = &apiTransport{}
... ...
@@ -4,11 +4,12 @@ import (
4 4
 	"encoding/json"
5 5
 
6 6
 	"github.com/docker/engine-api/types"
7
+	"golang.org/x/net/context"
7 8
 )
8 9
 
9 10
 // ServerVersion returns information of the docker client and server host.
10
-func (cli *Client) ServerVersion() (types.Version, error) {
11
-	resp, err := cli.get("/version", nil, nil)
11
+func (cli *Client) ServerVersion(ctx context.Context) (types.Version, error) {
12
+	resp, err := cli.get(ctx, "/version", nil, nil)
12 13
 	if err != nil {
13 14
 		return types.Version{}, err
14 15
 	}
... ...
@@ -4,12 +4,13 @@ import (
4 4
 	"encoding/json"
5 5
 
6 6
 	"github.com/docker/engine-api/types"
7
+	"golang.org/x/net/context"
7 8
 )
8 9
 
9 10
 // VolumeCreate creates a volume in the docker host.
10
-func (cli *Client) VolumeCreate(options types.VolumeCreateRequest) (types.Volume, error) {
11
+func (cli *Client) VolumeCreate(ctx context.Context, options types.VolumeCreateRequest) (types.Volume, error) {
11 12
 	var volume types.Volume
12
-	resp, err := cli.post("/volumes/create", nil, options, nil)
13
+	resp, err := cli.post(ctx, "/volumes/create", nil, options, nil)
13 14
 	if err != nil {
14 15
 		return volume, err
15 16
 	}
... ...
@@ -5,12 +5,13 @@ import (
5 5
 	"net/http"
6 6
 
7 7
 	"github.com/docker/engine-api/types"
8
+	"golang.org/x/net/context"
8 9
 )
9 10
 
10 11
 // VolumeInspect returns the information about a specific volume in the docker host.
11
-func (cli *Client) VolumeInspect(volumeID string) (types.Volume, error) {
12
+func (cli *Client) VolumeInspect(ctx context.Context, volumeID string) (types.Volume, error) {
12 13
 	var volume types.Volume
13
-	resp, err := cli.get("/volumes/"+volumeID, nil, nil)
14
+	resp, err := cli.get(ctx, "/volumes/"+volumeID, nil, nil)
14 15
 	if err != nil {
15 16
 		if resp.statusCode == http.StatusNotFound {
16 17
 			return volume, volumeNotFoundError{volumeID}
... ...
@@ -6,10 +6,11 @@ import (
6 6
 
7 7
 	"github.com/docker/engine-api/types"
8 8
 	"github.com/docker/engine-api/types/filters"
9
+	"golang.org/x/net/context"
9 10
 )
10 11
 
11 12
 // VolumeList returns the volumes configured in the docker host.
12
-func (cli *Client) VolumeList(filter filters.Args) (types.VolumesListResponse, error) {
13
+func (cli *Client) VolumeList(ctx context.Context, filter filters.Args) (types.VolumesListResponse, error) {
13 14
 	var volumes types.VolumesListResponse
14 15
 	query := url.Values{}
15 16
 
... ...
@@ -20,7 +21,7 @@ func (cli *Client) VolumeList(filter filters.Args) (types.VolumesListResponse, e
20 20
 		}
21 21
 		query.Set("filters", filterJSON)
22 22
 	}
23
-	resp, err := cli.get("/volumes", query, nil)
23
+	resp, err := cli.get(ctx, "/volumes", query, nil)
24 24
 	if err != nil {
25 25
 		return volumes, err
26 26
 	}
... ...
@@ -1,8 +1,10 @@
1 1
 package client
2 2
 
3
+import "golang.org/x/net/context"
4
+
3 5
 // VolumeRemove removes a volume from the docker host.
4
-func (cli *Client) VolumeRemove(volumeID string) error {
5
-	resp, err := cli.delete("/volumes/"+volumeID, nil, nil)
6
+func (cli *Client) VolumeRemove(ctx context.Context, volumeID string) error {
7
+	resp, err := cli.delete(ctx, "/volumes/"+volumeID, nil, nil)
6 8
 	ensureReaderClosed(resp)
7 9
 	return err
8 10
 }
... ...
@@ -89,6 +89,27 @@ func (n UsernsMode) Valid() bool {
89 89
 	return true
90 90
 }
91 91
 
92
+// Cgroup Spec represents the cgroup to use for the container.
93
+type CgroupSpec string
94
+
95
+func (c CgroupSpec) IsContainer() bool {
96
+	parts := strings.SplitN(string(c), ":", 2)
97
+	return len(parts) > 1 && parts[0] == "container"
98
+}
99
+
100
+func (c CgroupSpec) Valid() bool {
101
+	return c.IsContainer() || c == ""
102
+}
103
+
104
+// Container returns the name of the container whose cgroup will be used.
105
+func (c CgroupSpec) Container() string {
106
+	parts := strings.SplitN(string(c), ":", 2)
107
+	if len(parts) > 1 {
108
+		return parts[1]
109
+	}
110
+	return ""
111
+}
112
+
92 113
 // UTSMode represents the UTS namespace of the container.
93 114
 type UTSMode string
94 115
 
... ...
@@ -215,6 +236,8 @@ type Resources struct {
215 215
 	Ulimits              []*units.Ulimit // List of ulimits to be set in the container
216 216
 
217 217
 	// Applicable to Windows
218
+	CPUCount    int64  `json:"CpuCount"`   // CPU count
219
+	CPUPercent  int64  `json:"CpuPercent"` // CPU percent
218 220
 	BlkioIOps   uint64 // Maximum IOps for the container system drive
219 221
 	BlkioBps    uint64 // Maximum Bytes per second for the container system drive
220 222
 	SandboxSize uint64 // System drive will be expanded to at least this size (in bytes)
... ...
@@ -252,6 +275,7 @@ type HostConfig struct {
252 252
 	ExtraHosts      []string          // List of extra hosts
253 253
 	GroupAdd        []string          // List of additional groups that the container process will run as
254 254
 	IpcMode         IpcMode           // IPC namespace to use for the container
255
+	Cgroup          CgroupSpec        // Cgroup to use for the container
255 256
 	Links           []string          // List of links (in the name:alias form)
256 257
 	OomScoreAdj     int               // Container preference for OOM-killing
257 258
 	PidMode         PidMode           // PID namespace to use for the container
... ...
@@ -259,7 +283,7 @@ type HostConfig struct {
259 259
 	PublishAllPorts bool              // Should docker publish all exposed port for the container
260 260
 	ReadonlyRootfs  bool              // Is the container root filesystem in read-only
261 261
 	SecurityOpt     []string          // List of string values to customize labels for MLS systems, such as SELinux.
262
-	StorageOpt      []string          // Storage driver options per container.
262
+	StorageOpt      map[string]string // Storage driver options per container.
263 263
 	Tmpfs           map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container
264 264
 	UTSMode         UTSMode           // UTS namespace to use for the container
265 265
 	UsernsMode      UsernsMode        // The user namespace to use for the container