mirror of https://github.com/docker/cli.git
Merge pull request #319 from keloyang/bugfix-docker-cp
Bugfix docker cp
This commit is contained in:
commit
2dac00bdca
|
@ -7,7 +7,7 @@ github.com/coreos/etcd 824277cb3a577a0e8c829ca9ec557b973fe06d20
|
||||||
github.com/cpuguy83/go-md2man a65d4d2de4d5f7c74868dfa9b202a3c8be315aaa
|
github.com/cpuguy83/go-md2man a65d4d2de4d5f7c74868dfa9b202a3c8be315aaa
|
||||||
github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76
|
github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76
|
||||||
github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621
|
github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621
|
||||||
github.com/docker/docker 87df0e533b619c088091fd1e2310e92bb9a24822
|
github.com/docker/docker d58ffa0364c04d03a8f25704d7f0489ee6cd9634
|
||||||
github.com/docker/docker-credential-helpers v0.5.1
|
github.com/docker/docker-credential-helpers v0.5.1
|
||||||
|
|
||||||
# the docker/go package contains a customized version of canonical/json
|
# the docker/go package contains a customized version of canonical/json
|
||||||
|
|
|
@ -2,7 +2,7 @@ package swarm
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
// ClusterInfo represents info about the cluster for outputing in "info"
|
// ClusterInfo represents info about the cluster for outputting in "info"
|
||||||
// it contains the same information as "Swarm", but without the JoinTokens
|
// it contains the same information as "Swarm", but without the JoinTokens
|
||||||
type ClusterInfo struct {
|
type ClusterInfo struct {
|
||||||
ID string
|
ID string
|
||||||
|
|
|
@ -91,7 +91,7 @@ type Client struct {
|
||||||
// CheckRedirect specifies the policy for dealing with redirect responses:
|
// CheckRedirect specifies the policy for dealing with redirect responses:
|
||||||
// If the request is non-GET return `ErrRedirect`. Otherwise use the last response.
|
// If the request is non-GET return `ErrRedirect`. Otherwise use the last response.
|
||||||
//
|
//
|
||||||
// Go 1.8 changes behavior for HTTP redirects (specificlaly 301, 307, and 308) in the client .
|
// Go 1.8 changes behavior for HTTP redirects (specifically 301, 307, and 308) in the client .
|
||||||
// The Docker client (and by extension docker API client) can be made to to send a request
|
// The Docker client (and by extension docker API client) can be made to to send a request
|
||||||
// like POST /containers//start where what would normally be in the name section of the URL is empty.
|
// like POST /containers//start where what would normally be in the name section of the URL is empty.
|
||||||
// This triggers an HTTP 301 from the daemon.
|
// This triggers an HTTP 301 from the daemon.
|
||||||
|
@ -260,8 +260,13 @@ func (cli *Client) NegotiateAPIVersionPing(p types.Ping) {
|
||||||
p.APIVersion = "1.24"
|
p.APIVersion = "1.24"
|
||||||
}
|
}
|
||||||
|
|
||||||
// if server version is lower than the current cli, downgrade
|
// if the client is not initialized with a version, start with the latest supported version
|
||||||
if versions.LessThan(p.APIVersion, cli.ClientVersion()) {
|
if cli.version == "" {
|
||||||
|
cli.version = api.DefaultVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
// if server version is lower than the maximum version supported by the Client, downgrade
|
||||||
|
if versions.LessThan(p.APIVersion, api.DefaultVersion) {
|
||||||
cli.version = p.APIVersion
|
cli.version = p.APIVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,26 @@ 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.
|
||||||
|
//
|
||||||
|
// The stream format on the response will be in one of two formats:
|
||||||
|
//
|
||||||
|
// If the container is using a TTY, there is only a single stream (stdout), and
|
||||||
|
// data is copied directly from the container output stream, no extra
|
||||||
|
// multiplexing or headers.
|
||||||
|
//
|
||||||
|
// If the container is *not* using a TTY, streams for stdout and stderr are
|
||||||
|
// multiplexed.
|
||||||
|
// The format of the multiplexed stream is as follows:
|
||||||
|
//
|
||||||
|
// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
|
||||||
|
//
|
||||||
|
// STREAM_TYPE can be 1 for stdout and 2 for stderr
|
||||||
|
//
|
||||||
|
// SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded as big endian.
|
||||||
|
// This is the size of OUTPUT.
|
||||||
|
//
|
||||||
|
// You can use github.com/docker/docker/pkg/stdcopy.StdCopy to demultiplex this
|
||||||
|
// stream.
|
||||||
func (cli *Client) ContainerAttach(ctx context.Context, container string, 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 {
|
||||||
|
|
|
@ -13,6 +13,26 @@ 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.
|
||||||
|
//
|
||||||
|
// The stream format on the response will be in one of two formats:
|
||||||
|
//
|
||||||
|
// If the container is using a TTY, there is only a single stream (stdout), and
|
||||||
|
// data is copied directly from the container output stream, no extra
|
||||||
|
// multiplexing or headers.
|
||||||
|
//
|
||||||
|
// If the container is *not* using a TTY, streams for stdout and stderr are
|
||||||
|
// multiplexed.
|
||||||
|
// The format of the multiplexed stream is as follows:
|
||||||
|
//
|
||||||
|
// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
|
||||||
|
//
|
||||||
|
// STREAM_TYPE can be 1 for stdout and 2 for stderr
|
||||||
|
//
|
||||||
|
// SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded as big endian.
|
||||||
|
// This is the size of OUTPUT.
|
||||||
|
//
|
||||||
|
// You can use github.com/docker/docker/pkg/stdcopy.StdCopy to demultiplex this
|
||||||
|
// stream.
|
||||||
func (cli *Client) ContainerLogs(ctx context.Context, container string, 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 {
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
// indicated by the given condition, either "not-running" (default),
|
// indicated by the given condition, either "not-running" (default),
|
||||||
// "next-exit", or "removed".
|
// "next-exit", or "removed".
|
||||||
//
|
//
|
||||||
// If this client's API version is beforer 1.30, condition is ignored and
|
// If this client's API version is before 1.30, condition is ignored and
|
||||||
// ContainerWait will return immediately with the two channels, as the server
|
// ContainerWait will return immediately with the two channels, as the server
|
||||||
// will wait as if the condition were "not-running".
|
// will wait as if the condition were "not-running".
|
||||||
//
|
//
|
||||||
|
@ -23,7 +23,7 @@ import (
|
||||||
// then returns two channels on which the caller can wait for the exit status
|
// then returns two channels on which the caller can wait for the exit status
|
||||||
// of the container or an error if there was a problem either beginning the
|
// of the container or an error if there was a problem either beginning the
|
||||||
// wait request or in getting the response. This allows the caller to
|
// wait request or in getting the response. This allows the caller to
|
||||||
// sychronize ContainerWait with other calls, such as specifying a
|
// synchronize ContainerWait with other calls, such as specifying a
|
||||||
// "next-exit" condition before issuing a ContainerStart request.
|
// "next-exit" condition before issuing a ContainerStart request.
|
||||||
func (cli *Client) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.ContainerWaitOKBody, <-chan error) {
|
func (cli *Client) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.ContainerWaitOKBody, <-chan error) {
|
||||||
if versions.LessThan(cli.ClientVersion(), "1.30") {
|
if versions.LessThan(cli.ClientVersion(), "1.30") {
|
||||||
|
|
|
@ -22,7 +22,7 @@ func NewIPOpt(ref *net.IP, defaultVal string) *IPOpt {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set sets an IPv4 or IPv6 address from a given string. If the given
|
// Set sets an IPv4 or IPv6 address from a given string. If the given
|
||||||
// string is not parseable as an IP address it returns an error.
|
// string is not parsable as an IP address it returns an error.
|
||||||
func (o *IPOpt) Set(val string) error {
|
func (o *IPOpt) Set(val string) error {
|
||||||
ip := net.ParseIP(val)
|
ip := net.ParseIP(val)
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
|
|
|
@ -180,7 +180,7 @@ func DecompressStream(archive io.Reader) (io.ReadCloser, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CompressStream compresseses the dest with specified compression algorithm.
|
// CompressStream compresses the dest with specified compression algorithm.
|
||||||
func CompressStream(dest io.Writer, compression Compression) (io.WriteCloser, error) {
|
func CompressStream(dest io.Writer, compression Compression) (io.WriteCloser, error) {
|
||||||
p := pools.BufioWriter32KPool
|
p := pools.BufioWriter32KPool
|
||||||
buf := p.Get(dest)
|
buf := p.Get(dest)
|
||||||
|
|
|
@ -332,6 +332,9 @@ func RebaseArchiveEntries(srcContent io.Reader, oldBase, newBase string) io.Read
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr.Name = strings.Replace(hdr.Name, oldBase, newBase, 1)
|
hdr.Name = strings.Replace(hdr.Name, oldBase, newBase, 1)
|
||||||
|
if hdr.Typeflag == tar.TypeLink {
|
||||||
|
hdr.Linkname = strings.Replace(hdr.Linkname, oldBase, newBase, 1)
|
||||||
|
}
|
||||||
|
|
||||||
if err = rebasedTar.WriteHeader(hdr); err != nil {
|
if err = rebasedTar.WriteHeader(hdr); err != nil {
|
||||||
w.CloseWithError(err)
|
w.CloseWithError(err)
|
||||||
|
|
|
@ -40,7 +40,7 @@ func FollowSymlinkInScope(path, root string) (string, error) {
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
// If /foo/bar -> /outside,
|
// If /foo/bar -> /outside,
|
||||||
// FollowSymlinkInScope("/foo/bar", "/foo") == "/foo/outside" instead of "/oustide"
|
// FollowSymlinkInScope("/foo/bar", "/foo") == "/foo/outside" instead of "/outside"
|
||||||
//
|
//
|
||||||
// IMPORTANT: it is the caller's responsibility to call evalSymlinksInScope *after* relevant symlinks
|
// IMPORTANT: it is the caller's responsibility to call evalSymlinksInScope *after* relevant symlinks
|
||||||
// are created and not to create subsequently, additional symlinks that could potentially make a
|
// are created and not to create subsequently, additional symlinks that could potentially make a
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
// This is used, for example, when validating a user provided path in docker cp.
|
// This is used, for example, when validating a user provided path in docker cp.
|
||||||
// If a drive letter is supplied, it must be the system drive. The drive letter
|
// If a drive letter is supplied, it must be the system drive. The drive letter
|
||||||
// is always removed. Also, it translates it to OS semantics (IOW / to \). We
|
// is always removed. Also, it translates it to OS semantics (IOW / to \). We
|
||||||
// need the path in this syntax so that it can ultimately be contatenated with
|
// need the path in this syntax so that it can ultimately be concatenated with
|
||||||
// a Windows long-path which doesn't support drive-letters. Examples:
|
// a Windows long-path which doesn't support drive-letters. Examples:
|
||||||
// C: --> Fail
|
// C: --> Fail
|
||||||
// C:\ --> \
|
// C:\ --> \
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
// These types of errors do not need to be returned since it's ok for the dir to
|
// These types of errors do not need to be returned since it's ok for the dir to
|
||||||
// be gone we can just retry the remove operation.
|
// be gone we can just retry the remove operation.
|
||||||
//
|
//
|
||||||
// This should not return a `os.ErrNotExist` kind of error under any cirucmstances
|
// This should not return a `os.ErrNotExist` kind of error under any circumstances
|
||||||
func EnsureRemoveAll(dir string) error {
|
func EnsureRemoveAll(dir string) error {
|
||||||
notExistErr := make(map[string]bool)
|
notExistErr := make(map[string]bool)
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ var basicFunctions = template.FuncMap{
|
||||||
// HeaderFunctions are used to created headers of a table.
|
// HeaderFunctions are used to created headers of a table.
|
||||||
// This is a replacement of basicFunctions for header generation
|
// This is a replacement of basicFunctions for header generation
|
||||||
// because we want the header to remain intact.
|
// because we want the header to remain intact.
|
||||||
// Some functions like `split` are irrevelant so not added.
|
// Some functions like `split` are irrelevant so not added.
|
||||||
var HeaderFunctions = template.FuncMap{
|
var HeaderFunctions = template.FuncMap{
|
||||||
"json": func(v string) string {
|
"json": func(v string) string {
|
||||||
return v
|
return v
|
||||||
|
|
|
@ -252,7 +252,7 @@ skip:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// allowNondistributableArtifacts returns true if the provided hostname is part of the list of regsitries
|
// allowNondistributableArtifacts returns true if the provided hostname is part of the list of registries
|
||||||
// that allow push of nondistributable artifacts.
|
// that allow push of nondistributable artifacts.
|
||||||
//
|
//
|
||||||
// The list can contain elements with CIDR notation to specify a whole subnet. If the subnet contains an IP
|
// The list can contain elements with CIDR notation to specify a whole subnet. If the subnet contains an IP
|
||||||
|
|
|
@ -175,7 +175,7 @@ func (e *V1Endpoint) Ping() (PingResult, error) {
|
||||||
Standalone: true,
|
Standalone: true,
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(jsonString, &info); err != nil {
|
if err := json.Unmarshal(jsonString, &info); err != nil {
|
||||||
logrus.Debugf("Error unmarshalling the _ping PingResult: %s", err)
|
logrus.Debugf("Error unmarshaling the _ping PingResult: %s", err)
|
||||||
// don't stop here. Just assume sane defaults
|
// don't stop here. Just assume sane defaults
|
||||||
}
|
}
|
||||||
if hdr := resp.Header.Get("X-Docker-Registry-Version"); hdr != "" {
|
if hdr := resp.Header.Get("X-Docker-Registry-Version"); hdr != "" {
|
||||||
|
|
|
@ -13,7 +13,6 @@ github.com/kr/pty 5cf931ef8f
|
||||||
github.com/mattn/go-shellwords v1.0.3
|
github.com/mattn/go-shellwords v1.0.3
|
||||||
github.com/tchap/go-patricia v2.2.6
|
github.com/tchap/go-patricia v2.2.6
|
||||||
github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3
|
github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3
|
||||||
# forked golang.org/x/net package includes a patch for lazy loading trace templates
|
|
||||||
golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6
|
golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6
|
||||||
golang.org/x/sys 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9
|
golang.org/x/sys 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9
|
||||||
github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
|
github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
|
||||||
|
|
|
@ -125,7 +125,7 @@ type MountPoint struct {
|
||||||
Spec mounttypes.Mount
|
Spec mounttypes.Mount
|
||||||
|
|
||||||
// Track usage of this mountpoint
|
// Track usage of this mountpoint
|
||||||
// Specicially needed for containers which are running and calls to `docker cp`
|
// Specifically needed for containers which are running and calls to `docker cp`
|
||||||
// because both these actions require mounting the volumes.
|
// because both these actions require mounting the volumes.
|
||||||
active int
|
active int
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ func ConvertTmpfsOptions(opt *mounttypes.TmpfsOptions, readOnly bool) (string, e
|
||||||
// okay, since API is that way anyways.
|
// okay, since API is that way anyways.
|
||||||
|
|
||||||
// we do this by finding the suffix that divides evenly into the
|
// we do this by finding the suffix that divides evenly into the
|
||||||
// value, returing the value itself, with no suffix, if it fails.
|
// value, returning the value itself, with no suffix, if it fails.
|
||||||
//
|
//
|
||||||
// For the most part, we don't enforce any semantic to this values.
|
// For the most part, we don't enforce any semantic to this values.
|
||||||
// The operating system will usually align this and enforce minimum
|
// The operating system will usually align this and enforce minimum
|
||||||
|
|
Loading…
Reference in New Issue