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>
This commit is contained in:
Vincent Demeester 2016-04-13 10:33:46 +02:00
parent 9802d7d10f
commit b9c94b70bf
No known key found for this signature in database
GPG Key ID: 083CC6FD6EB699A3
26 changed files with 174 additions and 238 deletions

View File

@ -48,8 +48,9 @@ func (cli *DockerCli) CmdAttach(args ...string) error {
cli.configFile.DetachKeys = *detachKeys cli.configFile.DetachKeys = *detachKeys
} }
container := cmd.Arg(0)
options := types.ContainerAttachOptions{ options := types.ContainerAttachOptions{
ContainerID: cmd.Arg(0),
Stream: true, Stream: true,
Stdin: !*noStdin && c.Config.OpenStdin, Stdin: !*noStdin && c.Config.OpenStdin,
Stdout: true, Stdout: true,
@ -63,11 +64,11 @@ func (cli *DockerCli) CmdAttach(args ...string) error {
} }
if *proxy && !c.Config.Tty { if *proxy && !c.Config.Tty {
sigc := cli.forwardAllSignals(options.ContainerID) sigc := cli.forwardAllSignals(container)
defer signal.StopCatch(sigc) 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 { if errAttach != nil && errAttach != httputil.ErrPersistEOF {
// ContainerAttach returns an ErrPersistEOF (connection closed) // ContainerAttach returns an ErrPersistEOF (connection closed)
// means server met an error and put it in Hijacked connection // means server met an error and put it in Hijacked connection
@ -98,7 +99,7 @@ func (cli *DockerCli) CmdAttach(args ...string) error {
return errAttach return errAttach
} }
_, status, err := getExitCode(cli, options.ContainerID) _, status, err := getExitCode(cli, container)
if err != nil { if err != nil {
return err return err
} }

View File

@ -212,7 +212,6 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
} }
options := types.ImageBuildOptions{ options := types.ImageBuildOptions{
Context: body,
Memory: memory, Memory: memory,
MemorySwap: memorySwap, MemorySwap: memorySwap,
Tags: flTags.GetAll(), Tags: flTags.GetAll(),
@ -236,7 +235,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
Labels: runconfigopts.ConvertKVStringsToMap(flLabels.GetAll()), 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 { if err != nil {
return err return err
} }

View File

@ -2,7 +2,6 @@ package client
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -10,7 +9,6 @@ import (
Cli "github.com/docker/docker/cli" Cli "github.com/docker/docker/cli"
"github.com/docker/docker/opts" "github.com/docker/docker/opts"
flag "github.com/docker/docker/pkg/mflag" flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/reference"
"github.com/docker/engine-api/types" "github.com/docker/engine-api/types"
"github.com/docker/engine-api/types/container" "github.com/docker/engine-api/types/container"
) )
@ -34,28 +32,9 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
var ( var (
name = cmd.Arg(0) name = cmd.Arg(0)
repositoryAndTag = cmd.Arg(1) reference = cmd.Arg(1)
repositoryName string
tag string
) )
//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 var config *container.Config
if *flConfig != "" { if *flConfig != "" {
config = &container.Config{} config = &container.Config{}
@ -65,9 +44,7 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
} }
options := types.ContainerCommitOptions{ options := types.ContainerCommitOptions{
ContainerID: name, Reference: reference,
RepositoryName: repositoryName,
Tag: tag,
Comment: *flComment, Comment: *flComment,
Author: *flAuthor, Author: *flAuthor,
Changes: flChanges.GetAll(), Changes: flChanges.GetAll(),
@ -75,7 +52,7 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
Config: config, Config: config,
} }
response, err := cli.client.ContainerCommit(context.Background(), options) response, err := cli.client.ContainerCommit(context.Background(), name, options)
if err != nil { if err != nil {
return err return err
} }

View File

@ -9,6 +9,7 @@ import (
Cli "github.com/docker/docker/cli" Cli "github.com/docker/docker/cli"
"github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/jsonmessage"
// FIXME migrate to docker/distribution/reference
"github.com/docker/docker/reference" "github.com/docker/docker/reference"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
runconfigopts "github.com/docker/docker/runconfig/opts" runconfigopts "github.com/docker/docker/runconfig/opts"
@ -24,14 +25,6 @@ func (cli *DockerCli) pullImage(image string, out io.Writer) error {
return err 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 // Resolve the Repository name from fqn to RepositoryInfo
repoInfo, err := registry.ParseRepositoryInfo(ref) repoInfo, err := registry.ParseRepositoryInfo(ref)
if err != nil { if err != nil {
@ -45,12 +38,10 @@ func (cli *DockerCli) pullImage(image string, out io.Writer) error {
} }
options := types.ImageCreateOptions{ options := types.ImageCreateOptions{
Parent: ref.Name(),
Tag: tag,
RegistryAuth: encodedAuth, RegistryAuth: encodedAuth,
} }
responseBody, err := cli.client.ImageCreate(context.Background(), options) responseBody, err := cli.client.ImageCreate(context.Background(), image, options)
if err != nil { if err != nil {
return err return err
} }

View File

@ -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") detachKeys := cmd.String([]string{"-detach-keys"}, "", "Override the key sequence for detaching a container")
execConfig, err := ParseExec(cmd, args) execConfig, err := ParseExec(cmd, args)
container := cmd.Arg(0)
// just in case the ParseExec does not exit // just in case the ParseExec does not exit
if execConfig.Container == "" || err != nil { if container == "" || err != nil {
return Cli.StatusError{StatusCode: 1} return Cli.StatusError{StatusCode: 1}
} }
@ -33,7 +34,7 @@ func (cli *DockerCli) CmdExec(args ...string) error {
// Send client escape keys // Send client escape keys
execConfig.DetachKeys = cli.configFile.DetachKeys 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 { if err != nil {
return err 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>])") 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") flPrivileged = cmd.Bool([]string{"-privileged"}, false, "Give extended privileges to the command")
execCmd []string execCmd []string
container string
) )
cmd.Require(flag.Min, 2) cmd.Require(flag.Min, 2)
if err := cmd.ParseFlags(args, true); err != nil { if err := cmd.ParseFlags(args, true); err != nil {
return nil, err return nil, err
} }
container = cmd.Arg(0)
parsedArgs := cmd.Args() parsedArgs := cmd.Args()
execCmd = parsedArgs[1:] execCmd = parsedArgs[1:]
@ -143,7 +142,6 @@ func ParseExec(cmd *flag.FlagSet, args []string) (*types.ExecConfig, error) {
Privileged: *flPrivileged, Privileged: *flPrivileged,
Tty: *flTty, Tty: *flTty,
Cmd: execCmd, Cmd: execCmd,
Container: container,
Detach: *flDetach, Detach: *flDetach,
} }

View File

@ -23,7 +23,6 @@ func TestParseExec(t *testing.T) {
&arguments{ &arguments{
[]string{"container", "command"}, []string{"container", "command"},
}: { }: {
Container: "container",
Cmd: []string{"command"}, Cmd: []string{"command"},
AttachStdout: true, AttachStdout: true,
AttachStderr: true, AttachStderr: true,
@ -31,7 +30,6 @@ func TestParseExec(t *testing.T) {
&arguments{ &arguments{
[]string{"container", "command1", "command2"}, []string{"container", "command1", "command2"},
}: { }: {
Container: "container",
Cmd: []string{"command1", "command2"}, Cmd: []string{"command1", "command2"},
AttachStdout: true, AttachStdout: true,
AttachStderr: true, AttachStderr: true,
@ -44,7 +42,6 @@ func TestParseExec(t *testing.T) {
AttachStdout: true, AttachStdout: true,
AttachStderr: true, AttachStderr: true,
Tty: true, Tty: true,
Container: "container",
Cmd: []string{"command"}, Cmd: []string{"command"},
}, },
&arguments{ &arguments{
@ -54,7 +51,6 @@ func TestParseExec(t *testing.T) {
AttachStdout: false, AttachStdout: false,
AttachStderr: false, AttachStderr: false,
Detach: true, Detach: true,
Container: "container",
Cmd: []string{"command"}, Cmd: []string{"command"},
}, },
&arguments{ &arguments{
@ -65,7 +61,6 @@ func TestParseExec(t *testing.T) {
AttachStderr: false, AttachStderr: false,
Detach: true, Detach: true,
Tty: true, Tty: true,
Container: "container",
Cmd: []string{"command"}, Cmd: []string{"command"},
}, },
} }
@ -103,9 +98,6 @@ func compareExecConfig(config1 *types.ExecConfig, config2 *types.ExecConfig) boo
if config1.AttachStdout != config2.AttachStdout { if config1.AttachStdout != config2.AttachStdout {
return false return false
} }
if config1.Container != config2.Container {
return false
}
if config1.Detach != config2.Detach { if config1.Detach != config2.Detach {
return false return false
} }

View File

@ -12,7 +12,6 @@ import (
"github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/jsonmessage"
flag "github.com/docker/docker/pkg/mflag" flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/urlutil" "github.com/docker/docker/pkg/urlutil"
"github.com/docker/docker/reference"
"github.com/docker/engine-api/types" "github.com/docker/engine-api/types"
) )
@ -35,22 +34,16 @@ func (cli *DockerCli) CmdImport(args ...string) error {
tag string tag string
src = cmd.Arg(0) src = cmd.Arg(0)
srcName = src srcName = src
repository = cmd.Arg(1) ref = cmd.Arg(1)
changes = flChanges.GetAll() changes = flChanges.GetAll()
) )
if cmd.NArg() == 3 { 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") 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) 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 == "-" { if src == "-" {
in = cli.in in = cli.in
} else if !urlutil.IsURL(src) { } else if !urlutil.IsURL(src) {
@ -63,16 +56,18 @@ func (cli *DockerCli) CmdImport(args ...string) error {
in = file in = file
} }
options := types.ImageImportOptions{ source := types.ImageImportSource{
Source: in, Source: in,
SourceName: srcName, SourceName: srcName,
RepositoryName: repository, }
options := types.ImageImportOptions{
Message: *message, Message: *message,
Tag: tag, Tag: tag,
Changes: changes, Changes: changes,
} }
responseBody, err := cli.client.ImageImport(context.Background(), options) responseBody, err := cli.client.ImageImport(context.Background(), source, ref, options)
if err != nil { if err != nil {
return err return err
} }

View File

@ -42,7 +42,6 @@ func (cli *DockerCli) CmdLogs(args ...string) error {
} }
options := types.ContainerLogsOptions{ options := types.ContainerLogsOptions{
ContainerID: name,
ShowStdout: true, ShowStdout: true,
ShowStderr: true, ShowStderr: true,
Since: *since, Since: *since,
@ -50,7 +49,7 @@ func (cli *DockerCli) CmdLogs(args ...string) error {
Follow: *follow, Follow: *follow,
Tail: *tail, Tail: *tail,
} }
responseBody, err := cli.client.ContainerLogs(context.Background(), options) responseBody, err := cli.client.ContainerLogs(context.Background(), name, options)
if err != nil { if err != nil {
return err return err
} }

View File

@ -77,7 +77,6 @@ func (cli *DockerCli) CmdNetworkCreate(args ...string) error {
// Construct network create request body // Construct network create request body
nc := types.NetworkCreate{ nc := types.NetworkCreate{
Name: cmd.Arg(0),
Driver: driver, Driver: driver,
IPAM: network.IPAM{Driver: *flIpamDriver, Config: ipamCfg, Options: flIpamOpt.GetAll()}, IPAM: network.IPAM{Driver: *flIpamDriver, Config: ipamCfg, Options: flIpamOpt.GetAll()},
Options: flOpts.GetAll(), Options: flOpts.GetAll(),
@ -87,7 +86,7 @@ func (cli *DockerCli) CmdNetworkCreate(args ...string) error {
Labels: runconfigopts.ConvertKVStringsToMap(flLabels.GetAll()), 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 { if err != nil {
return err return err
} }

View File

@ -11,7 +11,6 @@ import (
flag "github.com/docker/docker/pkg/mflag" flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/reference" "github.com/docker/docker/reference"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
"github.com/docker/engine-api/client"
"github.com/docker/engine-api/types" "github.com/docker/engine-api/types"
) )
@ -48,7 +47,7 @@ func (cli *DockerCli) CmdPull(args ...string) error {
tag = x.Tag() tag = x.Tag()
} }
ref := registry.ParseReference(tag) registryRef := registry.ParseReference(tag)
// Resolve the Repository name from fqn to RepositoryInfo // Resolve the Repository name from fqn to RepositoryInfo
repoInfo, err := registry.ParseRepositoryInfo(distributionRef) repoInfo, err := registry.ParseRepositoryInfo(distributionRef)
@ -59,27 +58,26 @@ func (cli *DockerCli) CmdPull(args ...string) error {
authConfig := cli.resolveAuthConfig(repoInfo.Index) authConfig := cli.resolveAuthConfig(repoInfo.Index)
requestPrivilege := cli.registryAuthenticationPrivilegedFunc(repoInfo.Index, "pull") requestPrivilege := cli.registryAuthenticationPrivilegedFunc(repoInfo.Index, "pull")
if isTrusted() && !ref.HasDigest() { if isTrusted() && !registryRef.HasDigest() {
// Check if tag is digest // 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) encodedAuth, err := encodeAuthToBase64(authConfig)
if err != nil { if err != nil {
return err return err
} }
options := types.ImagePullOptions{ 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 { if err != nil {
return err return err
} }

View File

@ -1,7 +1,6 @@
package client package client
import ( import (
"errors"
"io" "io"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -11,7 +10,6 @@ import (
flag "github.com/docker/docker/pkg/mflag" flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/reference" "github.com/docker/docker/reference"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
"github.com/docker/engine-api/client"
"github.com/docker/engine-api/types" "github.com/docker/engine-api/types"
) )
@ -30,14 +28,6 @@ func (cli *DockerCli) CmdPush(args ...string) error {
return err 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 // Resolve the Repository name from fqn to RepositoryInfo
repoInfo, err := registry.ParseRepositoryInfo(ref) repoInfo, err := registry.ParseRepositoryInfo(ref)
if err != nil { if err != nil {
@ -48,10 +38,10 @@ func (cli *DockerCli) CmdPush(args ...string) error {
requestPrivilege := cli.registryAuthenticationPrivilegedFunc(repoInfo.Index, "push") requestPrivilege := cli.registryAuthenticationPrivilegedFunc(repoInfo.Index, "push")
if isTrusted() { 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 { if err != nil {
return err return err
} }
@ -61,16 +51,15 @@ func (cli *DockerCli) CmdPush(args ...string) error {
return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut, nil) 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) encodedAuth, err := encodeAuthToBase64(authConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
options := types.ImagePushOptions{ 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)
} }

View File

@ -42,14 +42,13 @@ func (cli *DockerCli) CmdRm(args ...string) error {
return nil 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{ options := types.ContainerRemoveOptions{
ContainerID: containerID,
RemoveVolumes: removeVolumes, RemoveVolumes: removeVolumes,
RemoveLinks: removeLinks, RemoveLinks: removeLinks,
Force: force, 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 err
} }
return nil return nil

View File

@ -32,14 +32,13 @@ func (cli *DockerCli) CmdRmi(args ...string) error {
} }
var errs []string var errs []string
for _, name := range cmd.Args() { for _, image := range cmd.Args() {
options := types.ImageRemoveOptions{ options := types.ImageRemoveOptions{
ImageID: name,
Force: *force, Force: *force,
PruneChildren: !*noprune, PruneChildren: !*noprune,
} }
dels, err := cli.client.ImageRemove(context.Background(), options) dels, err := cli.client.ImageRemove(context.Background(), image, options)
if err != nil { if err != nil {
errs = append(errs, err.Error()) errs = append(errs, err.Error())
} else { } else {

View File

@ -198,7 +198,6 @@ func (cli *DockerCli) CmdRun(args ...string) error {
} }
options := types.ContainerAttachOptions{ options := types.ContainerAttachOptions{
ContainerID: createResponse.ID,
Stream: true, Stream: true,
Stdin: config.AttachStdin, Stdin: config.AttachStdin,
Stdout: config.AttachStdout, Stdout: config.AttachStdout,
@ -206,7 +205,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
DetachKeys: cli.configFile.DetachKeys, 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 { if errAttach != nil && errAttach != httputil.ErrPersistEOF {
// ContainerAttach returns an ErrPersistEOF (connection closed) // ContainerAttach returns an ErrPersistEOF (connection closed)
// means server met an error and put it in Hijacked connection // means server met an error and put it in Hijacked connection

View File

@ -47,11 +47,11 @@ func (cli *DockerCli) CmdSearch(args ...string) error {
} }
options := types.ImageSearchOptions{ 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 { if err != nil {
return err return err
} }

View File

@ -65,14 +65,14 @@ func (cli *DockerCli) CmdStart(args ...string) error {
} }
// 2. Attach to the container. // 2. Attach to the container.
containerID := cmd.Arg(0) container := cmd.Arg(0)
c, err := cli.client.ContainerInspect(context.Background(), containerID) c, err := cli.client.ContainerInspect(context.Background(), container)
if err != nil { if err != nil {
return err return err
} }
if !c.Config.Tty { if !c.Config.Tty {
sigc := cli.forwardAllSignals(containerID) sigc := cli.forwardAllSignals(container)
defer signal.StopCatch(sigc) defer signal.StopCatch(sigc)
} }
@ -81,7 +81,6 @@ func (cli *DockerCli) CmdStart(args ...string) error {
} }
options := types.ContainerAttachOptions{ options := types.ContainerAttachOptions{
ContainerID: containerID,
Stream: true, Stream: true,
Stdin: *openStdin && c.Config.OpenStdin, Stdin: *openStdin && c.Config.OpenStdin,
Stdout: true, Stdout: true,
@ -95,7 +94,7 @@ func (cli *DockerCli) CmdStart(args ...string) error {
in = cli.in 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 { if errAttach != nil && errAttach != httputil.ErrPersistEOF {
// ContainerAttach return an ErrPersistEOF (connection closed) // ContainerAttach return an ErrPersistEOF (connection closed)
// means server met an error and put it in Hijacked connection // 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. // 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() cancelFun()
<-cErr <-cErr
return err return err
@ -121,14 +120,14 @@ func (cli *DockerCli) CmdStart(args ...string) error {
// 4. Wait for attachment to break. // 4. Wait for attachment to break.
if c.Config.Tty && cli.isTerminalOut { 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) fmt.Fprintf(cli.err, "Error monitoring TTY size: %s\n", err)
} }
} }
if attchErr := <-cErr; attchErr != nil { if attchErr := <-cErr; attchErr != nil {
return attchErr return attchErr
} }
_, status, err := getExitCode(cli, containerID) _, status, err := getExitCode(cli, container)
if err != nil { if err != nil {
return err return err
} }
@ -144,14 +143,14 @@ func (cli *DockerCli) CmdStart(args ...string) error {
return nil return nil
} }
func (cli *DockerCli) startContainersWithoutAttachments(containerIDs []string) error { func (cli *DockerCli) startContainersWithoutAttachments(containers []string) error {
var failedContainers []string var failedContainers []string
for _, containerID := range containerIDs { for _, container := range containers {
if err := cli.client.ContainerStart(context.Background(), containerID); err != nil { if err := cli.client.ContainerStart(context.Background(), container); err != nil {
fmt.Fprintf(cli.err, "%s\n", err) fmt.Fprintf(cli.err, "%s\n", err)
failedContainers = append(failedContainers, containerID) failedContainers = append(failedContainers, container)
} else { } else {
fmt.Fprintf(cli.out, "%s\n", containerID) fmt.Fprintf(cli.out, "%s\n", container)
} }
} }

View File

@ -1,13 +1,10 @@
package client package client
import ( import (
"errors"
"golang.org/x/net/context" "golang.org/x/net/context"
Cli "github.com/docker/docker/cli" Cli "github.com/docker/docker/cli"
flag "github.com/docker/docker/pkg/mflag" flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/reference"
"github.com/docker/engine-api/types" "github.com/docker/engine-api/types"
) )
@ -21,26 +18,9 @@ func (cli *DockerCli) CmdTag(args ...string) error {
cmd.ParseFlags(args, true) 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{ 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)
} }

View File

@ -27,7 +27,6 @@ import (
flag "github.com/docker/docker/pkg/mflag" flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/reference" "github.com/docker/docker/reference"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
apiclient "github.com/docker/engine-api/client"
"github.com/docker/engine-api/types" "github.com/docker/engine-api/types"
registrytypes "github.com/docker/engine-api/types/registry" registrytypes "github.com/docker/engine-api/types/registry"
"github.com/docker/go-connections/tlsconfig" "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()) fmt.Fprintf(cli.out, "Tagging %s as %s\n", trustedRef.String(), ref.String())
options := types.ImageTagOptions{ 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 { func notaryError(repoName string, err error) error {
@ -319,7 +315,7 @@ func notaryError(repoName string, err error) error {
return err 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 var refs []target
notaryRepo, err := cli.getNotaryRepository(repoInfo, authConfig, "pull") 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) 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 return err
} }
@ -399,8 +399,8 @@ func (cli *DockerCli) trustedPull(repoInfo *registry.RepositoryInfo, ref registr
return nil return nil
} }
func (cli *DockerCli) trustedPush(repoInfo *registry.RepositoryInfo, tag string, authConfig types.AuthConfig, requestPrivilege apiclient.RequestPrivilegeFunc) error { func (cli *DockerCli) trustedPush(repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig types.AuthConfig, requestPrivilege types.RequestPrivilegeFunc) error {
responseBody, err := cli.imagePushPrivileged(authConfig, repoInfo.Name(), tag, requestPrivilege) responseBody, err := cli.imagePushPrivileged(authConfig, ref.String(), requestPrivilege)
if err != nil { if err != nil {
return err 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, // We want trust signatures to always take an explicit tag,
// otherwise it will act as an untrusted push. // otherwise it will act as an untrusted push.
if tag == "" { if tag == "" {

View File

@ -46,7 +46,7 @@ func encodeAuthToBase64(authConfig types.AuthConfig) (string, error) {
return base64.URLEncoding.EncodeToString(buf), nil 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) { return func() (string, error) {
fmt.Fprintf(cli.out, "\nPlease login prior to %s:\n", cmdName) fmt.Fprintf(cli.out, "\nPlease login prior to %s:\n", cmdName)
indexServer := registry.GetAuthConfigKey(index) indexServer := registry.GetAuthConfigKey(index)
@ -69,16 +69,15 @@ func (cli *DockerCli) resizeTtyTo(id string, height, width int, isExec bool) {
} }
options := types.ResizeOptions{ options := types.ResizeOptions{
ID: id,
Height: height, Height: height,
Width: width, Width: width,
} }
var err error var err error
if isExec { if isExec {
err = cli.client.ContainerExecResize(context.Background(), options) err = cli.client.ContainerExecResize(context.Background(), id, options)
} else { } else {
err = cli.client.ContainerResize(context.Background(), options) err = cli.client.ContainerResize(context.Background(), id, options)
} }
if err != nil { if err != nil {

View File

@ -15,7 +15,7 @@ import (
// execBackend includes functions to implement to provide exec functionality. // execBackend includes functions to implement to provide exec functionality.
type execBackend interface { type execBackend interface {
ContainerExecCreate(config *types.ExecConfig) (string, error) ContainerExecCreate(name string, config *types.ExecConfig) (string, error)
ContainerExecInspect(id string) (*backend.ExecInspect, error) ContainerExecInspect(id string) (*backend.ExecInspect, error)
ContainerExecResize(name string, height, width int) error ContainerExecResize(name string, height, width int) error
ContainerExecStart(name string, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) error ContainerExecStart(name string, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) error

View File

@ -36,14 +36,13 @@ func (s *containerRouter) postContainerExecCreate(ctx context.Context, w http.Re
if err := json.NewDecoder(r.Body).Decode(execConfig); err != nil { if err := json.NewDecoder(r.Body).Decode(execConfig); err != nil {
return err return err
} }
execConfig.Container = name
if len(execConfig.Cmd) == 0 { if len(execConfig.Cmd) == 0 {
return fmt.Errorf("No exec command specified") return fmt.Errorf("No exec command specified")
} }
// Register an instance of Exec in container. // Register an instance of Exec in container.
id, err := s.backend.ContainerExecCreate(execConfig) id, err := s.backend.ContainerExecCreate(name, execConfig)
if err != nil { if err != nil {
logrus.Errorf("Error setting up exec command in container %s: %v", name, err) logrus.Errorf("Error setting up exec command in container %s: %v", name, err)
return err return err

View File

@ -14,7 +14,7 @@ type Backend interface {
GetNetworkByName(idName string) (libnetwork.Network, error) GetNetworkByName(idName string) (libnetwork.Network, error)
GetNetworksByID(partialID string) []libnetwork.Network GetNetworksByID(partialID string) []libnetwork.Network
FilterNetworks(netFilters filters.Args) ([]libnetwork.Network, error) 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 ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error
DisconnectContainerFromNetwork(containerName string, network libnetwork.Network, force bool) error DisconnectContainerFromNetwork(containerName string, network libnetwork.Network, force bool) error
DeleteNetwork(name string) error DeleteNetwork(name string) error

View File

@ -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 { 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 { if err := httputils.ParseForm(r); err != nil {
return err return err

View File

@ -88,8 +88,8 @@ func (d *Daemon) getActiveContainer(name string) (*container.Container, error) {
} }
// ContainerExecCreate sets up an exec in a running container. // ContainerExecCreate sets up an exec in a running container.
func (d *Daemon) ContainerExecCreate(config *types.ExecConfig) (string, error) { func (d *Daemon) ContainerExecCreate(name string, config *types.ExecConfig) (string, error) {
container, err := d.getActiveContainer(config.Container) container, err := d.getActiveContainer(name)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -94,7 +94,7 @@ func (daemon *Daemon) getAllNetworks() []libnetwork.Network {
} }
// CreateNetwork creates a network with the given name, driver and other optional parameters // 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) { if runconfig.IsPreDefinedNetwork(create.Name) {
err := fmt.Errorf("%s is a pre-defined network and cannot be created", create.Name) err := fmt.Errorf("%s is a pre-defined network and cannot be created", create.Name)
return nil, errors.NewErrorWithStatusCode(err, http.StatusForbidden) return nil, errors.NewErrorWithStatusCode(err, http.StatusForbidden)

View File

@ -28,9 +28,11 @@ func (s *DockerSuite) TestApiNetworkCreateDelete(c *check.C) {
testRequires(c, DaemonIsLinux) testRequires(c, DaemonIsLinux)
// Create a network // Create a network
name := "testnetwork" name := "testnetwork"
config := types.NetworkCreate{ config := types.NetworkCreateRequest{
Name: name, Name: name,
NetworkCreate: types.NetworkCreate{
CheckDuplicate: true, CheckDuplicate: true,
},
} }
id := createNetwork(c, config, true) id := createNetwork(c, config, true)
c.Assert(isNetworkAvailable(c, name), checker.Equals, 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) { func (s *DockerSuite) TestApiNetworkCreateCheckDuplicate(c *check.C) {
testRequires(c, DaemonIsLinux) testRequires(c, DaemonIsLinux)
name := "testcheckduplicate" name := "testcheckduplicate"
configOnCheck := types.NetworkCreate{ configOnCheck := types.NetworkCreateRequest{
Name: name, Name: name,
NetworkCreate: types.NetworkCreate{
CheckDuplicate: true, CheckDuplicate: true,
},
} }
configNotCheck := types.NetworkCreate{ configNotCheck := types.NetworkCreateRequest{
Name: name, Name: name,
NetworkCreate: types.NetworkCreate{
CheckDuplicate: false, CheckDuplicate: false,
},
} }
// Creating a new network first // Creating a new network first
@ -99,11 +105,13 @@ func (s *DockerSuite) TestApiNetworkInspect(c *check.C) {
Driver: "default", Driver: "default",
Config: []network.IPAMConfig{{Subnet: "172.28.0.0/16", IPRange: "172.28.5.0/24", Gateway: "172.28.5.254"}}, Config: []network.IPAMConfig{{Subnet: "172.28.0.0/16", IPRange: "172.28.5.0/24", Gateway: "172.28.5.254"}},
} }
config := types.NetworkCreate{ config := types.NetworkCreateRequest{
Name: "br0", Name: "br0",
NetworkCreate: types.NetworkCreate{
Driver: "bridge", Driver: "bridge",
IPAM: ipam, IPAM: ipam,
Options: map[string]string{"foo": "bar", "opts": "dopts"}, Options: map[string]string{"foo": "bar", "opts": "dopts"},
},
} }
id0 := createNetwork(c, config, true) id0 := createNetwork(c, config, true)
c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, true) c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, true)
@ -125,7 +133,7 @@ func (s *DockerSuite) TestApiNetworkConnectDisconnect(c *check.C) {
testRequires(c, DaemonIsLinux) testRequires(c, DaemonIsLinux)
// Create test network // Create test network
name := "testnetwork" name := "testnetwork"
config := types.NetworkCreate{ config := types.NetworkCreateRequest{
Name: name, Name: name,
} }
id := createNetwork(c, config, true) id := createNetwork(c, config, true)
@ -169,10 +177,12 @@ func (s *DockerSuite) TestApiNetworkIpamMultipleBridgeNetworks(c *check.C) {
Driver: "default", Driver: "default",
Config: []network.IPAMConfig{{Subnet: "192.178.0.0/16", IPRange: "192.178.128.0/17", Gateway: "192.178.138.100"}}, Config: []network.IPAMConfig{{Subnet: "192.178.0.0/16", IPRange: "192.178.128.0/17", Gateway: "192.178.138.100"}},
} }
config0 := types.NetworkCreate{ config0 := types.NetworkCreateRequest{
Name: "test0", Name: "test0",
NetworkCreate: types.NetworkCreate{
Driver: "bridge", Driver: "bridge",
IPAM: ipam0, IPAM: ipam0,
},
} }
id0 := createNetwork(c, config0, true) id0 := createNetwork(c, config0, true)
c.Assert(isNetworkAvailable(c, "test0"), checker.Equals, 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"}}, Config: []network.IPAMConfig{{Subnet: "192.178.128.0/17", Gateway: "192.178.128.1"}},
} }
// test1 bridge network overlaps with test0 // test1 bridge network overlaps with test0
config1 := types.NetworkCreate{ config1 := types.NetworkCreateRequest{
Name: "test1", Name: "test1",
NetworkCreate: types.NetworkCreate{
Driver: "bridge", Driver: "bridge",
IPAM: ipam1, IPAM: ipam1,
},
} }
createNetwork(c, config1, false) createNetwork(c, config1, false)
c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, 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"}}, Config: []network.IPAMConfig{{Subnet: "192.169.0.0/16", Gateway: "192.169.100.100"}},
} }
// test2 bridge network does not overlap // test2 bridge network does not overlap
config2 := types.NetworkCreate{ config2 := types.NetworkCreateRequest{
Name: "test2", Name: "test2",
NetworkCreate: types.NetworkCreate{
Driver: "bridge", Driver: "bridge",
IPAM: ipam2, IPAM: ipam2,
},
} }
createNetwork(c, config2, true) createNetwork(c, config2, true)
c.Assert(isNetworkAvailable(c, "test2"), checker.Equals, 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) c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, true)
// for networks w/o ipam specified, docker will choose proper non-overlapping subnets // 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) 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) 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) c.Assert(isNetworkAvailable(c, "test5"), checker.Equals, true)
for i := 1; i < 6; i++ { for i := 1; i < 6; i++ {
@ -230,9 +244,11 @@ func (s *DockerSuite) TestApiCreateDeletePredefinedNetworks(c *check.C) {
func createDeletePredefinedNetwork(c *check.C, name string) { func createDeletePredefinedNetwork(c *check.C, name string) {
// Create pre-defined network // Create pre-defined network
config := types.NetworkCreate{ config := types.NetworkCreateRequest{
Name: name, Name: name,
NetworkCreate: types.NetworkCreate{
CheckDuplicate: true, CheckDuplicate: true,
},
} }
shouldSucceed := false shouldSucceed := false
createNetwork(c, config, shouldSucceed) createNetwork(c, config, shouldSucceed)
@ -289,7 +305,7 @@ func getNetworkResource(c *check.C, id string) *types.NetworkResource {
return &nr 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) status, resp, err := sockRequest("POST", "/networks/create", config)
if !shouldSucceed { if !shouldSucceed {
c.Assert(status, checker.Not(checker.Equals), http.StatusCreated) c.Assert(status, checker.Not(checker.Equals), http.StatusCreated)