From e5d5e1b581bb7689f8837106803b36ce39c05bd5 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Wed, 13 Apr 2016 10:33:35 +0200 Subject: [PATCH 1/2] Vendor engine-api with required arguments Signed-off-by: Vincent Demeester Upstream-commit: 9802d7d10f0cfbd74bc129c01f96e183b9743766 Component: engine --- components/engine/hack/vendor.sh | 2 +- .../docker/engine-api/client/client.go | 6 ++ .../engine-api/client/container_attach.go | 4 +- .../engine-api/client/container_commit.go | 26 +++++- .../engine-api/client/container_exec.go | 4 +- .../engine-api/client/container_list.go | 3 +- .../engine-api/client/container_logs.go | 4 +- .../engine-api/client/container_remove.go | 4 +- .../engine-api/client/container_resize.go | 8 +- .../docker/engine-api/client/image_build.go | 5 +- .../docker/engine-api/client/image_create.go | 12 ++- .../docker/engine-api/client/image_import.go | 16 +++- .../docker/engine-api/client/image_pull.go | 20 +++-- .../docker/engine-api/client/image_push.go | 26 ++++-- .../docker/engine-api/client/image_remove.go | 4 +- .../docker/engine-api/client/image_search.go | 6 +- .../docker/engine-api/client/image_tag.go | 26 ++++-- .../docker/engine-api/client/interface.go | 77 +++++++++--------- .../engine-api/client/network_create.go | 8 +- .../docker/engine-api/client/privileged.go | 8 -- .../docker/engine-api/client/request.go | 12 +-- .../docker/engine-api/types/client.go | 80 +++++++++---------- .../docker/engine-api/types/configs.go | 1 - .../engine-api/types/container/config.go | 1 - .../engine-api/types/container/host_config.go | 2 + .../docker/engine-api/types/filters/parse.go | 68 ++++++++++++++++ .../types/reference/image_reference.go | 32 ++++++++ .../docker/engine-api/types/stats.go | 3 + .../docker/engine-api/types/types.go | 9 ++- 29 files changed, 331 insertions(+), 146 deletions(-) create mode 100644 components/engine/vendor/src/github.com/docker/engine-api/types/reference/image_reference.go diff --git a/components/engine/hack/vendor.sh b/components/engine/hack/vendor.sh index 5467f2e1aa..5d1c61cc6a 100755 --- a/components/engine/hack/vendor.sh +++ b/components/engine/hack/vendor.sh @@ -25,7 +25,7 @@ clone git golang.org/x/net 78cb2c067747f08b343f20614155233ab4ea2ad3 https://gith clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://github.com/golang/sys.git clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3 clone git github.com/docker/go-connections v0.2.0 -clone git github.com/docker/engine-api 8924d6900370b4c7e7984be5adc61f50a80d7537 +clone git github.com/docker/engine-api a6dca654f28f26b648115649f6382252ada81119 clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837 clone git github.com/imdario/mergo 0.2.1 diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/client.go b/components/engine/vendor/src/github.com/docker/engine-api/client/client.go index 0716667b3a..f91d235be4 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/client.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/client.go @@ -114,6 +114,12 @@ func (cli *Client) ClientVersion() string { return cli.version } +// UpdateClientVersion updates the version string associated with this +// instance of the Client. +func (cli *Client) UpdateClientVersion(v string) { + cli.version = v +} + // ParseHost verifies that the given host strings is valid. func ParseHost(host string) (string, string, string, error) { protoAddrParts := strings.SplitN(host, "://", 2) diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/container_attach.go b/components/engine/vendor/src/github.com/docker/engine-api/client/container_attach.go index d87fc655c2..1b616bf038 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/container_attach.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/container_attach.go @@ -11,7 +11,7 @@ import ( // It returns a types.HijackedConnection with the hijacked connection // and the a reader to get output. It's up to the called to close // the hijacked connection by calling types.HijackedResponse.Close. -func (cli *Client) ContainerAttach(ctx context.Context, options types.ContainerAttachOptions) (types.HijackedResponse, error) { +func (cli *Client) ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error) { query := url.Values{} if options.Stream { query.Set("stream", "1") @@ -30,5 +30,5 @@ func (cli *Client) ContainerAttach(ctx context.Context, options types.ContainerA } headers := map[string][]string{"Content-Type": {"text/plain"}} - return cli.postHijacked(ctx, "/containers/"+options.ContainerID+"/attach", query, nil, headers) + return cli.postHijacked(ctx, "/containers/"+container+"/attach", query, nil, headers) } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/container_commit.go b/components/engine/vendor/src/github.com/docker/engine-api/client/container_commit.go index 8a6c89935a..d5c4749906 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/container_commit.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/container_commit.go @@ -2,18 +2,36 @@ package client import ( "encoding/json" + "errors" "net/url" + distreference "github.com/docker/distribution/reference" "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/reference" "golang.org/x/net/context" ) // ContainerCommit applies changes into a container and creates a new tagged image. -func (cli *Client) ContainerCommit(ctx context.Context, options types.ContainerCommitOptions) (types.ContainerCommitResponse, error) { +func (cli *Client) ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.ContainerCommitResponse, error) { + var repository, tag string + if options.Reference != "" { + distributionRef, err := distreference.ParseNamed(options.Reference) + if err != nil { + return types.ContainerCommitResponse{}, err + } + + if _, isCanonical := distributionRef.(distreference.Canonical); isCanonical { + return types.ContainerCommitResponse{}, errors.New("refusing to create a tag with a digest reference") + } + + tag = reference.GetTagFromNamedRef(distributionRef) + repository = distributionRef.Name() + } + query := url.Values{} - query.Set("container", options.ContainerID) - query.Set("repo", options.RepositoryName) - query.Set("tag", options.Tag) + query.Set("container", container) + query.Set("repo", repository) + query.Set("tag", tag) query.Set("comment", options.Comment) query.Set("author", options.Author) for _, change := range options.Changes { diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/container_exec.go b/components/engine/vendor/src/github.com/docker/engine-api/client/container_exec.go index 3119679397..ff7e1a9d05 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/container_exec.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/container_exec.go @@ -8,9 +8,9 @@ import ( ) // ContainerExecCreate creates a new exec configuration to run an exec process. -func (cli *Client) ContainerExecCreate(ctx context.Context, config types.ExecConfig) (types.ContainerExecCreateResponse, error) { +func (cli *Client) ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.ContainerExecCreateResponse, error) { var response types.ContainerExecCreateResponse - resp, err := cli.post(ctx, "/containers/"+config.Container+"/exec", nil, config, nil) + resp, err := cli.post(ctx, "/containers/"+container+"/exec", nil, config, nil) if err != nil { return response, err } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/container_list.go b/components/engine/vendor/src/github.com/docker/engine-api/client/container_list.go index 573f41d5c6..87f7333dc7 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/container_list.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/container_list.go @@ -35,7 +35,8 @@ func (cli *Client) ContainerList(ctx context.Context, options types.ContainerLis } if options.Filter.Len() > 0 { - filterJSON, err := filters.ToParam(options.Filter) + filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filter) + if err != nil { return nil, err } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/container_logs.go b/components/engine/vendor/src/github.com/docker/engine-api/client/container_logs.go index 47c60ee3c4..9699ac7dde 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/container_logs.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/container_logs.go @@ -13,7 +13,7 @@ import ( // ContainerLogs returns the logs generated by a container in an io.ReadCloser. // It's up to the caller to close the stream. -func (cli *Client) ContainerLogs(ctx context.Context, options types.ContainerLogsOptions) (io.ReadCloser, error) { +func (cli *Client) ContainerLogs(ctx context.Context, container string, options types.ContainerLogsOptions) (io.ReadCloser, error) { query := url.Values{} if options.ShowStdout { query.Set("stdout", "1") @@ -40,7 +40,7 @@ func (cli *Client) ContainerLogs(ctx context.Context, options types.ContainerLog } query.Set("tail", options.Tail) - resp, err := cli.get(ctx, "/containers/"+options.ContainerID+"/logs", query, nil) + resp, err := cli.get(ctx, "/containers/"+container+"/logs", query, nil) if err != nil { return nil, err } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/container_remove.go b/components/engine/vendor/src/github.com/docker/engine-api/client/container_remove.go index 56796231f4..cef4b81220 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/container_remove.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/container_remove.go @@ -8,7 +8,7 @@ import ( ) // ContainerRemove kills and removes a container from the docker host. -func (cli *Client) ContainerRemove(ctx context.Context, options types.ContainerRemoveOptions) error { +func (cli *Client) ContainerRemove(ctx context.Context, containerID string, options types.ContainerRemoveOptions) error { query := url.Values{} if options.RemoveVolumes { query.Set("v", "1") @@ -21,7 +21,7 @@ func (cli *Client) ContainerRemove(ctx context.Context, options types.ContainerR query.Set("force", "1") } - resp, err := cli.delete(ctx, "/containers/"+options.ContainerID, query, nil) + resp, err := cli.delete(ctx, "/containers/"+containerID, query, nil) ensureReaderClosed(resp) return err } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/container_resize.go b/components/engine/vendor/src/github.com/docker/engine-api/client/container_resize.go index 0782017497..b95d26b335 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/container_resize.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/container_resize.go @@ -9,13 +9,13 @@ import ( ) // ContainerResize changes the size of the tty for a container. -func (cli *Client) ContainerResize(ctx context.Context, options types.ResizeOptions) error { - return cli.resize(ctx, "/containers/"+options.ID, options.Height, options.Width) +func (cli *Client) ContainerResize(ctx context.Context, containerID string, options types.ResizeOptions) error { + return cli.resize(ctx, "/containers/"+containerID, options.Height, options.Width) } // ContainerExecResize changes the size of the tty for an exec process running inside a container. -func (cli *Client) ContainerExecResize(ctx context.Context, options types.ResizeOptions) error { - return cli.resize(ctx, "/exec/"+options.ID, options.Height, options.Width) +func (cli *Client) ContainerExecResize(ctx context.Context, execID string, options types.ResizeOptions) error { + return cli.resize(ctx, "/exec/"+execID, options.Height, options.Width) } func (cli *Client) resize(ctx context.Context, basePath string, height, width int) error { diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/image_build.go b/components/engine/vendor/src/github.com/docker/engine-api/client/image_build.go index 1612c6a1b8..4165c4e9a8 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/image_build.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/image_build.go @@ -3,6 +3,7 @@ package client import ( "encoding/base64" "encoding/json" + "io" "net/http" "net/url" "regexp" @@ -20,7 +21,7 @@ var headerRegexp = regexp.MustCompile(`\ADocker/.+\s\((.+)\)\z`) // ImageBuild sends request to the daemon to build images. // The Body in the response implement an io.ReadCloser and it's up to the caller to // close it. -func (cli *Client) ImageBuild(ctx context.Context, options types.ImageBuildOptions) (types.ImageBuildResponse, error) { +func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) { query, err := imageBuildOptionsToQuery(options) if err != nil { return types.ImageBuildResponse{}, err @@ -34,7 +35,7 @@ func (cli *Client) ImageBuild(ctx context.Context, options types.ImageBuildOptio headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf)) headers.Set("Content-Type", "application/tar") - serverResp, err := cli.postRaw(ctx, "/build", query, options.Context, headers) + serverResp, err := cli.postRaw(ctx, "/build", query, buildContext, headers) if err != nil { return types.ImageBuildResponse{}, err } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/image_create.go b/components/engine/vendor/src/github.com/docker/engine-api/client/image_create.go index 1ec1f9d09b..6dfc0391c0 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/image_create.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/image_create.go @@ -7,14 +7,20 @@ import ( "golang.org/x/net/context" "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/reference" ) // ImageCreate creates a new image based in the parent options. // It returns the JSON content in the response body. -func (cli *Client) ImageCreate(ctx context.Context, options types.ImageCreateOptions) (io.ReadCloser, error) { +func (cli *Client) ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) { + repository, tag, err := reference.Parse(parentReference) + if err != nil { + return nil, err + } + query := url.Values{} - query.Set("fromImage", options.Parent) - query.Set("tag", options.Tag) + query.Set("fromImage", repository) + query.Set("tag", tag) resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth) if err != nil { return nil, err diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/image_import.go b/components/engine/vendor/src/github.com/docker/engine-api/client/image_import.go index 48e2c951a4..4e8749a01d 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/image_import.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/image_import.go @@ -6,22 +6,30 @@ import ( "golang.org/x/net/context" + "github.com/docker/distribution/reference" "github.com/docker/engine-api/types" ) // ImageImport creates a new image based in the source options. // It returns the JSON content in the response body. -func (cli *Client) ImageImport(ctx context.Context, options types.ImageImportOptions) (io.ReadCloser, error) { +func (cli *Client) ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) { + if ref != "" { + //Check if the given image name can be resolved + if _, err := reference.ParseNamed(ref); err != nil { + return nil, err + } + } + query := url.Values{} - query.Set("fromSrc", options.SourceName) - query.Set("repo", options.RepositoryName) + query.Set("fromSrc", source.SourceName) + query.Set("repo", ref) query.Set("tag", options.Tag) query.Set("message", options.Message) for _, change := range options.Changes { query.Add("changes", change) } - resp, err := cli.postRaw(ctx, "/images/create", query, options.Source, nil) + resp, err := cli.postRaw(ctx, "/images/create", query, source.Source, nil) if err != nil { return nil, err } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/image_pull.go b/components/engine/vendor/src/github.com/docker/engine-api/client/image_pull.go index 4c045173a5..0584f00bd4 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/image_pull.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/image_pull.go @@ -8,22 +8,32 @@ import ( "golang.org/x/net/context" "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/reference" ) // ImagePull requests the docker host to pull an image from a remote registry. // It executes the privileged function if the operation is unauthorized // and it tries one more time. // It's up to the caller to handle the io.ReadCloser and close it properly. -func (cli *Client) ImagePull(ctx context.Context, options types.ImagePullOptions, privilegeFunc RequestPrivilegeFunc) (io.ReadCloser, error) { +// +// FIXME(vdemeester): there is currently used in a few way in docker/docker +// - if not in trusted content, ref is used to pass the whole reference, and tag is empty +// - if in trusted content, ref is used to pass the reference name, and tag for the digest +func (cli *Client) ImagePull(ctx context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error) { + repository, tag, err := reference.Parse(ref) + if err != nil { + return nil, err + } + query := url.Values{} - query.Set("fromImage", options.ImageID) - if options.Tag != "" { - query.Set("tag", options.Tag) + query.Set("fromImage", repository) + if tag != "" { + query.Set("tag", tag) } resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth) if resp.statusCode == http.StatusUnauthorized { - newAuthHeader, privilegeErr := privilegeFunc() + newAuthHeader, privilegeErr := options.PrivilegeFunc() if privilegeErr != nil { return nil, privilegeErr } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/image_push.go b/components/engine/vendor/src/github.com/docker/engine-api/client/image_push.go index 0b09362f49..8134f8018c 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/image_push.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/image_push.go @@ -1,30 +1,44 @@ package client import ( + "errors" "io" "net/http" "net/url" "golang.org/x/net/context" + distreference "github.com/docker/distribution/reference" "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/reference" ) // ImagePush requests the docker host to push an image to a remote registry. // It executes the privileged function if the operation is unauthorized // and it tries one more time. // It's up to the caller to handle the io.ReadCloser and close it properly. -func (cli *Client) ImagePush(ctx context.Context, options types.ImagePushOptions, privilegeFunc RequestPrivilegeFunc) (io.ReadCloser, error) { - query := url.Values{} - query.Set("tag", options.Tag) +func (cli *Client) ImagePush(ctx context.Context, ref string, options types.ImagePushOptions) (io.ReadCloser, error) { + distributionRef, err := distreference.ParseNamed(ref) + if err != nil { + return nil, err + } - resp, err := cli.tryImagePush(ctx, options.ImageID, query, options.RegistryAuth) + if _, isCanonical := distributionRef.(distreference.Canonical); isCanonical { + return nil, errors.New("cannot push a digest reference") + } + + tag := reference.GetTagFromNamedRef(distributionRef) + + query := url.Values{} + query.Set("tag", tag) + + resp, err := cli.tryImagePush(ctx, distributionRef.Name(), query, options.RegistryAuth) if resp.statusCode == http.StatusUnauthorized { - newAuthHeader, privilegeErr := privilegeFunc() + newAuthHeader, privilegeErr := options.PrivilegeFunc() if privilegeErr != nil { return nil, privilegeErr } - resp, err = cli.tryImagePush(ctx, options.ImageID, query, newAuthHeader) + resp, err = cli.tryImagePush(ctx, distributionRef.Name(), query, newAuthHeader) } if err != nil { return nil, err diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/image_remove.go b/components/engine/vendor/src/github.com/docker/engine-api/client/image_remove.go index d7e71c89ce..47224326e0 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/image_remove.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/image_remove.go @@ -9,7 +9,7 @@ import ( ) // ImageRemove removes an image from the docker host. -func (cli *Client) ImageRemove(ctx context.Context, options types.ImageRemoveOptions) ([]types.ImageDelete, error) { +func (cli *Client) ImageRemove(ctx context.Context, imageID string, options types.ImageRemoveOptions) ([]types.ImageDelete, error) { query := url.Values{} if options.Force { @@ -19,7 +19,7 @@ func (cli *Client) ImageRemove(ctx context.Context, options types.ImageRemoveOpt query.Set("noprune", "1") } - resp, err := cli.delete(ctx, "/images/"+options.ImageID, query, nil) + resp, err := cli.delete(ctx, "/images/"+imageID, query, nil) if err != nil { return nil, err } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/image_search.go b/components/engine/vendor/src/github.com/docker/engine-api/client/image_search.go index ebe9dc0b6e..3528bda6bd 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/image_search.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/image_search.go @@ -12,14 +12,14 @@ import ( // ImageSearch makes the docker host to search by a term in a remote registry. // The list of results is not sorted in any fashion. -func (cli *Client) ImageSearch(ctx context.Context, options types.ImageSearchOptions, privilegeFunc RequestPrivilegeFunc) ([]registry.SearchResult, error) { +func (cli *Client) ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error) { var results []registry.SearchResult query := url.Values{} - query.Set("term", options.Term) + query.Set("term", term) resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth) if resp.statusCode == http.StatusUnauthorized { - newAuthHeader, privilegeErr := privilegeFunc() + newAuthHeader, privilegeErr := options.PrivilegeFunc() if privilegeErr != nil { return results, privilegeErr } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/image_tag.go b/components/engine/vendor/src/github.com/docker/engine-api/client/image_tag.go index 20feda38c1..490de4e5fe 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/image_tag.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/image_tag.go @@ -1,22 +1,38 @@ package client import ( + "errors" + "fmt" "net/url" - "github.com/docker/engine-api/types" "golang.org/x/net/context" + + distreference "github.com/docker/distribution/reference" + "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/reference" ) // ImageTag tags an image in the docker host -func (cli *Client) ImageTag(ctx context.Context, options types.ImageTagOptions) error { +func (cli *Client) ImageTag(ctx context.Context, imageID, ref string, options types.ImageTagOptions) error { + distributionRef, err := distreference.ParseNamed(ref) + if err != nil { + return fmt.Errorf("Error parsing reference: %q is not a valid repository/tag", ref) + } + + if _, isCanonical := distributionRef.(distreference.Canonical); isCanonical { + return errors.New("refusing to create a tag with a digest reference") + } + + tag := reference.GetTagFromNamedRef(distributionRef) + query := url.Values{} - query.Set("repo", options.RepositoryName) - query.Set("tag", options.Tag) + query.Set("repo", distributionRef.Name()) + query.Set("tag", tag) if options.Force { query.Set("force", "1") } - resp, err := cli.post(ctx, "/images/"+options.ImageID+"/tag", query, nil, nil) + resp, err := cli.post(ctx, "/images/"+imageID+"/tag", query, nil, nil) ensureReaderClosed(resp) return err } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/interface.go b/components/engine/vendor/src/github.com/docker/engine-api/client/interface.go index e95ed55567..6c15c5bf98 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/interface.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/interface.go @@ -15,59 +15,60 @@ import ( // APIClient is an interface that clients that talk with a docker server must implement. type APIClient interface { ClientVersion() string - ContainerAttach(ctx context.Context, options types.ContainerAttachOptions) (types.HijackedResponse, error) - ContainerCommit(ctx context.Context, options types.ContainerCommitOptions) (types.ContainerCommitResponse, error) + ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error) + ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.ContainerCommitResponse, error) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (types.ContainerCreateResponse, error) - ContainerDiff(ctx context.Context, ontainerID string) ([]types.ContainerChange, error) + ContainerDiff(ctx context.Context, container string) ([]types.ContainerChange, error) ContainerExecAttach(ctx context.Context, execID string, config types.ExecConfig) (types.HijackedResponse, error) - ContainerExecCreate(ctx context.Context, config types.ExecConfig) (types.ContainerExecCreateResponse, error) + ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.ContainerExecCreateResponse, error) ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error) - ContainerExecResize(ctx context.Context, options types.ResizeOptions) error + ContainerExecResize(ctx context.Context, execID string, options types.ResizeOptions) error ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error - ContainerExport(ctx context.Context, containerID string) (io.ReadCloser, error) - ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) - ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool) (types.ContainerJSON, []byte, error) - ContainerKill(ctx context.Context, containerID, signal string) error + ContainerExport(ctx context.Context, container string) (io.ReadCloser, error) + ContainerInspect(ctx context.Context, container string) (types.ContainerJSON, error) + ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (types.ContainerJSON, []byte, error) + ContainerKill(ctx context.Context, container, signal string) error ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error) - ContainerLogs(ctx context.Context, options types.ContainerLogsOptions) (io.ReadCloser, error) - ContainerPause(ctx context.Context, containerID string) error - ContainerRemove(ctx context.Context, options types.ContainerRemoveOptions) error - ContainerRename(ctx context.Context, containerID, newContainerName string) error - ContainerResize(ctx context.Context, options types.ResizeOptions) error - ContainerRestart(ctx context.Context, containerID string, timeout int) error - ContainerStatPath(ctx context.Context, containerID, path string) (types.ContainerPathStat, error) - ContainerStats(ctx context.Context, containerID string, stream bool) (io.ReadCloser, error) - ContainerStart(ctx context.Context, containerID string) error - ContainerStop(ctx context.Context, containerID string, timeout int) error - ContainerTop(ctx context.Context, containerID string, arguments []string) (types.ContainerProcessList, error) - ContainerUnpause(ctx context.Context, containerID string) error - ContainerUpdate(ctx context.Context, containerID string, updateConfig container.UpdateConfig) error - ContainerWait(ctx context.Context, containerID string) (int, error) - CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) + ContainerLogs(ctx context.Context, container string, options types.ContainerLogsOptions) (io.ReadCloser, error) + ContainerPause(ctx context.Context, container string) error + ContainerRemove(ctx context.Context, container string, options types.ContainerRemoveOptions) error + ContainerRename(ctx context.Context, container, newContainerName string) error + ContainerResize(ctx context.Context, container string, options types.ResizeOptions) error + ContainerRestart(ctx context.Context, container string, timeout int) error + ContainerStatPath(ctx context.Context, container, path string) (types.ContainerPathStat, error) + ContainerStats(ctx context.Context, container string, stream bool) (io.ReadCloser, error) + ContainerStart(ctx context.Context, container string) error + ContainerStop(ctx context.Context, container string, timeout int) error + ContainerTop(ctx context.Context, container string, arguments []string) (types.ContainerProcessList, error) + ContainerUnpause(ctx context.Context, container string) error + ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) error + ContainerWait(ctx context.Context, container string) (int, error) + CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) CopyToContainer(ctx context.Context, options types.CopyToContainerOptions) error Events(ctx context.Context, options types.EventsOptions) (io.ReadCloser, error) - ImageBuild(ctx context.Context, options types.ImageBuildOptions) (types.ImageBuildResponse, error) - ImageCreate(ctx context.Context, options types.ImageCreateOptions) (io.ReadCloser, error) - ImageHistory(ctx context.Context, imageID string) ([]types.ImageHistory, error) - ImageImport(ctx context.Context, options types.ImageImportOptions) (io.ReadCloser, error) - ImageInspectWithRaw(ctx context.Context, imageID string, getSize bool) (types.ImageInspect, []byte, error) + ImageBuild(ctx context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) + ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) + ImageHistory(ctx context.Context, image string) ([]types.ImageHistory, error) + ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) + ImageInspectWithRaw(ctx context.Context, image string, getSize bool) (types.ImageInspect, []byte, error) ImageList(ctx context.Context, options types.ImageListOptions) ([]types.Image, error) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error) - ImagePull(ctx context.Context, options types.ImagePullOptions, privilegeFunc RequestPrivilegeFunc) (io.ReadCloser, error) - ImagePush(ctx context.Context, options types.ImagePushOptions, privilegeFunc RequestPrivilegeFunc) (io.ReadCloser, error) - ImageRemove(ctx context.Context, options types.ImageRemoveOptions) ([]types.ImageDelete, error) - ImageSearch(ctx context.Context, options types.ImageSearchOptions, privilegeFunc RequestPrivilegeFunc) ([]registry.SearchResult, error) - ImageSave(ctx context.Context, imageIDs []string) (io.ReadCloser, error) - ImageTag(ctx context.Context, options types.ImageTagOptions) error + ImagePull(ctx context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error) + ImagePush(ctx context.Context, ref string, options types.ImagePushOptions) (io.ReadCloser, error) + ImageRemove(ctx context.Context, image string, options types.ImageRemoveOptions) ([]types.ImageDelete, error) + ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error) + ImageSave(ctx context.Context, images []string) (io.ReadCloser, error) + ImageTag(ctx context.Context, image, ref string, options types.ImageTagOptions) error Info(ctx context.Context) (types.Info, error) - NetworkConnect(ctx context.Context, networkID, containerID string, config *network.EndpointSettings) error - NetworkCreate(ctx context.Context, options types.NetworkCreate) (types.NetworkCreateResponse, error) - NetworkDisconnect(ctx context.Context, networkID, containerID string, force bool) error + NetworkConnect(ctx context.Context, networkID, container string, config *network.EndpointSettings) error + NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) + NetworkDisconnect(ctx context.Context, networkID, container string, force bool) error NetworkInspect(ctx context.Context, networkID string) (types.NetworkResource, error) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) NetworkRemove(ctx context.Context, networkID string) error RegistryLogin(ctx context.Context, auth types.AuthConfig) (types.AuthResponse, error) ServerVersion(ctx context.Context) (types.Version, error) + UpdateClientVersion(v string) VolumeCreate(ctx context.Context, options types.VolumeCreateRequest) (types.Volume, error) VolumeInspect(ctx context.Context, volumeID string) (types.Volume, error) VolumeList(ctx context.Context, filter filters.Args) (types.VolumesListResponse, error) diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/network_create.go b/components/engine/vendor/src/github.com/docker/engine-api/client/network_create.go index 2c41ad7ec4..c9c0b9fde7 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/network_create.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/network_create.go @@ -8,9 +8,13 @@ import ( ) // NetworkCreate creates a new network in the docker host. -func (cli *Client) NetworkCreate(ctx context.Context, options types.NetworkCreate) (types.NetworkCreateResponse, error) { +func (cli *Client) NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) { + networkCreateRequest := types.NetworkCreateRequest{ + NetworkCreate: options, + Name: name, + } var response types.NetworkCreateResponse - serverResp, err := cli.post(ctx, "/networks/create", nil, options, nil) + serverResp, err := cli.post(ctx, "/networks/create", nil, networkCreateRequest, nil) if err != nil { return response, err } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/privileged.go b/components/engine/vendor/src/github.com/docker/engine-api/client/privileged.go index 945f18cef5..da13c8ef3c 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/privileged.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/privileged.go @@ -1,9 +1 @@ package client - -// RequestPrivilegeFunc is a function interface that -// clients can supply to retry operations after -// getting an authorization error. -// This function returns the registry authentication -// header value in base 64 format, or an error -// if the privilege request fails. -type RequestPrivilegeFunc func() (string, error) diff --git a/components/engine/vendor/src/github.com/docker/engine-api/client/request.go b/components/engine/vendor/src/github.com/docker/engine-api/client/request.go index f45182399c..4ad2d24b88 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/client/request.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/client/request.go @@ -56,12 +56,14 @@ func (cli *Client) delete(ctx context.Context, path string, query url.Values, he } func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, obj interface{}, headers map[string][]string) (*serverResponse, error) { - body, err := encodeData(obj) - if err != nil { - return nil, err - } + var body io.Reader - if body != nil { + if obj != nil { + var err error + body, err = encodeData(obj) + if err != nil { + return nil, err + } if headers == nil { headers = make(map[string][]string) } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/types/client.go b/components/engine/vendor/src/github.com/docker/engine-api/types/client.go index 975a5bb639..c7067f01c5 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/types/client.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/types/client.go @@ -12,24 +12,21 @@ import ( // ContainerAttachOptions holds parameters to attach to a container. type ContainerAttachOptions struct { - ContainerID string - Stream bool - Stdin bool - Stdout bool - Stderr bool - DetachKeys string + Stream bool + Stdin bool + Stdout bool + Stderr bool + DetachKeys string } // ContainerCommitOptions holds parameters to commit changes into a container. type ContainerCommitOptions struct { - ContainerID string - RepositoryName string - Tag string - Comment string - Author string - Changes []string - Pause bool - Config *container.Config + Reference string + Comment string + Author string + Changes []string + Pause bool + Config *container.Config } // ContainerExecInspect holds information returned by exec inspect. @@ -54,18 +51,16 @@ type ContainerListOptions struct { // ContainerLogsOptions holds parameters to filter logs with. type ContainerLogsOptions struct { - ContainerID string - ShowStdout bool - ShowStderr bool - Since string - Timestamps bool - Follow bool - Tail string + ShowStdout bool + ShowStderr bool + Since string + Timestamps bool + Follow bool + Tail string } // ContainerRemoveOptions holds parameters to remove containers. type ContainerRemoveOptions struct { - ContainerID string RemoveVolumes bool RemoveLinks bool Force bool @@ -155,19 +150,20 @@ type ImageBuildResponse struct { // ImageCreateOptions holds information to create images. type ImageCreateOptions struct { - Parent string // Parent is the name of the image to pull - Tag string // Tag is the name to tag this image with RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry } +// ImageImportSource holds source information for ImageImport +type ImageImportSource struct { + Source io.Reader // Source is the data to send to the server to create this image from (mutually exclusive with SourceName) + SourceName string // SourceName is the name of the image to pull (mutually exclusive with Source) +} + // ImageImportOptions holds information to import images from the client host. type ImageImportOptions struct { - Source io.Reader // Source is the data to send to the server to create this image from (mutually exclusive with SourceName) - SourceName string // SourceName is the name of the image to pull (mutually exclusive with Source) - RepositoryName string // RepositoryName is the name of the repository to import this image into - Message string // Message is the message to tag the image with - Tag string // Tag is the name to tag this image with - Changes []string // Changes are the raw changes to apply to this image + Tag string // Tag is the name to tag this image with. This attribute is deprecated. + Message string // Message is the message to tag the image with + Changes []string // Changes are the raw changes to apply to this image } // ImageListOptions holds parameters to filter the list of images with. @@ -185,40 +181,42 @@ type ImageLoadResponse struct { // ImagePullOptions holds information to pull images. type ImagePullOptions struct { - ImageID string // ImageID is the name of the image to pull - Tag string // Tag is the name of the tag to be pulled - RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry + RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry + PrivilegeFunc RequestPrivilegeFunc } +// RequestPrivilegeFunc is a function interface that +// clients can supply to retry operations after +// getting an authorization error. +// This function returns the registry authentication +// header value in base 64 format, or an error +// if the privilege request fails. +type RequestPrivilegeFunc func() (string, error) + //ImagePushOptions holds information to push images. type ImagePushOptions ImagePullOptions // ImageRemoveOptions holds parameters to remove images. type ImageRemoveOptions struct { - ImageID string Force bool PruneChildren bool } // ImageSearchOptions holds parameters to search images with. type ImageSearchOptions struct { - Term string - RegistryAuth string + RegistryAuth string + PrivilegeFunc RequestPrivilegeFunc } // ImageTagOptions holds parameters to tag an image type ImageTagOptions struct { - ImageID string - RepositoryName string - Tag string - Force bool + Force bool } // ResizeOptions holds parameters to resize a tty. // It can be used to resize container ttys and // exec process ttys too. type ResizeOptions struct { - ID string Height int Width int } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/types/configs.go b/components/engine/vendor/src/github.com/docker/engine-api/types/configs.go index 6874a037df..fc840e3f2d 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/types/configs.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/types/configs.go @@ -44,7 +44,6 @@ type ExecConfig struct { User string // User that will run the command Privileged bool // Is the container in privileged mode Tty bool // Attach standard streams to a tty. - Container string // Name of the container (to execute in) AttachStdin bool // Attach the standard input, makes possible user interaction AttachStderr bool // Attach the standard output AttachStdout bool // Attach the standard error diff --git a/components/engine/vendor/src/github.com/docker/engine-api/types/container/config.go b/components/engine/vendor/src/github.com/docker/engine-api/types/container/config.go index b8747a5087..1dfc408348 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/types/container/config.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/types/container/config.go @@ -19,7 +19,6 @@ type Config struct { AttachStdout bool // Attach the standard output AttachStderr bool // Attach the standard error ExposedPorts map[nat.Port]struct{} `json:",omitempty"` // List of exposed ports - PublishService string `json:",omitempty"` // Name of the network service exposed by the container Tty bool // Attach standard streams to a tty, including stdin if it is not closed. OpenStdin bool // Open stdin StdinOnce bool // If true, close stdin after the 1 attached client disconnects. diff --git a/components/engine/vendor/src/github.com/docker/engine-api/types/container/host_config.go b/components/engine/vendor/src/github.com/docker/engine-api/types/container/host_config.go index 7ad634b6da..cd3a9f6725 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/types/container/host_config.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/types/container/host_config.go @@ -92,11 +92,13 @@ func (n UsernsMode) Valid() bool { // CgroupSpec represents the cgroup to use for the container. type CgroupSpec string +// IsContainer indicates whether the container is using another container cgroup func (c CgroupSpec) IsContainer() bool { parts := strings.SplitN(string(c), ":", 2) return len(parts) > 1 && parts[0] == "container" } +// Valid indicates whether the cgroup spec is valid. func (c CgroupSpec) Valid() bool { return c.IsContainer() || c == "" } diff --git a/components/engine/vendor/src/github.com/docker/engine-api/types/filters/parse.go b/components/engine/vendor/src/github.com/docker/engine-api/types/filters/parse.go index da2a089297..82c18845dd 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/types/filters/parse.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/types/filters/parse.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "regexp" + "strconv" "strings" ) @@ -68,6 +69,28 @@ func ToParam(a Args) (string, error) { return string(buf), nil } +// ToParamWithVersion packs the Args into a string for easy transport from client to server. +// The generated string will depend on the specified version (corresponding to the API version). +func ToParamWithVersion(version string, a Args) (string, error) { + // this way we don't URL encode {}, just empty space + if a.Len() == 0 { + return "", nil + } + + // for daemons older than v1.10, filter must be of the form map[string][]string + buf := []byte{} + err := errors.New("") + if version != "" && compareTo(version, "1.22") == -1 { + buf, err = json.Marshal(convertArgsToSlice(a.fields)) + } else { + buf, err = json.Marshal(a.fields) + } + if err != nil { + return "", err + } + return string(buf), nil +} + // FromParam unpacks the filter Args. func FromParam(p string) (Args, error) { if len(p) == 0 { @@ -255,3 +278,48 @@ func deprecatedArgs(d map[string][]string) map[string]map[string]bool { } return m } + +func convertArgsToSlice(f map[string]map[string]bool) map[string][]string { + m := map[string][]string{} + for k, v := range f { + values := []string{} + for kk := range v { + if v[kk] { + values = append(values, kk) + } + } + m[k] = values + } + return m +} + +// compareTo compares two version strings +// returns -1 if v1 < v2, 1 if v1 > v2, 0 otherwise +func compareTo(v1, v2 string) int { + var ( + currTab = strings.Split(v1, ".") + otherTab = strings.Split(v2, ".") + ) + + max := len(currTab) + if len(otherTab) > max { + max = len(otherTab) + } + for i := 0; i < max; i++ { + var currInt, otherInt int + + if len(currTab) > i { + currInt, _ = strconv.Atoi(currTab[i]) + } + if len(otherTab) > i { + otherInt, _ = strconv.Atoi(otherTab[i]) + } + if currInt > otherInt { + return 1 + } + if otherInt > currInt { + return -1 + } + } + return 0 +} diff --git a/components/engine/vendor/src/github.com/docker/engine-api/types/reference/image_reference.go b/components/engine/vendor/src/github.com/docker/engine-api/types/reference/image_reference.go new file mode 100644 index 0000000000..6bfb2f99bf --- /dev/null +++ b/components/engine/vendor/src/github.com/docker/engine-api/types/reference/image_reference.go @@ -0,0 +1,32 @@ +package reference + +import ( + distreference "github.com/docker/distribution/reference" +) + +// Parse parses the given references and return the repository and +// tag (if present) from it. If there is an error during parsing, it will +// return an error. +func Parse(ref string) (string, string, error) { + distributionRef, err := distreference.ParseNamed(ref) + if err != nil { + return "", "", err + } + + tag := GetTagFromNamedRef(distributionRef) + return distributionRef.Name(), tag, nil +} + +// GetTagFromNamedRef returns a tag from the specified reference. +// This function is necessary as long as the docker "server" api make the distinction between repository +// and tags. +func GetTagFromNamedRef(ref distreference.Named) string { + var tag string + switch x := ref.(type) { + case distreference.Digested: + tag = x.Digest().String() + case distreference.NamedTagged: + tag = x.Tag() + } + return tag +} diff --git a/components/engine/vendor/src/github.com/docker/engine-api/types/stats.go b/components/engine/vendor/src/github.com/docker/engine-api/types/stats.go index 1434033410..b420ebe7f6 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/types/stats.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/types/stats.go @@ -91,6 +91,9 @@ type NetworkStats struct { type PidsStats struct { // Current is the number of pids in the cgroup Current uint64 `json:"current,omitempty"` + // Limit is the hard limit on the number of pids in the cgroup. + // A "Limit" of 0 means that there is no limit. + Limit uint64 `json:"limit,omitempty"` } // Stats is Ultimate struct aggregating all types of stats of one container diff --git a/components/engine/vendor/src/github.com/docker/engine-api/types/types.go b/components/engine/vendor/src/github.com/docker/engine-api/types/types.go index e691c3f1dd..406b561a6e 100644 --- a/components/engine/vendor/src/github.com/docker/engine-api/types/types.go +++ b/components/engine/vendor/src/github.com/docker/engine-api/types/types.go @@ -290,7 +290,7 @@ type ContainerState struct { FinishedAt string } -// NodeData stores information about the node that a container +// ContainerNode stores information about the node that a container // is running on. It's only available in Docker Swarm type ContainerNode struct { ID string @@ -438,7 +438,6 @@ type EndpointResource struct { // NetworkCreate is the expected body of the "create network" http request message type NetworkCreate struct { - Name string CheckDuplicate bool Driver string EnableIPv6 bool @@ -448,6 +447,12 @@ type NetworkCreate struct { Labels map[string]string } +// NetworkCreateRequest is the request message sent to the server for network create call. +type NetworkCreateRequest struct { + NetworkCreate + Name string +} + // NetworkCreateResponse is the response message sent by the server for network create call type NetworkCreateResponse struct { ID string `json:"Id"` From b48cb728b8fb9b0af75ea7331b8c5a91f06d6955 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Wed, 13 Apr 2016 10:33:46 +0200 Subject: [PATCH 2/2] Update client code with api changes Using new methods from engine-api, that make it clearer which element is required when consuming the API. Signed-off-by: Vincent Demeester Upstream-commit: b9c94b70bf2f703f260844b3862a61f93dee6337 Component: engine --- components/engine/api/client/attach.go | 19 +++-- components/engine/api/client/build.go | 3 +- components/engine/api/client/commit.go | 41 ++------- components/engine/api/client/create.go | 13 +-- components/engine/api/client/exec.go | 8 +- components/engine/api/client/exec_test.go | 8 -- components/engine/api/client/import.go | 39 ++++----- components/engine/api/client/logs.go | 15 ++-- components/engine/api/client/network.go | 3 +- components/engine/api/client/pull.go | 18 ++-- components/engine/api/client/push.go | 23 ++--- components/engine/api/client/rm.go | 5 +- components/engine/api/client/rmi.go | 5 +- components/engine/api/client/run.go | 13 ++- components/engine/api/client/search.go | 6 +- components/engine/api/client/start.go | 35 ++++---- components/engine/api/client/tag.go | 24 +----- components/engine/api/client/trust.go | 28 ++++--- components/engine/api/client/utils.go | 7 +- .../api/server/router/container/backend.go | 2 +- .../api/server/router/container/exec.go | 3 +- .../api/server/router/network/backend.go | 2 +- .../server/router/network/network_routes.go | 2 +- components/engine/daemon/exec.go | 4 +- components/engine/daemon/network.go | 2 +- .../docker_api_network_test.go | 84 +++++++++++-------- 26 files changed, 174 insertions(+), 238 deletions(-) diff --git a/components/engine/api/client/attach.go b/components/engine/api/client/attach.go index e9e1a891c2..1506dc662c 100644 --- a/components/engine/api/client/attach.go +++ b/components/engine/api/client/attach.go @@ -48,13 +48,14 @@ func (cli *DockerCli) CmdAttach(args ...string) error { cli.configFile.DetachKeys = *detachKeys } + container := cmd.Arg(0) + options := types.ContainerAttachOptions{ - ContainerID: cmd.Arg(0), - Stream: true, - Stdin: !*noStdin && c.Config.OpenStdin, - Stdout: true, - Stderr: true, - DetachKeys: cli.configFile.DetachKeys, + Stream: true, + Stdin: !*noStdin && c.Config.OpenStdin, + Stdout: true, + Stderr: true, + DetachKeys: cli.configFile.DetachKeys, } var in io.ReadCloser @@ -63,11 +64,11 @@ func (cli *DockerCli) CmdAttach(args ...string) error { } if *proxy && !c.Config.Tty { - sigc := cli.forwardAllSignals(options.ContainerID) + sigc := cli.forwardAllSignals(container) defer signal.StopCatch(sigc) } - resp, errAttach := cli.client.ContainerAttach(context.Background(), options) + resp, errAttach := cli.client.ContainerAttach(context.Background(), container, options) if errAttach != nil && errAttach != httputil.ErrPersistEOF { // ContainerAttach returns an ErrPersistEOF (connection closed) // means server met an error and put it in Hijacked connection @@ -98,7 +99,7 @@ func (cli *DockerCli) CmdAttach(args ...string) error { return errAttach } - _, status, err := getExitCode(cli, options.ContainerID) + _, status, err := getExitCode(cli, container) if err != nil { return err } diff --git a/components/engine/api/client/build.go b/components/engine/api/client/build.go index 300d0cd9d9..5b6fb152a9 100644 --- a/components/engine/api/client/build.go +++ b/components/engine/api/client/build.go @@ -212,7 +212,6 @@ func (cli *DockerCli) CmdBuild(args ...string) error { } options := types.ImageBuildOptions{ - Context: body, Memory: memory, MemorySwap: memorySwap, Tags: flTags.GetAll(), @@ -236,7 +235,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error { Labels: runconfigopts.ConvertKVStringsToMap(flLabels.GetAll()), } - response, err := cli.client.ImageBuild(context.Background(), options) + response, err := cli.client.ImageBuild(context.Background(), body, options) if err != nil { return err } diff --git a/components/engine/api/client/commit.go b/components/engine/api/client/commit.go index 6bec4297f4..4a985a43a4 100644 --- a/components/engine/api/client/commit.go +++ b/components/engine/api/client/commit.go @@ -2,7 +2,6 @@ package client import ( "encoding/json" - "errors" "fmt" "golang.org/x/net/context" @@ -10,7 +9,6 @@ import ( Cli "github.com/docker/docker/cli" "github.com/docker/docker/opts" flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/docker/reference" "github.com/docker/engine-api/types" "github.com/docker/engine-api/types/container" ) @@ -33,29 +31,10 @@ func (cli *DockerCli) CmdCommit(args ...string) error { cmd.ParseFlags(args, true) var ( - name = cmd.Arg(0) - repositoryAndTag = cmd.Arg(1) - repositoryName string - tag string + name = cmd.Arg(0) + reference = cmd.Arg(1) ) - //Check if the given image name can be resolved - if repositoryAndTag != "" { - ref, err := reference.ParseNamed(repositoryAndTag) - if err != nil { - return err - } - - repositoryName = ref.Name() - - switch x := ref.(type) { - case reference.Canonical: - return errors.New("cannot commit to digest reference") - case reference.NamedTagged: - tag = x.Tag() - } - } - var config *container.Config if *flConfig != "" { config = &container.Config{} @@ -65,17 +44,15 @@ func (cli *DockerCli) CmdCommit(args ...string) error { } options := types.ContainerCommitOptions{ - ContainerID: name, - RepositoryName: repositoryName, - Tag: tag, - Comment: *flComment, - Author: *flAuthor, - Changes: flChanges.GetAll(), - Pause: *flPause, - Config: config, + Reference: reference, + Comment: *flComment, + Author: *flAuthor, + Changes: flChanges.GetAll(), + Pause: *flPause, + Config: config, } - response, err := cli.client.ContainerCommit(context.Background(), options) + response, err := cli.client.ContainerCommit(context.Background(), name, options) if err != nil { return err } diff --git a/components/engine/api/client/create.go b/components/engine/api/client/create.go index 7c386bcd3c..4c770e9221 100644 --- a/components/engine/api/client/create.go +++ b/components/engine/api/client/create.go @@ -9,6 +9,7 @@ import ( Cli "github.com/docker/docker/cli" "github.com/docker/docker/pkg/jsonmessage" + // FIXME migrate to docker/distribution/reference "github.com/docker/docker/reference" "github.com/docker/docker/registry" runconfigopts "github.com/docker/docker/runconfig/opts" @@ -24,14 +25,6 @@ func (cli *DockerCli) pullImage(image string, out io.Writer) error { return err } - var tag string - switch x := reference.WithDefaultTag(ref).(type) { - case reference.Canonical: - tag = x.Digest().String() - case reference.NamedTagged: - tag = x.Tag() - } - // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(ref) if err != nil { @@ -45,12 +38,10 @@ func (cli *DockerCli) pullImage(image string, out io.Writer) error { } options := types.ImageCreateOptions{ - Parent: ref.Name(), - Tag: tag, RegistryAuth: encodedAuth, } - responseBody, err := cli.client.ImageCreate(context.Background(), options) + responseBody, err := cli.client.ImageCreate(context.Background(), image, options) if err != nil { return err } diff --git a/components/engine/api/client/exec.go b/components/engine/api/client/exec.go index c96f03a0bd..2202324661 100644 --- a/components/engine/api/client/exec.go +++ b/components/engine/api/client/exec.go @@ -21,8 +21,9 @@ func (cli *DockerCli) CmdExec(args ...string) error { detachKeys := cmd.String([]string{"-detach-keys"}, "", "Override the key sequence for detaching a container") execConfig, err := ParseExec(cmd, args) + container := cmd.Arg(0) // just in case the ParseExec does not exit - if execConfig.Container == "" || err != nil { + if container == "" || err != nil { return Cli.StatusError{StatusCode: 1} } @@ -33,7 +34,7 @@ func (cli *DockerCli) CmdExec(args ...string) error { // Send client escape keys execConfig.DetachKeys = cli.configFile.DetachKeys - response, err := cli.client.ContainerExecCreate(context.Background(), *execConfig) + response, err := cli.client.ContainerExecCreate(context.Background(), container, *execConfig) if err != nil { return err } @@ -128,13 +129,11 @@ func ParseExec(cmd *flag.FlagSet, args []string) (*types.ExecConfig, error) { flUser = cmd.String([]string{"u", "-user"}, "", "Username or UID (format: [:])") flPrivileged = cmd.Bool([]string{"-privileged"}, false, "Give extended privileges to the command") execCmd []string - container string ) cmd.Require(flag.Min, 2) if err := cmd.ParseFlags(args, true); err != nil { return nil, err } - container = cmd.Arg(0) parsedArgs := cmd.Args() execCmd = parsedArgs[1:] @@ -143,7 +142,6 @@ func ParseExec(cmd *flag.FlagSet, args []string) (*types.ExecConfig, error) { Privileged: *flPrivileged, Tty: *flTty, Cmd: execCmd, - Container: container, Detach: *flDetach, } diff --git a/components/engine/api/client/exec_test.go b/components/engine/api/client/exec_test.go index 1680fa6e79..8b1a3674e9 100644 --- a/components/engine/api/client/exec_test.go +++ b/components/engine/api/client/exec_test.go @@ -23,7 +23,6 @@ func TestParseExec(t *testing.T) { &arguments{ []string{"container", "command"}, }: { - Container: "container", Cmd: []string{"command"}, AttachStdout: true, AttachStderr: true, @@ -31,7 +30,6 @@ func TestParseExec(t *testing.T) { &arguments{ []string{"container", "command1", "command2"}, }: { - Container: "container", Cmd: []string{"command1", "command2"}, AttachStdout: true, AttachStderr: true, @@ -44,7 +42,6 @@ func TestParseExec(t *testing.T) { AttachStdout: true, AttachStderr: true, Tty: true, - Container: "container", Cmd: []string{"command"}, }, &arguments{ @@ -54,7 +51,6 @@ func TestParseExec(t *testing.T) { AttachStdout: false, AttachStderr: false, Detach: true, - Container: "container", Cmd: []string{"command"}, }, &arguments{ @@ -65,7 +61,6 @@ func TestParseExec(t *testing.T) { AttachStderr: false, Detach: true, Tty: true, - Container: "container", Cmd: []string{"command"}, }, } @@ -103,9 +98,6 @@ func compareExecConfig(config1 *types.ExecConfig, config2 *types.ExecConfig) boo if config1.AttachStdout != config2.AttachStdout { return false } - if config1.Container != config2.Container { - return false - } if config1.Detach != config2.Detach { return false } diff --git a/components/engine/api/client/import.go b/components/engine/api/client/import.go index c96e1e9768..39023b2381 100644 --- a/components/engine/api/client/import.go +++ b/components/engine/api/client/import.go @@ -12,7 +12,6 @@ import ( "github.com/docker/docker/pkg/jsonmessage" flag "github.com/docker/docker/pkg/mflag" "github.com/docker/docker/pkg/urlutil" - "github.com/docker/docker/reference" "github.com/docker/engine-api/types" ) @@ -31,26 +30,20 @@ func (cli *DockerCli) CmdImport(args ...string) error { cmd.ParseFlags(args, true) var ( - in io.Reader - tag string - src = cmd.Arg(0) - srcName = src - repository = cmd.Arg(1) - changes = flChanges.GetAll() + in io.Reader + tag string + src = cmd.Arg(0) + srcName = src + ref = cmd.Arg(1) + changes = flChanges.GetAll() ) if cmd.NArg() == 3 { + // FIXME(vdemeester) Which version has this been deprecated ? should we remove it ? fmt.Fprintf(cli.err, "[DEPRECATED] The format 'file|URL|- [REPOSITORY [TAG]]' has been deprecated. Please use file|URL|- [REPOSITORY[:TAG]]\n") tag = cmd.Arg(2) } - if repository != "" { - //Check if the given image name can be resolved - if _, err := reference.ParseNamed(repository); err != nil { - return err - } - } - if src == "-" { in = cli.in } else if !urlutil.IsURL(src) { @@ -63,16 +56,18 @@ func (cli *DockerCli) CmdImport(args ...string) error { in = file } - options := types.ImageImportOptions{ - Source: in, - SourceName: srcName, - RepositoryName: repository, - Message: *message, - Tag: tag, - Changes: changes, + source := types.ImageImportSource{ + Source: in, + SourceName: srcName, } - responseBody, err := cli.client.ImageImport(context.Background(), options) + options := types.ImageImportOptions{ + Message: *message, + Tag: tag, + Changes: changes, + } + + responseBody, err := cli.client.ImageImport(context.Background(), source, ref, options) if err != nil { return err } diff --git a/components/engine/api/client/logs.go b/components/engine/api/client/logs.go index 7cd5605ed5..85545b9304 100644 --- a/components/engine/api/client/logs.go +++ b/components/engine/api/client/logs.go @@ -42,15 +42,14 @@ func (cli *DockerCli) CmdLogs(args ...string) error { } options := types.ContainerLogsOptions{ - ContainerID: name, - ShowStdout: true, - ShowStderr: true, - Since: *since, - Timestamps: *times, - Follow: *follow, - Tail: *tail, + ShowStdout: true, + ShowStderr: true, + Since: *since, + Timestamps: *times, + Follow: *follow, + Tail: *tail, } - responseBody, err := cli.client.ContainerLogs(context.Background(), options) + responseBody, err := cli.client.ContainerLogs(context.Background(), name, options) if err != nil { return err } diff --git a/components/engine/api/client/network.go b/components/engine/api/client/network.go index 83d958bf4e..6eaf21662e 100644 --- a/components/engine/api/client/network.go +++ b/components/engine/api/client/network.go @@ -77,7 +77,6 @@ func (cli *DockerCli) CmdNetworkCreate(args ...string) error { // Construct network create request body nc := types.NetworkCreate{ - Name: cmd.Arg(0), Driver: driver, IPAM: network.IPAM{Driver: *flIpamDriver, Config: ipamCfg, Options: flIpamOpt.GetAll()}, Options: flOpts.GetAll(), @@ -87,7 +86,7 @@ func (cli *DockerCli) CmdNetworkCreate(args ...string) error { Labels: runconfigopts.ConvertKVStringsToMap(flLabels.GetAll()), } - resp, err := cli.client.NetworkCreate(context.Background(), nc) + resp, err := cli.client.NetworkCreate(context.Background(), cmd.Arg(0), nc) if err != nil { return err } diff --git a/components/engine/api/client/pull.go b/components/engine/api/client/pull.go index 29d9677e95..50d4ff7228 100644 --- a/components/engine/api/client/pull.go +++ b/components/engine/api/client/pull.go @@ -11,7 +11,6 @@ import ( flag "github.com/docker/docker/pkg/mflag" "github.com/docker/docker/reference" "github.com/docker/docker/registry" - "github.com/docker/engine-api/client" "github.com/docker/engine-api/types" ) @@ -48,7 +47,7 @@ func (cli *DockerCli) CmdPull(args ...string) error { tag = x.Tag() } - ref := registry.ParseReference(tag) + registryRef := registry.ParseReference(tag) // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(distributionRef) @@ -59,27 +58,26 @@ func (cli *DockerCli) CmdPull(args ...string) error { authConfig := cli.resolveAuthConfig(repoInfo.Index) requestPrivilege := cli.registryAuthenticationPrivilegedFunc(repoInfo.Index, "pull") - if isTrusted() && !ref.HasDigest() { + if isTrusted() && !registryRef.HasDigest() { // Check if tag is digest - return cli.trustedPull(repoInfo, ref, authConfig, requestPrivilege) + return cli.trustedPull(repoInfo, registryRef, authConfig, requestPrivilege) } - return cli.imagePullPrivileged(authConfig, distributionRef.String(), "", requestPrivilege) + return cli.imagePullPrivileged(authConfig, distributionRef.String(), requestPrivilege) } -func (cli *DockerCli) imagePullPrivileged(authConfig types.AuthConfig, imageID, tag string, requestPrivilege client.RequestPrivilegeFunc) error { +func (cli *DockerCli) imagePullPrivileged(authConfig types.AuthConfig, ref string, requestPrivilege types.RequestPrivilegeFunc) error { encodedAuth, err := encodeAuthToBase64(authConfig) if err != nil { return err } options := types.ImagePullOptions{ - ImageID: imageID, - Tag: tag, - RegistryAuth: encodedAuth, + RegistryAuth: encodedAuth, + PrivilegeFunc: requestPrivilege, } - responseBody, err := cli.client.ImagePull(context.Background(), options, requestPrivilege) + responseBody, err := cli.client.ImagePull(context.Background(), ref, options) if err != nil { return err } diff --git a/components/engine/api/client/push.go b/components/engine/api/client/push.go index 29f26c4673..0d631002e8 100644 --- a/components/engine/api/client/push.go +++ b/components/engine/api/client/push.go @@ -1,7 +1,6 @@ package client import ( - "errors" "io" "golang.org/x/net/context" @@ -11,7 +10,6 @@ import ( flag "github.com/docker/docker/pkg/mflag" "github.com/docker/docker/reference" "github.com/docker/docker/registry" - "github.com/docker/engine-api/client" "github.com/docker/engine-api/types" ) @@ -30,14 +28,6 @@ func (cli *DockerCli) CmdPush(args ...string) error { return err } - var tag string - switch x := ref.(type) { - case reference.Canonical: - return errors.New("cannot push a digest reference") - case reference.NamedTagged: - tag = x.Tag() - } - // Resolve the Repository name from fqn to RepositoryInfo repoInfo, err := registry.ParseRepositoryInfo(ref) if err != nil { @@ -48,10 +38,10 @@ func (cli *DockerCli) CmdPush(args ...string) error { requestPrivilege := cli.registryAuthenticationPrivilegedFunc(repoInfo.Index, "push") if isTrusted() { - return cli.trustedPush(repoInfo, tag, authConfig, requestPrivilege) + return cli.trustedPush(repoInfo, ref, authConfig, requestPrivilege) } - responseBody, err := cli.imagePushPrivileged(authConfig, ref.Name(), tag, requestPrivilege) + responseBody, err := cli.imagePushPrivileged(authConfig, ref.String(), requestPrivilege) if err != nil { return err } @@ -61,16 +51,15 @@ func (cli *DockerCli) CmdPush(args ...string) error { return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut, nil) } -func (cli *DockerCli) imagePushPrivileged(authConfig types.AuthConfig, imageID, tag string, requestPrivilege client.RequestPrivilegeFunc) (io.ReadCloser, error) { +func (cli *DockerCli) imagePushPrivileged(authConfig types.AuthConfig, ref string, requestPrivilege types.RequestPrivilegeFunc) (io.ReadCloser, error) { encodedAuth, err := encodeAuthToBase64(authConfig) if err != nil { return nil, err } options := types.ImagePushOptions{ - ImageID: imageID, - Tag: tag, - RegistryAuth: encodedAuth, + RegistryAuth: encodedAuth, + PrivilegeFunc: requestPrivilege, } - return cli.client.ImagePush(context.Background(), options, requestPrivilege) + return cli.client.ImagePush(context.Background(), ref, options) } diff --git a/components/engine/api/client/rm.go b/components/engine/api/client/rm.go index c252b1f792..7b9c0a4723 100644 --- a/components/engine/api/client/rm.go +++ b/components/engine/api/client/rm.go @@ -42,14 +42,13 @@ func (cli *DockerCli) CmdRm(args ...string) error { return nil } -func (cli *DockerCli) removeContainer(containerID string, removeVolumes, removeLinks, force bool) error { +func (cli *DockerCli) removeContainer(container string, removeVolumes, removeLinks, force bool) error { options := types.ContainerRemoveOptions{ - ContainerID: containerID, RemoveVolumes: removeVolumes, RemoveLinks: removeLinks, Force: force, } - if err := cli.client.ContainerRemove(context.Background(), options); err != nil { + if err := cli.client.ContainerRemove(context.Background(), container, options); err != nil { return err } return nil diff --git a/components/engine/api/client/rmi.go b/components/engine/api/client/rmi.go index ac1b41db0b..e6bb3d4fc8 100644 --- a/components/engine/api/client/rmi.go +++ b/components/engine/api/client/rmi.go @@ -32,14 +32,13 @@ func (cli *DockerCli) CmdRmi(args ...string) error { } var errs []string - for _, name := range cmd.Args() { + for _, image := range cmd.Args() { options := types.ImageRemoveOptions{ - ImageID: name, Force: *force, PruneChildren: !*noprune, } - dels, err := cli.client.ImageRemove(context.Background(), options) + dels, err := cli.client.ImageRemove(context.Background(), image, options) if err != nil { errs = append(errs, err.Error()) } else { diff --git a/components/engine/api/client/run.go b/components/engine/api/client/run.go index 88160965bf..4b66c8c2a8 100644 --- a/components/engine/api/client/run.go +++ b/components/engine/api/client/run.go @@ -198,15 +198,14 @@ func (cli *DockerCli) CmdRun(args ...string) error { } options := types.ContainerAttachOptions{ - ContainerID: createResponse.ID, - Stream: true, - Stdin: config.AttachStdin, - Stdout: config.AttachStdout, - Stderr: config.AttachStderr, - DetachKeys: cli.configFile.DetachKeys, + Stream: true, + Stdin: config.AttachStdin, + Stdout: config.AttachStdout, + Stderr: config.AttachStderr, + DetachKeys: cli.configFile.DetachKeys, } - resp, errAttach := cli.client.ContainerAttach(context.Background(), options) + resp, errAttach := cli.client.ContainerAttach(context.Background(), createResponse.ID, options) if errAttach != nil && errAttach != httputil.ErrPersistEOF { // ContainerAttach returns an ErrPersistEOF (connection closed) // means server met an error and put it in Hijacked connection diff --git a/components/engine/api/client/search.go b/components/engine/api/client/search.go index 82deb4095e..5abd8f75bd 100644 --- a/components/engine/api/client/search.go +++ b/components/engine/api/client/search.go @@ -47,11 +47,11 @@ func (cli *DockerCli) CmdSearch(args ...string) error { } options := types.ImageSearchOptions{ - Term: name, - RegistryAuth: encodedAuth, + RegistryAuth: encodedAuth, + PrivilegeFunc: requestPrivilege, } - unorderedResults, err := cli.client.ImageSearch(context.Background(), options, requestPrivilege) + unorderedResults, err := cli.client.ImageSearch(context.Background(), name, options) if err != nil { return err } diff --git a/components/engine/api/client/start.go b/components/engine/api/client/start.go index 68274ca66a..db0f77804c 100644 --- a/components/engine/api/client/start.go +++ b/components/engine/api/client/start.go @@ -65,14 +65,14 @@ func (cli *DockerCli) CmdStart(args ...string) error { } // 2. Attach to the container. - containerID := cmd.Arg(0) - c, err := cli.client.ContainerInspect(context.Background(), containerID) + container := cmd.Arg(0) + c, err := cli.client.ContainerInspect(context.Background(), container) if err != nil { return err } if !c.Config.Tty { - sigc := cli.forwardAllSignals(containerID) + sigc := cli.forwardAllSignals(container) defer signal.StopCatch(sigc) } @@ -81,12 +81,11 @@ func (cli *DockerCli) CmdStart(args ...string) error { } options := types.ContainerAttachOptions{ - ContainerID: containerID, - Stream: true, - Stdin: *openStdin && c.Config.OpenStdin, - Stdout: true, - Stderr: true, - DetachKeys: cli.configFile.DetachKeys, + Stream: true, + Stdin: *openStdin && c.Config.OpenStdin, + Stdout: true, + Stderr: true, + DetachKeys: cli.configFile.DetachKeys, } var in io.ReadCloser @@ -95,7 +94,7 @@ func (cli *DockerCli) CmdStart(args ...string) error { in = cli.in } - resp, errAttach := cli.client.ContainerAttach(context.Background(), options) + resp, errAttach := cli.client.ContainerAttach(context.Background(), container, options) if errAttach != nil && errAttach != httputil.ErrPersistEOF { // ContainerAttach return an ErrPersistEOF (connection closed) // means server met an error and put it in Hijacked connection @@ -113,7 +112,7 @@ func (cli *DockerCli) CmdStart(args ...string) error { }) // 3. Start the container. - if err := cli.client.ContainerStart(context.Background(), containerID); err != nil { + if err := cli.client.ContainerStart(context.Background(), container); err != nil { cancelFun() <-cErr return err @@ -121,14 +120,14 @@ func (cli *DockerCli) CmdStart(args ...string) error { // 4. Wait for attachment to break. if c.Config.Tty && cli.isTerminalOut { - if err := cli.monitorTtySize(containerID, false); err != nil { + if err := cli.monitorTtySize(container, false); err != nil { fmt.Fprintf(cli.err, "Error monitoring TTY size: %s\n", err) } } if attchErr := <-cErr; attchErr != nil { return attchErr } - _, status, err := getExitCode(cli, containerID) + _, status, err := getExitCode(cli, container) if err != nil { return err } @@ -144,14 +143,14 @@ func (cli *DockerCli) CmdStart(args ...string) error { return nil } -func (cli *DockerCli) startContainersWithoutAttachments(containerIDs []string) error { +func (cli *DockerCli) startContainersWithoutAttachments(containers []string) error { var failedContainers []string - for _, containerID := range containerIDs { - if err := cli.client.ContainerStart(context.Background(), containerID); err != nil { + for _, container := range containers { + if err := cli.client.ContainerStart(context.Background(), container); err != nil { fmt.Fprintf(cli.err, "%s\n", err) - failedContainers = append(failedContainers, containerID) + failedContainers = append(failedContainers, container) } else { - fmt.Fprintf(cli.out, "%s\n", containerID) + fmt.Fprintf(cli.out, "%s\n", container) } } diff --git a/components/engine/api/client/tag.go b/components/engine/api/client/tag.go index 1d87e437c8..21fe92a5f2 100644 --- a/components/engine/api/client/tag.go +++ b/components/engine/api/client/tag.go @@ -1,13 +1,10 @@ package client import ( - "errors" - "golang.org/x/net/context" Cli "github.com/docker/docker/cli" flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/docker/reference" "github.com/docker/engine-api/types" ) @@ -21,26 +18,9 @@ func (cli *DockerCli) CmdTag(args ...string) error { cmd.ParseFlags(args, true) - ref, err := reference.ParseNamed(cmd.Arg(1)) - if err != nil { - return err - } - - if _, isCanonical := ref.(reference.Canonical); isCanonical { - return errors.New("refusing to create a tag with a digest reference") - } - - var tag string - if tagged, isTagged := ref.(reference.NamedTagged); isTagged { - tag = tagged.Tag() - } - options := types.ImageTagOptions{ - ImageID: cmd.Arg(0), - RepositoryName: ref.Name(), - Tag: tag, - Force: *force, + Force: *force, } - return cli.client.ImageTag(context.Background(), options) + return cli.client.ImageTag(context.Background(), cmd.Arg(0), cmd.Arg(1), options) } diff --git a/components/engine/api/client/trust.go b/components/engine/api/client/trust.go index bf22d3a211..4f1e4131f4 100644 --- a/components/engine/api/client/trust.go +++ b/components/engine/api/client/trust.go @@ -27,7 +27,6 @@ import ( flag "github.com/docker/docker/pkg/mflag" "github.com/docker/docker/reference" "github.com/docker/docker/registry" - apiclient "github.com/docker/engine-api/client" "github.com/docker/engine-api/types" registrytypes "github.com/docker/engine-api/types/registry" "github.com/docker/go-connections/tlsconfig" @@ -280,13 +279,10 @@ func (cli *DockerCli) tagTrusted(trustedRef reference.Canonical, ref reference.N fmt.Fprintf(cli.out, "Tagging %s as %s\n", trustedRef.String(), ref.String()) options := types.ImageTagOptions{ - ImageID: trustedRef.String(), - RepositoryName: trustedRef.Name(), - Tag: ref.Tag(), - Force: true, + Force: true, } - return cli.client.ImageTag(context.Background(), options) + return cli.client.ImageTag(context.Background(), trustedRef.String(), ref.String(), options) } func notaryError(repoName string, err error) error { @@ -319,7 +315,7 @@ func notaryError(repoName string, err error) error { return err } -func (cli *DockerCli) trustedPull(repoInfo *registry.RepositoryInfo, ref registry.Reference, authConfig types.AuthConfig, requestPrivilege apiclient.RequestPrivilegeFunc) error { +func (cli *DockerCli) trustedPull(repoInfo *registry.RepositoryInfo, ref registry.Reference, authConfig types.AuthConfig, requestPrivilege types.RequestPrivilegeFunc) error { var refs []target notaryRepo, err := cli.getNotaryRepository(repoInfo, authConfig, "pull") @@ -377,7 +373,11 @@ func (cli *DockerCli) trustedPull(repoInfo *registry.RepositoryInfo, ref registr } fmt.Fprintf(cli.out, "Pull (%d of %d): %s%s@%s\n", i+1, len(refs), repoInfo.Name(), displayTag, r.digest) - if err := cli.imagePullPrivileged(authConfig, repoInfo.Name(), r.digest.String(), requestPrivilege); err != nil { + ref, err := reference.WithDigest(repoInfo, r.digest) + if err != nil { + return err + } + if err := cli.imagePullPrivileged(authConfig, ref.String(), requestPrivilege); err != nil { return err } @@ -399,8 +399,8 @@ func (cli *DockerCli) trustedPull(repoInfo *registry.RepositoryInfo, ref registr return nil } -func (cli *DockerCli) trustedPush(repoInfo *registry.RepositoryInfo, tag string, authConfig types.AuthConfig, requestPrivilege apiclient.RequestPrivilegeFunc) error { - responseBody, err := cli.imagePushPrivileged(authConfig, repoInfo.Name(), tag, requestPrivilege) +func (cli *DockerCli) trustedPush(repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig types.AuthConfig, requestPrivilege types.RequestPrivilegeFunc) error { + responseBody, err := cli.imagePushPrivileged(authConfig, ref.String(), requestPrivilege) if err != nil { return err } @@ -434,6 +434,14 @@ func (cli *DockerCli) trustedPush(repoInfo *registry.RepositoryInfo, tag string, } } + var tag string + switch x := ref.(type) { + case reference.Canonical: + return errors.New("cannot push a digest reference") + case reference.NamedTagged: + tag = x.Tag() + } + // We want trust signatures to always take an explicit tag, // otherwise it will act as an untrusted push. if tag == "" { diff --git a/components/engine/api/client/utils.go b/components/engine/api/client/utils.go index 4deee22410..e9ed915821 100644 --- a/components/engine/api/client/utils.go +++ b/components/engine/api/client/utils.go @@ -46,7 +46,7 @@ func encodeAuthToBase64(authConfig types.AuthConfig) (string, error) { return base64.URLEncoding.EncodeToString(buf), nil } -func (cli *DockerCli) registryAuthenticationPrivilegedFunc(index *registrytypes.IndexInfo, cmdName string) client.RequestPrivilegeFunc { +func (cli *DockerCli) registryAuthenticationPrivilegedFunc(index *registrytypes.IndexInfo, cmdName string) types.RequestPrivilegeFunc { return func() (string, error) { fmt.Fprintf(cli.out, "\nPlease login prior to %s:\n", cmdName) indexServer := registry.GetAuthConfigKey(index) @@ -69,16 +69,15 @@ func (cli *DockerCli) resizeTtyTo(id string, height, width int, isExec bool) { } options := types.ResizeOptions{ - ID: id, Height: height, Width: width, } var err error if isExec { - err = cli.client.ContainerExecResize(context.Background(), options) + err = cli.client.ContainerExecResize(context.Background(), id, options) } else { - err = cli.client.ContainerResize(context.Background(), options) + err = cli.client.ContainerResize(context.Background(), id, options) } if err != nil { diff --git a/components/engine/api/server/router/container/backend.go b/components/engine/api/server/router/container/backend.go index 744d26389a..67d2cb2d47 100644 --- a/components/engine/api/server/router/container/backend.go +++ b/components/engine/api/server/router/container/backend.go @@ -15,7 +15,7 @@ import ( // execBackend includes functions to implement to provide exec functionality. type execBackend interface { - ContainerExecCreate(config *types.ExecConfig) (string, error) + ContainerExecCreate(name string, config *types.ExecConfig) (string, error) ContainerExecInspect(id string) (*backend.ExecInspect, error) ContainerExecResize(name string, height, width int) error ContainerExecStart(name string, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) error diff --git a/components/engine/api/server/router/container/exec.go b/components/engine/api/server/router/container/exec.go index 80f377e890..c077141ac5 100644 --- a/components/engine/api/server/router/container/exec.go +++ b/components/engine/api/server/router/container/exec.go @@ -36,14 +36,13 @@ func (s *containerRouter) postContainerExecCreate(ctx context.Context, w http.Re if err := json.NewDecoder(r.Body).Decode(execConfig); err != nil { return err } - execConfig.Container = name if len(execConfig.Cmd) == 0 { return fmt.Errorf("No exec command specified") } // Register an instance of Exec in container. - id, err := s.backend.ContainerExecCreate(execConfig) + id, err := s.backend.ContainerExecCreate(name, execConfig) if err != nil { logrus.Errorf("Error setting up exec command in container %s: %v", name, err) return err diff --git a/components/engine/api/server/router/network/backend.go b/components/engine/api/server/router/network/backend.go index bf5af0625f..4873e1ea28 100644 --- a/components/engine/api/server/router/network/backend.go +++ b/components/engine/api/server/router/network/backend.go @@ -14,7 +14,7 @@ type Backend interface { GetNetworkByName(idName string) (libnetwork.Network, error) GetNetworksByID(partialID string) []libnetwork.Network FilterNetworks(netFilters filters.Args) ([]libnetwork.Network, error) - CreateNetwork(types.NetworkCreate) (*types.NetworkCreateResponse, error) + CreateNetwork(nc types.NetworkCreateRequest) (*types.NetworkCreateResponse, error) ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error DisconnectContainerFromNetwork(containerName string, network libnetwork.Network, force bool) error DeleteNetwork(name string) error diff --git a/components/engine/api/server/router/network/network_routes.go b/components/engine/api/server/router/network/network_routes.go index dd4a28f3a5..8da6de1577 100644 --- a/components/engine/api/server/router/network/network_routes.go +++ b/components/engine/api/server/router/network/network_routes.go @@ -51,7 +51,7 @@ func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r } func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - var create types.NetworkCreate + var create types.NetworkCreateRequest if err := httputils.ParseForm(r); err != nil { return err diff --git a/components/engine/daemon/exec.go b/components/engine/daemon/exec.go index 2160fe4e1d..e58205361e 100644 --- a/components/engine/daemon/exec.go +++ b/components/engine/daemon/exec.go @@ -88,8 +88,8 @@ func (d *Daemon) getActiveContainer(name string) (*container.Container, error) { } // ContainerExecCreate sets up an exec in a running container. -func (d *Daemon) ContainerExecCreate(config *types.ExecConfig) (string, error) { - container, err := d.getActiveContainer(config.Container) +func (d *Daemon) ContainerExecCreate(name string, config *types.ExecConfig) (string, error) { + container, err := d.getActiveContainer(name) if err != nil { return "", err } diff --git a/components/engine/daemon/network.go b/components/engine/daemon/network.go index a9338d1252..80efdde3bc 100644 --- a/components/engine/daemon/network.go +++ b/components/engine/daemon/network.go @@ -94,7 +94,7 @@ func (daemon *Daemon) getAllNetworks() []libnetwork.Network { } // CreateNetwork creates a network with the given name, driver and other optional parameters -func (daemon *Daemon) CreateNetwork(create types.NetworkCreate) (*types.NetworkCreateResponse, error) { +func (daemon *Daemon) CreateNetwork(create types.NetworkCreateRequest) (*types.NetworkCreateResponse, error) { if runconfig.IsPreDefinedNetwork(create.Name) { err := fmt.Errorf("%s is a pre-defined network and cannot be created", create.Name) return nil, errors.NewErrorWithStatusCode(err, http.StatusForbidden) diff --git a/components/engine/integration-cli/docker_api_network_test.go b/components/engine/integration-cli/docker_api_network_test.go index b11803f9b9..13d2677b88 100644 --- a/components/engine/integration-cli/docker_api_network_test.go +++ b/components/engine/integration-cli/docker_api_network_test.go @@ -28,9 +28,11 @@ func (s *DockerSuite) TestApiNetworkCreateDelete(c *check.C) { testRequires(c, DaemonIsLinux) // Create a network name := "testnetwork" - config := types.NetworkCreate{ - Name: name, - CheckDuplicate: true, + config := types.NetworkCreateRequest{ + Name: name, + NetworkCreate: types.NetworkCreate{ + CheckDuplicate: true, + }, } id := createNetwork(c, config, true) c.Assert(isNetworkAvailable(c, name), checker.Equals, true) @@ -43,13 +45,17 @@ func (s *DockerSuite) TestApiNetworkCreateDelete(c *check.C) { func (s *DockerSuite) TestApiNetworkCreateCheckDuplicate(c *check.C) { testRequires(c, DaemonIsLinux) name := "testcheckduplicate" - configOnCheck := types.NetworkCreate{ - Name: name, - CheckDuplicate: true, + configOnCheck := types.NetworkCreateRequest{ + Name: name, + NetworkCreate: types.NetworkCreate{ + CheckDuplicate: true, + }, } - configNotCheck := types.NetworkCreate{ - Name: name, - CheckDuplicate: false, + configNotCheck := types.NetworkCreateRequest{ + Name: name, + NetworkCreate: types.NetworkCreate{ + CheckDuplicate: false, + }, } // Creating a new network first @@ -99,11 +105,13 @@ func (s *DockerSuite) TestApiNetworkInspect(c *check.C) { Driver: "default", Config: []network.IPAMConfig{{Subnet: "172.28.0.0/16", IPRange: "172.28.5.0/24", Gateway: "172.28.5.254"}}, } - config := types.NetworkCreate{ - Name: "br0", - Driver: "bridge", - IPAM: ipam, - Options: map[string]string{"foo": "bar", "opts": "dopts"}, + config := types.NetworkCreateRequest{ + Name: "br0", + NetworkCreate: types.NetworkCreate{ + Driver: "bridge", + IPAM: ipam, + Options: map[string]string{"foo": "bar", "opts": "dopts"}, + }, } id0 := createNetwork(c, config, true) c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, true) @@ -125,7 +133,7 @@ func (s *DockerSuite) TestApiNetworkConnectDisconnect(c *check.C) { testRequires(c, DaemonIsLinux) // Create test network name := "testnetwork" - config := types.NetworkCreate{ + config := types.NetworkCreateRequest{ Name: name, } id := createNetwork(c, config, true) @@ -169,10 +177,12 @@ func (s *DockerSuite) TestApiNetworkIpamMultipleBridgeNetworks(c *check.C) { Driver: "default", Config: []network.IPAMConfig{{Subnet: "192.178.0.0/16", IPRange: "192.178.128.0/17", Gateway: "192.178.138.100"}}, } - config0 := types.NetworkCreate{ - Name: "test0", - Driver: "bridge", - IPAM: ipam0, + config0 := types.NetworkCreateRequest{ + Name: "test0", + NetworkCreate: types.NetworkCreate{ + Driver: "bridge", + IPAM: ipam0, + }, } id0 := createNetwork(c, config0, true) c.Assert(isNetworkAvailable(c, "test0"), checker.Equals, true) @@ -182,10 +192,12 @@ func (s *DockerSuite) TestApiNetworkIpamMultipleBridgeNetworks(c *check.C) { Config: []network.IPAMConfig{{Subnet: "192.178.128.0/17", Gateway: "192.178.128.1"}}, } // test1 bridge network overlaps with test0 - config1 := types.NetworkCreate{ - Name: "test1", - Driver: "bridge", - IPAM: ipam1, + config1 := types.NetworkCreateRequest{ + Name: "test1", + NetworkCreate: types.NetworkCreate{ + Driver: "bridge", + IPAM: ipam1, + }, } createNetwork(c, config1, false) c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, false) @@ -195,10 +207,12 @@ func (s *DockerSuite) TestApiNetworkIpamMultipleBridgeNetworks(c *check.C) { Config: []network.IPAMConfig{{Subnet: "192.169.0.0/16", Gateway: "192.169.100.100"}}, } // test2 bridge network does not overlap - config2 := types.NetworkCreate{ - Name: "test2", - Driver: "bridge", - IPAM: ipam2, + config2 := types.NetworkCreateRequest{ + Name: "test2", + NetworkCreate: types.NetworkCreate{ + Driver: "bridge", + IPAM: ipam2, + }, } createNetwork(c, config2, true) c.Assert(isNetworkAvailable(c, "test2"), checker.Equals, true) @@ -209,11 +223,11 @@ func (s *DockerSuite) TestApiNetworkIpamMultipleBridgeNetworks(c *check.C) { c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, true) // for networks w/o ipam specified, docker will choose proper non-overlapping subnets - createNetwork(c, types.NetworkCreate{Name: "test3"}, true) + createNetwork(c, types.NetworkCreateRequest{Name: "test3"}, true) c.Assert(isNetworkAvailable(c, "test3"), checker.Equals, true) - createNetwork(c, types.NetworkCreate{Name: "test4"}, true) + createNetwork(c, types.NetworkCreateRequest{Name: "test4"}, true) c.Assert(isNetworkAvailable(c, "test4"), checker.Equals, true) - createNetwork(c, types.NetworkCreate{Name: "test5"}, true) + createNetwork(c, types.NetworkCreateRequest{Name: "test5"}, true) c.Assert(isNetworkAvailable(c, "test5"), checker.Equals, true) for i := 1; i < 6; i++ { @@ -230,9 +244,11 @@ func (s *DockerSuite) TestApiCreateDeletePredefinedNetworks(c *check.C) { func createDeletePredefinedNetwork(c *check.C, name string) { // Create pre-defined network - config := types.NetworkCreate{ - Name: name, - CheckDuplicate: true, + config := types.NetworkCreateRequest{ + Name: name, + NetworkCreate: types.NetworkCreate{ + CheckDuplicate: true, + }, } shouldSucceed := false createNetwork(c, config, shouldSucceed) @@ -289,7 +305,7 @@ func getNetworkResource(c *check.C, id string) *types.NetworkResource { return &nr } -func createNetwork(c *check.C, config types.NetworkCreate, shouldSucceed bool) string { +func createNetwork(c *check.C, config types.NetworkCreateRequest, shouldSucceed bool) string { status, resp, err := sockRequest("POST", "/networks/create", config) if !shouldSucceed { c.Assert(status, checker.Not(checker.Equals), http.StatusCreated)