Ver código fonte

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 <vincent@sbr.pm>
Vincent Demeester 9 anos atrás
pai
commit
b9c94b70bf

+ 10 - 9
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
 	}

+ 1 - 2
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
 	}

+ 9 - 32
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
 	}

+ 2 - 11
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
 	}

+ 3 - 5
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: <name|uid>[:<group|gid>])")
 		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,
 	}
 

+ 0 - 8
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
 	}

+ 16 - 21
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
 	}
 
+	source := types.ImageImportSource{
+		Source:     in,
+		SourceName: srcName,
+	}
+
 	options := types.ImageImportOptions{
-		Source:         in,
-		SourceName:     srcName,
-		RepositoryName: repository,
-		Message:        *message,
-		Tag:            tag,
-		Changes:        changes,
+		Message: *message,
+		Tag:     tag,
+		Changes: changes,
 	}
 
-	responseBody, err := cli.client.ImageImport(context.Background(), options)
+	responseBody, err := cli.client.ImageImport(context.Background(), source, ref, options)
 	if err != nil {
 		return err
 	}

+ 7 - 8
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
 	}

+ 1 - 2
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
 	}

+ 8 - 10
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
 	}

+ 6 - 17
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)
 }

+ 2 - 3
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

+ 2 - 3
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 {

+ 6 - 7
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

+ 3 - 3
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
 	}

+ 17 - 18
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)
 		}
 	}
 

+ 2 - 22
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)
 }

+ 18 - 10
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 == "" {

+ 3 - 4
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 {

+ 1 - 1
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

+ 1 - 2
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

+ 1 - 1
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

+ 1 - 1
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

+ 2 - 2
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
 	}

+ 1 - 1
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)

+ 50 - 34
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)