mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #21657 from vdemeester/update-engine-api
Update engine api with required arguments
This commit is contained in:
commit
7fd53f7c71
55 changed files with 505 additions and 384 deletions
|
@ -48,13 +48,14 @@ 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,
|
Stderr: true,
|
||||||
Stderr: true,
|
DetachKeys: cli.configFile.DetachKeys,
|
||||||
DetachKeys: cli.configFile.DetachKeys,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var in io.ReadCloser
|
var in io.ReadCloser
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
@ -33,29 +31,10 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
|
||||||
cmd.ParseFlags(args, true)
|
cmd.ParseFlags(args, true)
|
||||||
|
|
||||||
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,17 +44,15 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
options := types.ContainerCommitOptions{
|
options := types.ContainerCommitOptions{
|
||||||
ContainerID: name,
|
Reference: reference,
|
||||||
RepositoryName: repositoryName,
|
Comment: *flComment,
|
||||||
Tag: tag,
|
Author: *flAuthor,
|
||||||
Comment: *flComment,
|
Changes: flChanges.GetAll(),
|
||||||
Author: *flAuthor,
|
Pause: *flPause,
|
||||||
Changes: flChanges.GetAll(),
|
Config: config,
|
||||||
Pause: *flPause,
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -31,26 +30,20 @@ func (cli *DockerCli) CmdImport(args ...string) error {
|
||||||
cmd.ParseFlags(args, true)
|
cmd.ParseFlags(args, true)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
in io.Reader
|
in io.Reader
|
||||||
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,
|
|
||||||
Message: *message,
|
|
||||||
Tag: tag,
|
|
||||||
Changes: changes,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,15 +42,14 @@ 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,
|
Timestamps: *times,
|
||||||
Timestamps: *times,
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
RegistryAuth: encodedAuth,
|
||||||
Tag: tag,
|
PrivilegeFunc: requestPrivilege,
|
||||||
RegistryAuth: encodedAuth,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
RegistryAuth: encodedAuth,
|
||||||
Tag: tag,
|
PrivilegeFunc: requestPrivilege,
|
||||||
RegistryAuth: encodedAuth,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cli.client.ImagePush(context.Background(), options, requestPrivilege)
|
return cli.client.ImagePush(context.Background(), ref, options)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -198,15 +198,14 @@ 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,
|
Stderr: config.AttachStderr,
|
||||||
Stderr: config.AttachStderr,
|
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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,12 +81,11 @@ 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,
|
Stderr: true,
|
||||||
Stderr: true,
|
DetachKeys: cli.configFile.DetachKeys,
|
||||||
DetachKeys: cli.configFile.DetachKeys,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var in io.ReadCloser
|
var in io.ReadCloser
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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),
|
Force: *force,
|
||||||
RepositoryName: ref.Name(),
|
|
||||||
Tag: tag,
|
|
||||||
Force: *force,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cli.client.ImageTag(context.Background(), options)
|
return cli.client.ImageTag(context.Background(), cmd.Arg(0), cmd.Arg(1), options)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
Force: true,
|
||||||
RepositoryName: trustedRef.Name(),
|
|
||||||
Tag: ref.Tag(),
|
|
||||||
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 == "" {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 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-units 651fc226e7441360384da338d0fd37f2440ffbe3
|
||||||
clone git github.com/docker/go-connections v0.2.0
|
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/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837
|
||||||
clone git github.com/imdario/mergo 0.2.1
|
clone git github.com/imdario/mergo 0.2.1
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
CheckDuplicate: true,
|
NetworkCreate: types.NetworkCreate{
|
||||||
|
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,
|
||||||
CheckDuplicate: true,
|
NetworkCreate: types.NetworkCreate{
|
||||||
|
CheckDuplicate: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
configNotCheck := types.NetworkCreate{
|
configNotCheck := types.NetworkCreateRequest{
|
||||||
Name: name,
|
Name: name,
|
||||||
CheckDuplicate: false,
|
NetworkCreate: types.NetworkCreate{
|
||||||
|
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",
|
||||||
Driver: "bridge",
|
NetworkCreate: types.NetworkCreate{
|
||||||
IPAM: ipam,
|
Driver: "bridge",
|
||||||
Options: map[string]string{"foo": "bar", "opts": "dopts"},
|
IPAM: ipam,
|
||||||
|
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",
|
||||||
Driver: "bridge",
|
NetworkCreate: types.NetworkCreate{
|
||||||
IPAM: ipam0,
|
Driver: "bridge",
|
||||||
|
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",
|
||||||
Driver: "bridge",
|
NetworkCreate: types.NetworkCreate{
|
||||||
IPAM: ipam1,
|
Driver: "bridge",
|
||||||
|
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",
|
||||||
Driver: "bridge",
|
NetworkCreate: types.NetworkCreate{
|
||||||
IPAM: ipam2,
|
Driver: "bridge",
|
||||||
|
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,
|
||||||
CheckDuplicate: true,
|
NetworkCreate: types.NetworkCreate{
|
||||||
|
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)
|
||||||
|
|
|
@ -114,6 +114,12 @@ func (cli *Client) ClientVersion() string {
|
||||||
return cli.version
|
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.
|
// ParseHost verifies that the given host strings is valid.
|
||||||
func ParseHost(host string) (string, string, string, error) {
|
func ParseHost(host string) (string, string, string, error) {
|
||||||
protoAddrParts := strings.SplitN(host, "://", 2)
|
protoAddrParts := strings.SplitN(host, "://", 2)
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
// It returns a types.HijackedConnection with the hijacked connection
|
// It returns a types.HijackedConnection with the hijacked connection
|
||||||
// and the a reader to get output. It's up to the called to close
|
// and the a reader to get output. It's up to the called to close
|
||||||
// the hijacked connection by calling types.HijackedResponse.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{}
|
query := url.Values{}
|
||||||
if options.Stream {
|
if options.Stream {
|
||||||
query.Set("stream", "1")
|
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"}}
|
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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,36 @@ package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
distreference "github.com/docker/distribution/reference"
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
|
"github.com/docker/engine-api/types/reference"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ContainerCommit applies changes into a container and creates a new tagged image.
|
// 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 := url.Values{}
|
||||||
query.Set("container", options.ContainerID)
|
query.Set("container", container)
|
||||||
query.Set("repo", options.RepositoryName)
|
query.Set("repo", repository)
|
||||||
query.Set("tag", options.Tag)
|
query.Set("tag", tag)
|
||||||
query.Set("comment", options.Comment)
|
query.Set("comment", options.Comment)
|
||||||
query.Set("author", options.Author)
|
query.Set("author", options.Author)
|
||||||
for _, change := range options.Changes {
|
for _, change := range options.Changes {
|
||||||
|
|
|
@ -8,9 +8,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ContainerExecCreate creates a new exec configuration to run an exec process.
|
// 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
|
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 {
|
if err != nil {
|
||||||
return response, err
|
return response, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@ func (cli *Client) ContainerList(ctx context.Context, options types.ContainerLis
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.Filter.Len() > 0 {
|
if options.Filter.Len() > 0 {
|
||||||
filterJSON, err := filters.ToParam(options.Filter)
|
filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filter)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
// ContainerLogs returns the logs generated by a container in an io.ReadCloser.
|
// ContainerLogs returns the logs generated by a container in an io.ReadCloser.
|
||||||
// It's up to the caller to close the stream.
|
// 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{}
|
query := url.Values{}
|
||||||
if options.ShowStdout {
|
if options.ShowStdout {
|
||||||
query.Set("stdout", "1")
|
query.Set("stdout", "1")
|
||||||
|
@ -40,7 +40,7 @@ func (cli *Client) ContainerLogs(ctx context.Context, options types.ContainerLog
|
||||||
}
|
}
|
||||||
query.Set("tail", options.Tail)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ContainerRemove kills and removes a container from the docker host.
|
// 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{}
|
query := url.Values{}
|
||||||
if options.RemoveVolumes {
|
if options.RemoveVolumes {
|
||||||
query.Set("v", "1")
|
query.Set("v", "1")
|
||||||
|
@ -21,7 +21,7 @@ func (cli *Client) ContainerRemove(ctx context.Context, options types.ContainerR
|
||||||
query.Set("force", "1")
|
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)
|
ensureReaderClosed(resp)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ContainerResize changes the size of the tty for a container.
|
// ContainerResize changes the size of the tty for a container.
|
||||||
func (cli *Client) ContainerResize(ctx context.Context, options types.ResizeOptions) error {
|
func (cli *Client) ContainerResize(ctx context.Context, containerID string, options types.ResizeOptions) error {
|
||||||
return cli.resize(ctx, "/containers/"+options.ID, options.Height, options.Width)
|
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.
|
// 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 {
|
func (cli *Client) ContainerExecResize(ctx context.Context, execID string, options types.ResizeOptions) error {
|
||||||
return cli.resize(ctx, "/exec/"+options.ID, options.Height, options.Width)
|
return cli.resize(ctx, "/exec/"+execID, options.Height, options.Width)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) resize(ctx context.Context, basePath string, height, width int) error {
|
func (cli *Client) resize(ctx context.Context, basePath string, height, width int) error {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package client
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -20,7 +21,7 @@ var headerRegexp = regexp.MustCompile(`\ADocker/.+\s\((.+)\)\z`)
|
||||||
// ImageBuild sends request to the daemon to build images.
|
// 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
|
// The Body in the response implement an io.ReadCloser and it's up to the caller to
|
||||||
// close it.
|
// 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)
|
query, err := imageBuildOptionsToQuery(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.ImageBuildResponse{}, err
|
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.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf))
|
||||||
headers.Set("Content-Type", "application/tar")
|
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 {
|
if err != nil {
|
||||||
return types.ImageBuildResponse{}, err
|
return types.ImageBuildResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,20 @@ import (
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
|
"github.com/docker/engine-api/types/reference"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImageCreate creates a new image based in the parent options.
|
// ImageCreate creates a new image based in the parent options.
|
||||||
// It returns the JSON content in the response body.
|
// 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 := url.Values{}
|
||||||
query.Set("fromImage", options.Parent)
|
query.Set("fromImage", repository)
|
||||||
query.Set("tag", options.Tag)
|
query.Set("tag", tag)
|
||||||
resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth)
|
resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -6,22 +6,30 @@ import (
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImageImport creates a new image based in the source options.
|
// ImageImport creates a new image based in the source options.
|
||||||
// It returns the JSON content in the response body.
|
// 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 := url.Values{}
|
||||||
query.Set("fromSrc", options.SourceName)
|
query.Set("fromSrc", source.SourceName)
|
||||||
query.Set("repo", options.RepositoryName)
|
query.Set("repo", ref)
|
||||||
query.Set("tag", options.Tag)
|
query.Set("tag", options.Tag)
|
||||||
query.Set("message", options.Message)
|
query.Set("message", options.Message)
|
||||||
for _, change := range options.Changes {
|
for _, change := range options.Changes {
|
||||||
query.Add("changes", change)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,22 +8,32 @@ import (
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
"github.com/docker/engine-api/types"
|
"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.
|
// ImagePull requests the docker host to pull an image from a remote registry.
|
||||||
// It executes the privileged function if the operation is unauthorized
|
// It executes the privileged function if the operation is unauthorized
|
||||||
// and it tries one more time.
|
// and it tries one more time.
|
||||||
// It's up to the caller to handle the io.ReadCloser and close it properly.
|
// 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 := url.Values{}
|
||||||
query.Set("fromImage", options.ImageID)
|
query.Set("fromImage", repository)
|
||||||
if options.Tag != "" {
|
if tag != "" {
|
||||||
query.Set("tag", options.Tag)
|
query.Set("tag", tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth)
|
resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth)
|
||||||
if resp.statusCode == http.StatusUnauthorized {
|
if resp.statusCode == http.StatusUnauthorized {
|
||||||
newAuthHeader, privilegeErr := privilegeFunc()
|
newAuthHeader, privilegeErr := options.PrivilegeFunc()
|
||||||
if privilegeErr != nil {
|
if privilegeErr != nil {
|
||||||
return nil, privilegeErr
|
return nil, privilegeErr
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,44 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
|
distreference "github.com/docker/distribution/reference"
|
||||||
"github.com/docker/engine-api/types"
|
"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.
|
// ImagePush requests the docker host to push an image to a remote registry.
|
||||||
// It executes the privileged function if the operation is unauthorized
|
// It executes the privileged function if the operation is unauthorized
|
||||||
// and it tries one more time.
|
// and it tries one more time.
|
||||||
// It's up to the caller to handle the io.ReadCloser and close it properly.
|
// 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) {
|
func (cli *Client) ImagePush(ctx context.Context, ref string, options types.ImagePushOptions) (io.ReadCloser, error) {
|
||||||
query := url.Values{}
|
distributionRef, err := distreference.ParseNamed(ref)
|
||||||
query.Set("tag", options.Tag)
|
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 {
|
if resp.statusCode == http.StatusUnauthorized {
|
||||||
newAuthHeader, privilegeErr := privilegeFunc()
|
newAuthHeader, privilegeErr := options.PrivilegeFunc()
|
||||||
if privilegeErr != nil {
|
if privilegeErr != nil {
|
||||||
return nil, privilegeErr
|
return nil, privilegeErr
|
||||||
}
|
}
|
||||||
resp, err = cli.tryImagePush(ctx, options.ImageID, query, newAuthHeader)
|
resp, err = cli.tryImagePush(ctx, distributionRef.Name(), query, newAuthHeader)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImageRemove removes an image from the docker host.
|
// 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{}
|
query := url.Values{}
|
||||||
|
|
||||||
if options.Force {
|
if options.Force {
|
||||||
|
@ -19,7 +19,7 @@ func (cli *Client) ImageRemove(ctx context.Context, options types.ImageRemoveOpt
|
||||||
query.Set("noprune", "1")
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,14 +12,14 @@ import (
|
||||||
|
|
||||||
// ImageSearch makes the docker host to search by a term in a remote registry.
|
// ImageSearch makes the docker host to search by a term in a remote registry.
|
||||||
// The list of results is not sorted in any fashion.
|
// 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
|
var results []registry.SearchResult
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
query.Set("term", options.Term)
|
query.Set("term", term)
|
||||||
|
|
||||||
resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth)
|
resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth)
|
||||||
if resp.statusCode == http.StatusUnauthorized {
|
if resp.statusCode == http.StatusUnauthorized {
|
||||||
newAuthHeader, privilegeErr := privilegeFunc()
|
newAuthHeader, privilegeErr := options.PrivilegeFunc()
|
||||||
if privilegeErr != nil {
|
if privilegeErr != nil {
|
||||||
return results, privilegeErr
|
return results, privilegeErr
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,38 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/docker/engine-api/types"
|
|
||||||
"golang.org/x/net/context"
|
"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
|
// 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 := url.Values{}
|
||||||
query.Set("repo", options.RepositoryName)
|
query.Set("repo", distributionRef.Name())
|
||||||
query.Set("tag", options.Tag)
|
query.Set("tag", tag)
|
||||||
if options.Force {
|
if options.Force {
|
||||||
query.Set("force", "1")
|
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)
|
ensureReaderClosed(resp)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,59 +15,60 @@ import (
|
||||||
// APIClient is an interface that clients that talk with a docker server must implement.
|
// APIClient is an interface that clients that talk with a docker server must implement.
|
||||||
type APIClient interface {
|
type APIClient interface {
|
||||||
ClientVersion() string
|
ClientVersion() string
|
||||||
ContainerAttach(ctx context.Context, options types.ContainerAttachOptions) (types.HijackedResponse, error)
|
ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error)
|
||||||
ContainerCommit(ctx context.Context, options types.ContainerCommitOptions) (types.ContainerCommitResponse, 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)
|
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)
|
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)
|
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
|
ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error
|
||||||
ContainerExport(ctx context.Context, containerID string) (io.ReadCloser, error)
|
ContainerExport(ctx context.Context, container string) (io.ReadCloser, error)
|
||||||
ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error)
|
ContainerInspect(ctx context.Context, container string) (types.ContainerJSON, error)
|
||||||
ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool) (types.ContainerJSON, []byte, error)
|
ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (types.ContainerJSON, []byte, error)
|
||||||
ContainerKill(ctx context.Context, containerID, signal string) error
|
ContainerKill(ctx context.Context, container, signal string) error
|
||||||
ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error)
|
ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error)
|
||||||
ContainerLogs(ctx context.Context, options types.ContainerLogsOptions) (io.ReadCloser, error)
|
ContainerLogs(ctx context.Context, container string, options types.ContainerLogsOptions) (io.ReadCloser, error)
|
||||||
ContainerPause(ctx context.Context, containerID string) error
|
ContainerPause(ctx context.Context, container string) error
|
||||||
ContainerRemove(ctx context.Context, options types.ContainerRemoveOptions) error
|
ContainerRemove(ctx context.Context, container string, options types.ContainerRemoveOptions) error
|
||||||
ContainerRename(ctx context.Context, containerID, newContainerName string) error
|
ContainerRename(ctx context.Context, container, newContainerName string) error
|
||||||
ContainerResize(ctx context.Context, options types.ResizeOptions) error
|
ContainerResize(ctx context.Context, container string, options types.ResizeOptions) error
|
||||||
ContainerRestart(ctx context.Context, containerID string, timeout int) error
|
ContainerRestart(ctx context.Context, container string, timeout int) error
|
||||||
ContainerStatPath(ctx context.Context, containerID, path string) (types.ContainerPathStat, error)
|
ContainerStatPath(ctx context.Context, container, path string) (types.ContainerPathStat, error)
|
||||||
ContainerStats(ctx context.Context, containerID string, stream bool) (io.ReadCloser, error)
|
ContainerStats(ctx context.Context, container string, stream bool) (io.ReadCloser, error)
|
||||||
ContainerStart(ctx context.Context, containerID string) error
|
ContainerStart(ctx context.Context, container string) error
|
||||||
ContainerStop(ctx context.Context, containerID string, timeout int) error
|
ContainerStop(ctx context.Context, container string, timeout int) error
|
||||||
ContainerTop(ctx context.Context, containerID string, arguments []string) (types.ContainerProcessList, error)
|
ContainerTop(ctx context.Context, container string, arguments []string) (types.ContainerProcessList, error)
|
||||||
ContainerUnpause(ctx context.Context, containerID string) error
|
ContainerUnpause(ctx context.Context, container string) error
|
||||||
ContainerUpdate(ctx context.Context, containerID string, updateConfig container.UpdateConfig) error
|
ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) error
|
||||||
ContainerWait(ctx context.Context, containerID string) (int, error)
|
ContainerWait(ctx context.Context, container string) (int, error)
|
||||||
CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error)
|
CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error)
|
||||||
CopyToContainer(ctx context.Context, options types.CopyToContainerOptions) error
|
CopyToContainer(ctx context.Context, options types.CopyToContainerOptions) error
|
||||||
Events(ctx context.Context, options types.EventsOptions) (io.ReadCloser, error)
|
Events(ctx context.Context, options types.EventsOptions) (io.ReadCloser, error)
|
||||||
ImageBuild(ctx context.Context, options types.ImageBuildOptions) (types.ImageBuildResponse, error)
|
ImageBuild(ctx context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error)
|
||||||
ImageCreate(ctx context.Context, options types.ImageCreateOptions) (io.ReadCloser, error)
|
ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error)
|
||||||
ImageHistory(ctx context.Context, imageID string) ([]types.ImageHistory, error)
|
ImageHistory(ctx context.Context, image string) ([]types.ImageHistory, error)
|
||||||
ImageImport(ctx context.Context, options types.ImageImportOptions) (io.ReadCloser, error)
|
ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error)
|
||||||
ImageInspectWithRaw(ctx context.Context, imageID string, getSize bool) (types.ImageInspect, []byte, error)
|
ImageInspectWithRaw(ctx context.Context, image string, getSize bool) (types.ImageInspect, []byte, error)
|
||||||
ImageList(ctx context.Context, options types.ImageListOptions) ([]types.Image, error)
|
ImageList(ctx context.Context, options types.ImageListOptions) ([]types.Image, error)
|
||||||
ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, 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)
|
ImagePull(ctx context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error)
|
||||||
ImagePush(ctx context.Context, options types.ImagePushOptions, privilegeFunc RequestPrivilegeFunc) (io.ReadCloser, error)
|
ImagePush(ctx context.Context, ref string, options types.ImagePushOptions) (io.ReadCloser, error)
|
||||||
ImageRemove(ctx context.Context, options types.ImageRemoveOptions) ([]types.ImageDelete, error)
|
ImageRemove(ctx context.Context, image string, options types.ImageRemoveOptions) ([]types.ImageDelete, error)
|
||||||
ImageSearch(ctx context.Context, options types.ImageSearchOptions, privilegeFunc RequestPrivilegeFunc) ([]registry.SearchResult, error)
|
ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error)
|
||||||
ImageSave(ctx context.Context, imageIDs []string) (io.ReadCloser, error)
|
ImageSave(ctx context.Context, images []string) (io.ReadCloser, error)
|
||||||
ImageTag(ctx context.Context, options types.ImageTagOptions) error
|
ImageTag(ctx context.Context, image, ref string, options types.ImageTagOptions) error
|
||||||
Info(ctx context.Context) (types.Info, error)
|
Info(ctx context.Context) (types.Info, error)
|
||||||
NetworkConnect(ctx context.Context, networkID, containerID string, config *network.EndpointSettings) error
|
NetworkConnect(ctx context.Context, networkID, container string, config *network.EndpointSettings) error
|
||||||
NetworkCreate(ctx context.Context, options types.NetworkCreate) (types.NetworkCreateResponse, error)
|
NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error)
|
||||||
NetworkDisconnect(ctx context.Context, networkID, containerID string, force bool) error
|
NetworkDisconnect(ctx context.Context, networkID, container string, force bool) error
|
||||||
NetworkInspect(ctx context.Context, networkID string) (types.NetworkResource, error)
|
NetworkInspect(ctx context.Context, networkID string) (types.NetworkResource, error)
|
||||||
NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error)
|
NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error)
|
||||||
NetworkRemove(ctx context.Context, networkID string) error
|
NetworkRemove(ctx context.Context, networkID string) error
|
||||||
RegistryLogin(ctx context.Context, auth types.AuthConfig) (types.AuthResponse, error)
|
RegistryLogin(ctx context.Context, auth types.AuthConfig) (types.AuthResponse, error)
|
||||||
ServerVersion(ctx context.Context) (types.Version, error)
|
ServerVersion(ctx context.Context) (types.Version, error)
|
||||||
|
UpdateClientVersion(v string)
|
||||||
VolumeCreate(ctx context.Context, options types.VolumeCreateRequest) (types.Volume, error)
|
VolumeCreate(ctx context.Context, options types.VolumeCreateRequest) (types.Volume, error)
|
||||||
VolumeInspect(ctx context.Context, volumeID string) (types.Volume, error)
|
VolumeInspect(ctx context.Context, volumeID string) (types.Volume, error)
|
||||||
VolumeList(ctx context.Context, filter filters.Args) (types.VolumesListResponse, error)
|
VolumeList(ctx context.Context, filter filters.Args) (types.VolumesListResponse, error)
|
||||||
|
|
|
@ -8,9 +8,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// NetworkCreate creates a new network in the docker host.
|
// 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
|
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 {
|
if err != nil {
|
||||||
return response, err
|
return response, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1 @@
|
||||||
package client
|
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)
|
|
||||||
|
|
|
@ -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) {
|
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)
|
var body io.Reader
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if body != nil {
|
if obj != nil {
|
||||||
|
var err error
|
||||||
|
body, err = encodeData(obj)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if headers == nil {
|
if headers == nil {
|
||||||
headers = make(map[string][]string)
|
headers = make(map[string][]string)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,24 +12,21 @@ import (
|
||||||
|
|
||||||
// ContainerAttachOptions holds parameters to attach to a container.
|
// ContainerAttachOptions holds parameters to attach to a container.
|
||||||
type ContainerAttachOptions struct {
|
type ContainerAttachOptions struct {
|
||||||
ContainerID string
|
Stream bool
|
||||||
Stream bool
|
Stdin bool
|
||||||
Stdin bool
|
Stdout bool
|
||||||
Stdout bool
|
Stderr bool
|
||||||
Stderr bool
|
DetachKeys string
|
||||||
DetachKeys string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerCommitOptions holds parameters to commit changes into a container.
|
// ContainerCommitOptions holds parameters to commit changes into a container.
|
||||||
type ContainerCommitOptions struct {
|
type ContainerCommitOptions struct {
|
||||||
ContainerID string
|
Reference string
|
||||||
RepositoryName string
|
Comment string
|
||||||
Tag string
|
Author string
|
||||||
Comment string
|
Changes []string
|
||||||
Author string
|
Pause bool
|
||||||
Changes []string
|
Config *container.Config
|
||||||
Pause bool
|
|
||||||
Config *container.Config
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerExecInspect holds information returned by exec inspect.
|
// ContainerExecInspect holds information returned by exec inspect.
|
||||||
|
@ -54,18 +51,16 @@ type ContainerListOptions struct {
|
||||||
|
|
||||||
// ContainerLogsOptions holds parameters to filter logs with.
|
// ContainerLogsOptions holds parameters to filter logs with.
|
||||||
type ContainerLogsOptions struct {
|
type ContainerLogsOptions struct {
|
||||||
ContainerID string
|
ShowStdout bool
|
||||||
ShowStdout bool
|
ShowStderr bool
|
||||||
ShowStderr bool
|
Since string
|
||||||
Since string
|
Timestamps bool
|
||||||
Timestamps bool
|
Follow bool
|
||||||
Follow bool
|
Tail string
|
||||||
Tail string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerRemoveOptions holds parameters to remove containers.
|
// ContainerRemoveOptions holds parameters to remove containers.
|
||||||
type ContainerRemoveOptions struct {
|
type ContainerRemoveOptions struct {
|
||||||
ContainerID string
|
|
||||||
RemoveVolumes bool
|
RemoveVolumes bool
|
||||||
RemoveLinks bool
|
RemoveLinks bool
|
||||||
Force bool
|
Force bool
|
||||||
|
@ -155,19 +150,20 @@ type ImageBuildResponse struct {
|
||||||
|
|
||||||
// ImageCreateOptions holds information to create images.
|
// ImageCreateOptions holds information to create images.
|
||||||
type ImageCreateOptions struct {
|
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
|
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.
|
// ImageImportOptions holds information to import images from the client host.
|
||||||
type ImageImportOptions struct {
|
type ImageImportOptions struct {
|
||||||
Source io.Reader // Source is the data to send to the server to create this image from (mutually exclusive with SourceName)
|
Tag string // Tag is the name to tag this image with. This attribute is deprecated.
|
||||||
SourceName string // SourceName is the name of the image to pull (mutually exclusive with Source)
|
Message string // Message is the message to tag the image with
|
||||||
RepositoryName string // RepositoryName is the name of the repository to import this image into
|
Changes []string // Changes are the raw changes to apply to this image
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageListOptions holds parameters to filter the list of images with.
|
// ImageListOptions holds parameters to filter the list of images with.
|
||||||
|
@ -185,40 +181,42 @@ type ImageLoadResponse struct {
|
||||||
|
|
||||||
// ImagePullOptions holds information to pull images.
|
// ImagePullOptions holds information to pull images.
|
||||||
type ImagePullOptions struct {
|
type ImagePullOptions struct {
|
||||||
ImageID string // ImageID is the name of the image to pull
|
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
|
||||||
Tag string // Tag is the name of the tag to be pulled
|
PrivilegeFunc RequestPrivilegeFunc
|
||||||
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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.
|
//ImagePushOptions holds information to push images.
|
||||||
type ImagePushOptions ImagePullOptions
|
type ImagePushOptions ImagePullOptions
|
||||||
|
|
||||||
// ImageRemoveOptions holds parameters to remove images.
|
// ImageRemoveOptions holds parameters to remove images.
|
||||||
type ImageRemoveOptions struct {
|
type ImageRemoveOptions struct {
|
||||||
ImageID string
|
|
||||||
Force bool
|
Force bool
|
||||||
PruneChildren bool
|
PruneChildren bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageSearchOptions holds parameters to search images with.
|
// ImageSearchOptions holds parameters to search images with.
|
||||||
type ImageSearchOptions struct {
|
type ImageSearchOptions struct {
|
||||||
Term string
|
RegistryAuth string
|
||||||
RegistryAuth string
|
PrivilegeFunc RequestPrivilegeFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageTagOptions holds parameters to tag an image
|
// ImageTagOptions holds parameters to tag an image
|
||||||
type ImageTagOptions struct {
|
type ImageTagOptions struct {
|
||||||
ImageID string
|
Force bool
|
||||||
RepositoryName string
|
|
||||||
Tag string
|
|
||||||
Force bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResizeOptions holds parameters to resize a tty.
|
// ResizeOptions holds parameters to resize a tty.
|
||||||
// It can be used to resize container ttys and
|
// It can be used to resize container ttys and
|
||||||
// exec process ttys too.
|
// exec process ttys too.
|
||||||
type ResizeOptions struct {
|
type ResizeOptions struct {
|
||||||
ID string
|
|
||||||
Height int
|
Height int
|
||||||
Width int
|
Width int
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,6 @@ type ExecConfig struct {
|
||||||
User string // User that will run the command
|
User string // User that will run the command
|
||||||
Privileged bool // Is the container in privileged mode
|
Privileged bool // Is the container in privileged mode
|
||||||
Tty bool // Attach standard streams to a tty.
|
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
|
AttachStdin bool // Attach the standard input, makes possible user interaction
|
||||||
AttachStderr bool // Attach the standard output
|
AttachStderr bool // Attach the standard output
|
||||||
AttachStdout bool // Attach the standard error
|
AttachStdout bool // Attach the standard error
|
||||||
|
|
|
@ -19,7 +19,6 @@ type Config struct {
|
||||||
AttachStdout bool // Attach the standard output
|
AttachStdout bool // Attach the standard output
|
||||||
AttachStderr bool // Attach the standard error
|
AttachStderr bool // Attach the standard error
|
||||||
ExposedPorts map[nat.Port]struct{} `json:",omitempty"` // List of exposed ports
|
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.
|
Tty bool // Attach standard streams to a tty, including stdin if it is not closed.
|
||||||
OpenStdin bool // Open stdin
|
OpenStdin bool // Open stdin
|
||||||
StdinOnce bool // If true, close stdin after the 1 attached client disconnects.
|
StdinOnce bool // If true, close stdin after the 1 attached client disconnects.
|
||||||
|
|
|
@ -92,11 +92,13 @@ func (n UsernsMode) Valid() bool {
|
||||||
// CgroupSpec represents the cgroup to use for the container.
|
// CgroupSpec represents the cgroup to use for the container.
|
||||||
type CgroupSpec string
|
type CgroupSpec string
|
||||||
|
|
||||||
|
// IsContainer indicates whether the container is using another container cgroup
|
||||||
func (c CgroupSpec) IsContainer() bool {
|
func (c CgroupSpec) IsContainer() bool {
|
||||||
parts := strings.SplitN(string(c), ":", 2)
|
parts := strings.SplitN(string(c), ":", 2)
|
||||||
return len(parts) > 1 && parts[0] == "container"
|
return len(parts) > 1 && parts[0] == "container"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Valid indicates whether the cgroup spec is valid.
|
||||||
func (c CgroupSpec) Valid() bool {
|
func (c CgroupSpec) Valid() bool {
|
||||||
return c.IsContainer() || c == ""
|
return c.IsContainer() || c == ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -68,6 +69,28 @@ func ToParam(a Args) (string, error) {
|
||||||
return string(buf), nil
|
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.
|
// FromParam unpacks the filter Args.
|
||||||
func FromParam(p string) (Args, error) {
|
func FromParam(p string) (Args, error) {
|
||||||
if len(p) == 0 {
|
if len(p) == 0 {
|
||||||
|
@ -255,3 +278,48 @@ func deprecatedArgs(d map[string][]string) map[string]map[string]bool {
|
||||||
}
|
}
|
||||||
return m
|
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
|
||||||
|
}
|
||||||
|
|
32
vendor/src/github.com/docker/engine-api/types/reference/image_reference.go
vendored
Normal file
32
vendor/src/github.com/docker/engine-api/types/reference/image_reference.go
vendored
Normal file
|
@ -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
|
||||||
|
}
|
|
@ -91,6 +91,9 @@ type NetworkStats struct {
|
||||||
type PidsStats struct {
|
type PidsStats struct {
|
||||||
// Current is the number of pids in the cgroup
|
// Current is the number of pids in the cgroup
|
||||||
Current uint64 `json:"current,omitempty"`
|
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
|
// Stats is Ultimate struct aggregating all types of stats of one container
|
||||||
|
|
|
@ -290,7 +290,7 @@ type ContainerState struct {
|
||||||
FinishedAt string
|
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
|
// is running on. It's only available in Docker Swarm
|
||||||
type ContainerNode struct {
|
type ContainerNode struct {
|
||||||
ID string
|
ID string
|
||||||
|
@ -438,7 +438,6 @@ type EndpointResource struct {
|
||||||
|
|
||||||
// NetworkCreate is the expected body of the "create network" http request message
|
// NetworkCreate is the expected body of the "create network" http request message
|
||||||
type NetworkCreate struct {
|
type NetworkCreate struct {
|
||||||
Name string
|
|
||||||
CheckDuplicate bool
|
CheckDuplicate bool
|
||||||
Driver string
|
Driver string
|
||||||
EnableIPv6 bool
|
EnableIPv6 bool
|
||||||
|
@ -448,6 +447,12 @@ type NetworkCreate struct {
|
||||||
Labels map[string]string
|
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
|
// NetworkCreateResponse is the response message sent by the server for network create call
|
||||||
type NetworkCreateResponse struct {
|
type NetworkCreateResponse struct {
|
||||||
ID string `json:"Id"`
|
ID string `json:"Id"`
|
||||||
|
|
Loading…
Reference in a new issue