Vendor docker/docker, fsouza and more #2

Signed-off-by: TomSweeneyRedHat <tsweeney@redhat.com>

Vendors in fsouza/docker-client, docker/docker and
a few more related. Of particular note, changes to the TweakCapabilities()
function from docker/docker along with the parse.IDMappingOptions() function
from Buildah. Please pay particular attention to the related changes in
the call from libpod to those functions during the review.

Passes baseline tests.
This commit is contained in:
TomSweeneyRedHat
2019-03-13 11:40:24 -04:00
parent 8b3f759800
commit 8f418f1568
334 changed files with 4537 additions and 1972 deletions

View File

@ -14,7 +14,7 @@ import (
"github.com/containers/libpod/pkg/inspect" "github.com/containers/libpod/pkg/inspect"
"github.com/containers/libpod/pkg/lookup" "github.com/containers/libpod/pkg/lookup"
"github.com/containers/storage/pkg/stringid" "github.com/containers/storage/pkg/stringid"
"github.com/docker/docker/daemon/caps" "github.com/docker/docker/oci/caps"
opentracing "github.com/opentracing/opentracing-go" opentracing "github.com/opentracing/opentracing-go"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"

View File

@ -9,7 +9,7 @@ import (
"github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/rootless"
"github.com/containers/storage/pkg/mount" "github.com/containers/storage/pkg/mount"
pmount "github.com/containers/storage/pkg/mount" pmount "github.com/containers/storage/pkg/mount"
"github.com/docker/docker/daemon/caps" "github.com/docker/docker/oci/caps"
"github.com/docker/go-units" "github.com/docker/go-units"
"github.com/opencontainers/runc/libcontainer/user" "github.com/opencontainers/runc/libcontainer/user"
spec "github.com/opencontainers/runtime-spec/specs-go" spec "github.com/opencontainers/runtime-spec/specs-go"
@ -625,7 +625,7 @@ func setupCapabilities(config *CreateConfig, configSpec *spec.Spec) error {
if useNotRoot(config.User) { if useNotRoot(config.User) {
configSpec.Process.Capabilities.Bounding = caplist configSpec.Process.Capabilities.Bounding = caplist
} }
caplist, err = caps.TweakCapabilities(configSpec.Process.Capabilities.Bounding, config.CapAdd, config.CapDrop) caplist, err = caps.TweakCapabilities(configSpec.Process.Capabilities.Bounding, config.CapAdd, config.CapDrop, nil, false)
if err != nil { if err != nil {
return err return err
} }
@ -636,7 +636,7 @@ func setupCapabilities(config *CreateConfig, configSpec *spec.Spec) error {
configSpec.Process.Capabilities.Effective = caplist configSpec.Process.Capabilities.Effective = caplist
configSpec.Process.Capabilities.Ambient = caplist configSpec.Process.Capabilities.Ambient = caplist
if useNotRoot(config.User) { if useNotRoot(config.User) {
caplist, err = caps.TweakCapabilities(bounding, config.CapAdd, config.CapDrop) caplist, err = caps.TweakCapabilities(bounding, config.CapAdd, config.CapDrop, nil, false)
if err != nil { if err != nil {
return err return err
} }

View File

@ -26,10 +26,11 @@ github.com/cri-o/ocicni 2d2983e40c242322a56c22a903785e7f83eb378c
github.com/cyphar/filepath-securejoin v0.2.1 github.com/cyphar/filepath-securejoin v0.2.1
github.com/davecgh/go-spew v1.1.0 github.com/davecgh/go-spew v1.1.0
github.com/docker/distribution 5f6282db7d65e6d72ad7c2cc66310724a57be716 github.com/docker/distribution 5f6282db7d65e6d72ad7c2cc66310724a57be716
github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00 github.com/docker/docker 54dddadc7d5d89fe0be88f76979f6f6ab0dede83
github.com/docker/docker-credential-helpers v0.6.1 github.com/docker/docker-credential-helpers v0.6.1
github.com/docker/go-connections v0.4.0 github.com/docker/go-connections v0.4.0
github.com/docker/go-units v0.3.2 github.com/docker/go-units v0.3.2
github.com/docker/libnetwork 5f7a3f68c3d9696229cdc09b8cb3d84c06b13e4e
github.com/docker/libtrust aabc10ec26b754e797f9028f4589c5b7bd90dc20 github.com/docker/libtrust aabc10ec26b754e797f9028f4589c5b7bd90dc20
github.com/docker/spdystream 6480d4af844c189cf5dd913db24ddd339d3a4f85 github.com/docker/spdystream 6480d4af844c189cf5dd913db24ddd339d3a4f85
github.com/fatih/camelcase v1.0.0 github.com/fatih/camelcase v1.0.0
@ -96,9 +97,7 @@ github.com/varlink/go 3ac79db6fd6aec70924193b090962f92985fe199
github.com/containers/buildah 3ba8822d309128f7d76599432b8d9cdf77d4032f github.com/containers/buildah 3ba8822d309128f7d76599432b8d9cdf77d4032f
# TODO: Gotty has not been updated since 2012. Can we find replacement? # TODO: Gotty has not been updated since 2012. Can we find replacement?
github.com/Nvveen/Gotty cd527374f1e5bff4938207604a14f2e38a9cf512 github.com/Nvveen/Gotty cd527374f1e5bff4938207604a14f2e38a9cf512
# do not go beyond the below commit as the next one requires a more recent github.com/fsouza/go-dockerclient v1.3.0
# docker which is in conflict with openshift/imagebuilder
github.com/fsouza/go-dockerclient 29c1814d12c072344bb91aac5d2ff719db39c523
github.com/openshift/imagebuilder 705fe9255c57f8505efb9723a9ac4082b67973bc github.com/openshift/imagebuilder 705fe9255c57f8505efb9723a9ac4082b67973bc
github.com/ulikunitz/xz v0.5.5 github.com/ulikunitz/xz v0.5.5
github.com/coreos/go-iptables v0.4.0 github.com/coreos/go-iptables v0.4.0

View File

@ -176,7 +176,7 @@
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
Copyright 2013-2017 Docker, Inc. Copyright 2013-2018 Docker, Inc.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@ -1,11 +1,11 @@
package api package api // import "github.com/docker/docker/api"
// Common constants for daemon and client. // Common constants for daemon and client.
const ( const (
// DefaultVersion of Current REST API // DefaultVersion of Current REST API
DefaultVersion string = "1.34" DefaultVersion = "1.40"
// NoBaseImageSpecifier is the symbol used by the FROM // NoBaseImageSpecifier is the symbol used by the FROM
// command to specify that no base image is to be used. // command to specify that no base image is to be used.
NoBaseImageSpecifier string = "scratch" NoBaseImageSpecifier = "scratch"
) )

View File

@ -1,6 +1,6 @@
// +build !windows // +build !windows
package api package api // import "github.com/docker/docker/api"
// MinVersion represents Minimum REST API version supported // MinVersion represents Minimum REST API version supported
const MinVersion string = "1.12" const MinVersion = "1.12"

View File

@ -1,4 +1,4 @@
package api package api // import "github.com/docker/docker/api"
// MinVersion represents Minimum REST API version supported // MinVersion represents Minimum REST API version supported
// Technically the first daemon API version released on Windows is v1.25 in // Technically the first daemon API version released on Windows is v1.25 in

View File

@ -1,4 +1,4 @@
package types package types // import "github.com/docker/docker/api/types"
// AuthConfig contains authorization information for connecting to a Registry // AuthConfig contains authorization information for connecting to a Registry
type AuthConfig struct { type AuthConfig struct {

View File

@ -1,4 +1,4 @@
package blkiodev package blkiodev // import "github.com/docker/docker/api/types/blkiodev"
import "fmt" import "fmt"

View File

@ -1,4 +1,4 @@
package types package types // import "github.com/docker/docker/api/types"
import ( import (
"bufio" "bufio"
@ -74,6 +74,7 @@ type ContainerLogsOptions struct {
ShowStdout bool ShowStdout bool
ShowStderr bool ShowStderr bool
Since string Since string
Until string
Timestamps bool Timestamps bool
Follow bool Follow bool
Tail string Tail string
@ -180,8 +181,24 @@ type ImageBuildOptions struct {
Target string Target string
SessionID string SessionID string
Platform string Platform string
// Version specifies the version of the unerlying builder to use
Version BuilderVersion
// BuildID is an optional identifier that can be passed together with the
// build request. The same identifier can be used to gracefully cancel the
// build with the cancel request.
BuildID string
} }
// BuilderVersion sets the version of underlying builder to use
type BuilderVersion string
const (
// BuilderV1 is the first generation builder in docker daemon
BuilderV1 BuilderVersion = "1"
// BuilderBuildKit is builder based on moby/buildkit project
BuilderBuildKit = "2"
)
// ImageBuildResponse holds information // ImageBuildResponse holds information
// returned by a server after building // returned by a server after building
// an image. // an image.

View File

@ -1,4 +1,4 @@
package types package types // import "github.com/docker/docker/api/types"
import ( import (
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
@ -25,19 +25,6 @@ type ContainerRmConfig struct {
ForceRemove, RemoveVolume, RemoveLink bool ForceRemove, RemoveVolume, RemoveLink bool
} }
// ContainerCommitConfig contains build configs for commit operation,
// and is used when making a commit with the current state of the container.
type ContainerCommitConfig struct {
Pause bool
Repo string
Tag string
Author string
Comment string
// merge container config into commit config before commit
MergeConfigs bool
Config *container.Config
}
// ExecConfig is a small subset of the Config struct that holds the configuration // ExecConfig is a small subset of the Config struct that holds the configuration
// for the exec feature of docker. // for the exec feature of docker.
type ExecConfig struct { type ExecConfig struct {
@ -50,6 +37,7 @@ type ExecConfig struct {
Detach bool // Execute in detach mode Detach bool // Execute in detach mode
DetachKeys string // Escape keys for detach DetachKeys string // Escape keys for detach
Env []string // Environment variables Env []string // Environment variables
WorkingDir string // Working directory
Cmd []string // Execution commands and args Cmd []string // Execution commands and args
} }
@ -67,3 +55,10 @@ type PluginEnableConfig struct {
type PluginDisableConfig struct { type PluginDisableConfig struct {
ForceDisable bool ForceDisable bool
} }
// NetworkListConfig stores the options available for listing networks
type NetworkListConfig struct {
// TODO(@cpuguy83): naming is hard, this is pulled from what was being used in the router before moving here
Detailed bool
Verbose bool
}

View File

@ -1,4 +1,4 @@
package container package container // import "github.com/docker/docker/api/types/container"
import ( import (
"time" "time"

View File

@ -7,7 +7,7 @@ package container
// See hack/generate-swagger-api.sh // See hack/generate-swagger-api.sh
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ContainerChangeResponseItem container change response item // ContainerChangeResponseItem change item in response to ContainerChanges operation
// swagger:model ContainerChangeResponseItem // swagger:model ContainerChangeResponseItem
type ContainerChangeResponseItem struct { type ContainerChangeResponseItem struct {

View File

@ -7,7 +7,7 @@ package container
// See hack/generate-swagger-api.sh // See hack/generate-swagger-api.sh
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ContainerCreateCreatedBody container create created body // ContainerCreateCreatedBody OK response to ContainerCreate operation
// swagger:model ContainerCreateCreatedBody // swagger:model ContainerCreateCreatedBody
type ContainerCreateCreatedBody struct { type ContainerCreateCreatedBody struct {

View File

@ -7,7 +7,7 @@ package container
// See hack/generate-swagger-api.sh // See hack/generate-swagger-api.sh
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ContainerTopOKBody container top o k body // ContainerTopOKBody OK response to ContainerTop operation
// swagger:model ContainerTopOKBody // swagger:model ContainerTopOKBody
type ContainerTopOKBody struct { type ContainerTopOKBody struct {

View File

@ -7,7 +7,7 @@ package container
// See hack/generate-swagger-api.sh // See hack/generate-swagger-api.sh
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ContainerUpdateOKBody container update o k body // ContainerUpdateOKBody OK response to ContainerUpdate operation
// swagger:model ContainerUpdateOKBody // swagger:model ContainerUpdateOKBody
type ContainerUpdateOKBody struct { type ContainerUpdateOKBody struct {

View File

@ -7,10 +7,22 @@ package container
// See hack/generate-swagger-api.sh // See hack/generate-swagger-api.sh
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ContainerWaitOKBody container wait o k body // ContainerWaitOKBodyError container waiting error, if any
// swagger:model ContainerWaitOKBodyError
type ContainerWaitOKBodyError struct {
// Details of an error
Message string `json:"Message,omitempty"`
}
// ContainerWaitOKBody OK response to ContainerWait operation
// swagger:model ContainerWaitOKBody // swagger:model ContainerWaitOKBody
type ContainerWaitOKBody struct { type ContainerWaitOKBody struct {
// error
// Required: true
Error *ContainerWaitOKBodyError `json:"Error"`
// Exit code of the container // Exit code of the container
// Required: true // Required: true
StatusCode int64 `json:"StatusCode"` StatusCode int64 `json:"StatusCode"`

View File

@ -1,4 +1,4 @@
package container package container // import "github.com/docker/docker/api/types/container"
import ( import (
"strings" "strings"
@ -20,6 +20,27 @@ func (i Isolation) IsDefault() bool {
return strings.ToLower(string(i)) == "default" || string(i) == "" return strings.ToLower(string(i)) == "default" || string(i) == ""
} }
// IsHyperV indicates the use of a Hyper-V partition for isolation
func (i Isolation) IsHyperV() bool {
return strings.ToLower(string(i)) == "hyperv"
}
// IsProcess indicates the use of process isolation
func (i Isolation) IsProcess() bool {
return strings.ToLower(string(i)) == "process"
}
const (
// IsolationEmpty is unspecified (same behavior as default)
IsolationEmpty = Isolation("")
// IsolationDefault is the default isolation mode on current daemon
IsolationDefault = Isolation("default")
// IsolationProcess is process isolation mode
IsolationProcess = Isolation("process")
// IsolationHyperV is HyperV isolation mode
IsolationHyperV = Isolation("hyperv")
)
// IpcMode represents the container ipc stack. // IpcMode represents the container ipc stack.
type IpcMode string type IpcMode string
@ -308,11 +329,12 @@ type Resources struct {
DeviceCgroupRules []string // List of rule to be added to the device cgroup DeviceCgroupRules []string // List of rule to be added to the device cgroup
DiskQuota int64 // Disk limit (in bytes) DiskQuota int64 // Disk limit (in bytes)
KernelMemory int64 // Kernel memory limit (in bytes) KernelMemory int64 // Kernel memory limit (in bytes)
KernelMemoryTCP int64 // Hard limit for kernel TCP buffer memory (in bytes)
MemoryReservation int64 // Memory soft limit (in bytes) MemoryReservation int64 // Memory soft limit (in bytes)
MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap
MemorySwappiness *int64 // Tuning container memory swappiness behaviour MemorySwappiness *int64 // Tuning container memory swappiness behaviour
OomKillDisable *bool // Whether to disable OOM Killer or not OomKillDisable *bool // Whether to disable OOM Killer or not
PidsLimit int64 // Setting pids limit for a container PidsLimit *int64 // Setting PIDs limit for a container; Set `0` or `-1` for unlimited, or `null` to not change.
Ulimits []*units.Ulimit // List of ulimits to be set in the container Ulimits []*units.Ulimit // List of ulimits to be set in the container
// Applicable to Windows // Applicable to Windows
@ -348,9 +370,10 @@ type HostConfig struct {
// Applicable to UNIX platforms // Applicable to UNIX platforms
CapAdd strslice.StrSlice // List of kernel capabilities to add to the container CapAdd strslice.StrSlice // List of kernel capabilities to add to the container
CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container
DNS []string `json:"Dns"` // List of DNS server to lookup Capabilities []string `json:"Capabilities"` // List of kernel capabilities to be available for container (this overrides the default set)
DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for DNS []string `json:"Dns"` // List of DNS server to lookup
DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for
DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for
ExtraHosts []string // List of extra hosts ExtraHosts []string // List of extra hosts
GroupAdd []string // List of additional groups that the container process will run as GroupAdd []string // List of additional groups that the container process will run as
IpcMode IpcMode // IPC namespace to use for the container IpcMode IpcMode // IPC namespace to use for the container
@ -380,6 +403,12 @@ type HostConfig struct {
// Mounts specs used by the container // Mounts specs used by the container
Mounts []mount.Mount `json:",omitempty"` Mounts []mount.Mount `json:",omitempty"`
// MaskedPaths is the list of paths to be masked inside the container (this overrides the default set of paths)
MaskedPaths []string
// ReadonlyPaths is the list of paths to be set as read-only inside the container (this overrides the default set of paths)
ReadonlyPaths []string
// Run a custom init inside the container, if null, use the daemon's configured settings // Run a custom init inside the container, if null, use the daemon's configured settings
Init *bool `json:",omitempty"` Init *bool `json:",omitempty"`
} }

View File

@ -1,6 +1,6 @@
// +build !windows // +build !windows
package container package container // import "github.com/docker/docker/api/types/container"
// IsValid indicates if an isolation technology is valid // IsValid indicates if an isolation technology is valid
func (i Isolation) IsValid() bool { func (i Isolation) IsValid() bool {

View File

@ -1,8 +1,4 @@
package container package container // import "github.com/docker/docker/api/types/container"
import (
"strings"
)
// IsBridge indicates whether container uses the bridge network stack // IsBridge indicates whether container uses the bridge network stack
// in windows it is given the name NAT // in windows it is given the name NAT
@ -21,16 +17,6 @@ func (n NetworkMode) IsUserDefined() bool {
return !n.IsDefault() && !n.IsNone() && !n.IsBridge() && !n.IsContainer() return !n.IsDefault() && !n.IsNone() && !n.IsBridge() && !n.IsContainer()
} }
// IsHyperV indicates the use of a Hyper-V partition for isolation
func (i Isolation) IsHyperV() bool {
return strings.ToLower(string(i)) == "hyperv"
}
// IsProcess indicates the use of process isolation
func (i Isolation) IsProcess() bool {
return strings.ToLower(string(i)) == "process"
}
// IsValid indicates if an isolation technology is valid // IsValid indicates if an isolation technology is valid
func (i Isolation) IsValid() bool { func (i Isolation) IsValid() bool {
return i.IsDefault() || i.IsHyperV() || i.IsProcess() return i.IsDefault() || i.IsHyperV() || i.IsProcess()

View File

@ -1,4 +1,4 @@
package container package container // import "github.com/docker/docker/api/types/container"
// WaitCondition is a type used to specify a container state for which // WaitCondition is a type used to specify a container state for which
// to wait. // to wait.

View File

@ -1,4 +1,4 @@
package events package events // import "github.com/docker/docker/api/types/events"
const ( const (
// ContainerEventType is the event type that containers generate // ContainerEventType is the event type that containers generate

View File

@ -1,7 +1,7 @@
/*Package filters provides tools for encoding a mapping of keys to a set of /*Package filters provides tools for encoding a mapping of keys to a set of
multiple values. multiple values.
*/ */
package filters package filters // import "github.com/docker/docker/api/types/filters"
import ( import (
"encoding/json" "encoding/json"
@ -323,6 +323,22 @@ func (args Args) WalkValues(field string, op func(value string) error) error {
return nil return nil
} }
// Clone returns a copy of args.
func (args Args) Clone() (newArgs Args) {
newArgs.fields = make(map[string]map[string]bool, len(args.fields))
for k, m := range args.fields {
var mm map[string]bool
if m != nil {
mm = make(map[string]bool, len(m))
for kk, v := range m {
mm[kk] = v
}
}
newArgs.fields[k] = mm
}
return newArgs
}
func deprecatedArgs(d map[string][]string) map[string]map[string]bool { func deprecatedArgs(d map[string][]string) map[string]map[string]bool {
m := map[string]map[string]bool{} m := map[string]map[string]bool{}
for k, v := range d { for k, v := range d {

View File

@ -7,7 +7,7 @@ package image
// See hack/generate-swagger-api.sh // See hack/generate-swagger-api.sh
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// HistoryResponseItem history response item // HistoryResponseItem individual image layer information in response to ImageHistory operation
// swagger:model HistoryResponseItem // swagger:model HistoryResponseItem
type HistoryResponseItem struct { type HistoryResponseItem struct {

View File

@ -1,4 +1,4 @@
package mount package mount // import "github.com/docker/docker/api/types/mount"
import ( import (
"os" "os"
@ -79,7 +79,8 @@ const (
// BindOptions defines options specific to mounts of type "bind". // BindOptions defines options specific to mounts of type "bind".
type BindOptions struct { type BindOptions struct {
Propagation Propagation `json:",omitempty"` Propagation Propagation `json:",omitempty"`
NonRecursive bool `json:",omitempty"`
} }
// VolumeOptions represents the options for a mount of type volume. // VolumeOptions represents the options for a mount of type volume.

View File

@ -1,4 +1,8 @@
package network package network // import "github.com/docker/docker/api/types/network"
import (
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/errdefs"
)
// Address represents an IP address // Address represents an IP address
type Address struct { type Address struct {
@ -106,3 +110,18 @@ type NetworkingConfig struct {
type ConfigReference struct { type ConfigReference struct {
Network string Network string
} }
var acceptedFilters = map[string]bool{
"dangling": true,
"driver": true,
"id": true,
"label": true,
"name": true,
"scope": true,
"type": true,
}
// ValidateFilters validates the list of filter args with the available filters.
func ValidateFilters(filter filters.Args) error {
return errdefs.InvalidParameter(filter.Validate(acceptedFilters))
}

View File

@ -121,6 +121,9 @@ type PluginConfigArgs struct {
// swagger:model PluginConfigInterface // swagger:model PluginConfigInterface
type PluginConfigInterface struct { type PluginConfigInterface struct {
// Protocol to use for clients connecting to the plugin.
ProtocolScheme string `json:"ProtocolScheme,omitempty"`
// socket // socket
// Required: true // Required: true
Socket string `json:"Socket"` Socket string `json:"Socket"`

View File

@ -1,4 +1,4 @@
package types package types // import "github.com/docker/docker/api/types"
import ( import (
"encoding/json" "encoding/json"

View File

@ -7,7 +7,7 @@ package types
// swagger:model Port // swagger:model Port
type Port struct { type Port struct {
// IP // Host IP address that the container's port is mapped to
IP string `json:"IP,omitempty"` IP string `json:"IP,omitempty"`
// Port on the container // Port on the container

View File

@ -1,4 +1,4 @@
package registry package registry // import "github.com/docker/docker/api/types/registry"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE // DO NOT EDIT THIS FILE

View File

@ -1,4 +1,4 @@
package registry package registry // import "github.com/docker/docker/api/types/registry"
import ( import (
"encoding/json" "encoding/json"

View File

@ -1,4 +1,4 @@
package types package types // import "github.com/docker/docker/api/types"
// Seccomp represents the config for a seccomp profile for syscall restriction. // Seccomp represents the config for a seccomp profile for syscall restriction.
type Seccomp struct { type Seccomp struct {
@ -77,8 +77,9 @@ type Arg struct {
// Filter is used to conditionally apply Seccomp rules // Filter is used to conditionally apply Seccomp rules
type Filter struct { type Filter struct {
Caps []string `json:"caps,omitempty"` Caps []string `json:"caps,omitempty"`
Arches []string `json:"arches,omitempty"` Arches []string `json:"arches,omitempty"`
MinKernel string `json:"minKernel,omitempty"`
} }
// Syscall is used to match a group of syscalls in Seccomp // Syscall is used to match a group of syscalls in Seccomp

View File

@ -1,6 +1,6 @@
// Package types is used for API stability in the types and response to the // Package types is used for API stability in the types and response to the
// consumers of the API stats endpoint. // consumers of the API stats endpoint.
package types package types // import "github.com/docker/docker/api/types"
import "time" import "time"
@ -120,7 +120,7 @@ type NetworkStats struct {
RxBytes uint64 `json:"rx_bytes"` RxBytes uint64 `json:"rx_bytes"`
// Packets received. Windows and Linux. // Packets received. Windows and Linux.
RxPackets uint64 `json:"rx_packets"` RxPackets uint64 `json:"rx_packets"`
// Received errors. Not used on Windows. Note that we dont `omitempty` this // Received errors. Not used on Windows. Note that we don't `omitempty` this
// field as it is expected in the >=v1.21 API stats structure. // field as it is expected in the >=v1.21 API stats structure.
RxErrors uint64 `json:"rx_errors"` RxErrors uint64 `json:"rx_errors"`
// Incoming packets dropped. Windows and Linux. // Incoming packets dropped. Windows and Linux.
@ -129,7 +129,7 @@ type NetworkStats struct {
TxBytes uint64 `json:"tx_bytes"` TxBytes uint64 `json:"tx_bytes"`
// Packets sent. Windows and Linux. // Packets sent. Windows and Linux.
TxPackets uint64 `json:"tx_packets"` TxPackets uint64 `json:"tx_packets"`
// Sent errors. Not used on Windows. Note that we dont `omitempty` this // Sent errors. Not used on Windows. Note that we don't `omitempty` this
// field as it is expected in the >=v1.21 API stats structure. // field as it is expected in the >=v1.21 API stats structure.
TxErrors uint64 `json:"tx_errors"` TxErrors uint64 `json:"tx_errors"`
// Outgoing packets dropped. Windows and Linux. // Outgoing packets dropped. Windows and Linux.

View File

@ -1,4 +1,4 @@
package strslice package strslice // import "github.com/docker/docker/api/types/strslice"
import "encoding/json" import "encoding/json"

View File

@ -1,4 +1,4 @@
package swarm package swarm // import "github.com/docker/docker/api/types/swarm"
import "time" import "time"

View File

@ -1,4 +1,4 @@
package swarm package swarm // import "github.com/docker/docker/api/types/swarm"
import "os" import "os"
@ -13,6 +13,10 @@ type Config struct {
type ConfigSpec struct { type ConfigSpec struct {
Annotations Annotations
Data []byte `json:",omitempty"` Data []byte `json:",omitempty"`
// Templating controls whether and how to evaluate the config payload as
// a template. If it is not set, no templating is used.
Templating *Driver `json:",omitempty"`
} }
// ConfigReferenceFileTarget is a file target in a config reference // ConfigReferenceFileTarget is a file target in a config reference
@ -23,9 +27,14 @@ type ConfigReferenceFileTarget struct {
Mode os.FileMode Mode os.FileMode
} }
// ConfigReferenceRuntimeTarget is a target for a config specifying that it
// isn't mounted into the container but instead has some other purpose.
type ConfigReferenceRuntimeTarget struct{}
// ConfigReference is a reference to a config in swarm // ConfigReference is a reference to a config in swarm
type ConfigReference struct { type ConfigReference struct {
File *ConfigReferenceFileTarget File *ConfigReferenceFileTarget `json:",omitempty"`
Runtime *ConfigReferenceRuntimeTarget `json:",omitempty"`
ConfigID string ConfigID string
ConfigName string ConfigName string
} }

View File

@ -1,4 +1,4 @@
package swarm package swarm // import "github.com/docker/docker/api/types/swarm"
import ( import (
"time" "time"
@ -33,6 +33,7 @@ type SELinuxContext struct {
// CredentialSpec for managed service account (Windows only) // CredentialSpec for managed service account (Windows only)
type CredentialSpec struct { type CredentialSpec struct {
Config string
File string File string
Registry string Registry string
} }
@ -55,6 +56,7 @@ type ContainerSpec struct {
User string `json:",omitempty"` User string `json:",omitempty"`
Groups []string `json:",omitempty"` Groups []string `json:",omitempty"`
Privileges *Privileges `json:",omitempty"` Privileges *Privileges `json:",omitempty"`
Init *bool `json:",omitempty"`
StopSignal string `json:",omitempty"` StopSignal string `json:",omitempty"`
TTY bool `json:",omitempty"` TTY bool `json:",omitempty"`
OpenStdin bool `json:",omitempty"` OpenStdin bool `json:",omitempty"`
@ -65,8 +67,10 @@ type ContainerSpec struct {
// The format of extra hosts on swarmkit is specified in: // The format of extra hosts on swarmkit is specified in:
// http://man7.org/linux/man-pages/man5/hosts.5.html // http://man7.org/linux/man-pages/man5/hosts.5.html
// IP_address canonical_hostname [aliases...] // IP_address canonical_hostname [aliases...]
Hosts []string `json:",omitempty"` Hosts []string `json:",omitempty"`
DNSConfig *DNSConfig `json:",omitempty"` DNSConfig *DNSConfig `json:",omitempty"`
Secrets []*SecretReference `json:",omitempty"` Secrets []*SecretReference `json:",omitempty"`
Configs []*ConfigReference `json:",omitempty"` Configs []*ConfigReference `json:",omitempty"`
Isolation container.Isolation `json:",omitempty"`
Sysctls map[string]string `json:",omitempty"`
} }

View File

@ -1,4 +1,4 @@
package swarm package swarm // import "github.com/docker/docker/api/types/swarm"
import ( import (
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
@ -62,6 +62,8 @@ const (
PortConfigProtocolTCP PortConfigProtocol = "tcp" PortConfigProtocolTCP PortConfigProtocol = "tcp"
// PortConfigProtocolUDP UDP // PortConfigProtocolUDP UDP
PortConfigProtocolUDP PortConfigProtocol = "udp" PortConfigProtocolUDP PortConfigProtocol = "udp"
// PortConfigProtocolSCTP SCTP
PortConfigProtocolSCTP PortConfigProtocol = "sctp"
) )
// EndpointVirtualIP represents the virtual ip of a port. // EndpointVirtualIP represents the virtual ip of a port.

View File

@ -1,4 +1,4 @@
package swarm package swarm // import "github.com/docker/docker/api/types/swarm"
// Node represents a node. // Node represents a node.
type Node struct { type Node struct {

View File

@ -1,4 +1,4 @@
package swarm package swarm // import "github.com/docker/docker/api/types/swarm"
// RuntimeType is the type of runtime used for the TaskSpec // RuntimeType is the type of runtime used for the TaskSpec
type RuntimeType string type RuntimeType string
@ -11,9 +11,17 @@ const (
RuntimeContainer RuntimeType = "container" RuntimeContainer RuntimeType = "container"
// RuntimePlugin is the plugin based runtime // RuntimePlugin is the plugin based runtime
RuntimePlugin RuntimeType = "plugin" RuntimePlugin RuntimeType = "plugin"
// RuntimeNetworkAttachment is the network attachment runtime
RuntimeNetworkAttachment RuntimeType = "attachment"
// RuntimeURLContainer is the proto url for the container type // RuntimeURLContainer is the proto url for the container type
RuntimeURLContainer RuntimeURL = "types.docker.com/RuntimeContainer" RuntimeURLContainer RuntimeURL = "types.docker.com/RuntimeContainer"
// RuntimeURLPlugin is the proto url for the plugin type // RuntimeURLPlugin is the proto url for the plugin type
RuntimeURLPlugin RuntimeURL = "types.docker.com/RuntimePlugin" RuntimeURLPlugin RuntimeURL = "types.docker.com/RuntimePlugin"
) )
// NetworkAttachmentSpec represents the runtime spec type for network
// attachment tasks
type NetworkAttachmentSpec struct {
ContainerID string
}

View File

@ -1,3 +1,3 @@
//go:generate protoc -I . --gogofast_out=import_path=github.com/docker/docker/api/types/swarm/runtime:. plugin.proto //go:generate protoc -I . --gogofast_out=import_path=github.com/docker/docker/api/types/swarm/runtime:. plugin.proto
package runtime package runtime // import "github.com/docker/docker/api/types/swarm/runtime"

View File

@ -1,5 +1,7 @@
syntax = "proto3"; syntax = "proto3";
option go_package = "github.com/docker/docker/api/types/swarm/runtime;runtime";
// PluginSpec defines the base payload which clients can specify for creating // PluginSpec defines the base payload which clients can specify for creating
// a service with the plugin runtime. // a service with the plugin runtime.
message PluginSpec { message PluginSpec {

View File

@ -1,4 +1,4 @@
package swarm package swarm // import "github.com/docker/docker/api/types/swarm"
import "os" import "os"
@ -14,6 +14,10 @@ type SecretSpec struct {
Annotations Annotations
Data []byte `json:",omitempty"` Data []byte `json:",omitempty"`
Driver *Driver `json:",omitempty"` // name of the secrets driver used to fetch the secret's value from an external secret store Driver *Driver `json:",omitempty"` // name of the secrets driver used to fetch the secret's value from an external secret store
// Templating controls whether and how to evaluate the secret payload as
// a template. If it is not set, no templating is used.
Templating *Driver `json:",omitempty"`
} }
// SecretReferenceFileTarget is a file target in a secret reference // SecretReferenceFileTarget is a file target in a secret reference

View File

@ -1,4 +1,4 @@
package swarm package swarm // import "github.com/docker/docker/api/types/swarm"
import "time" import "time"

View File

@ -1,6 +1,8 @@
package swarm package swarm // import "github.com/docker/docker/api/types/swarm"
import "time" import (
"time"
)
// ClusterInfo represents info about the cluster for outputting 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
@ -10,6 +12,9 @@ type ClusterInfo struct {
Spec Spec Spec Spec
TLSInfo TLSInfo TLSInfo TLSInfo
RootRotationInProgress bool RootRotationInProgress bool
DefaultAddrPool []string
SubnetSize uint32
DataPathPort uint32
} }
// Swarm represents a swarm. // Swarm represents a swarm.
@ -149,10 +154,13 @@ type InitRequest struct {
ListenAddr string ListenAddr string
AdvertiseAddr string AdvertiseAddr string
DataPathAddr string DataPathAddr string
DataPathPort uint32
ForceNewCluster bool ForceNewCluster bool
Spec Spec Spec Spec
AutoLockManagers bool AutoLockManagers bool
Availability NodeAvailability Availability NodeAvailability
DefaultAddrPool []string
SubnetSize uint32
} }
// JoinRequest is the request used to join a swarm. // JoinRequest is the request used to join a swarm.

View File

@ -1,4 +1,4 @@
package swarm package swarm // import "github.com/docker/docker/api/types/swarm"
import ( import (
"time" "time"
@ -36,6 +36,10 @@ const (
TaskStateFailed TaskState = "failed" TaskStateFailed TaskState = "failed"
// TaskStateRejected REJECTED // TaskStateRejected REJECTED
TaskStateRejected TaskState = "rejected" TaskStateRejected TaskState = "rejected"
// TaskStateRemove REMOVE
TaskStateRemove TaskState = "remove"
// TaskStateOrphaned ORPHANED
TaskStateOrphaned TaskState = "orphaned"
) )
// Task represents a task. // Task represents a task.
@ -56,10 +60,13 @@ type Task struct {
// TaskSpec represents the spec of a task. // TaskSpec represents the spec of a task.
type TaskSpec struct { type TaskSpec struct {
// ContainerSpec and PluginSpec are mutually exclusive. // ContainerSpec, NetworkAttachmentSpec, and PluginSpec are mutually exclusive.
// PluginSpec will only be used when the `Runtime` field is set to `plugin` // PluginSpec is only used when the `Runtime` field is set to `plugin`
ContainerSpec *ContainerSpec `json:",omitempty"` // NetworkAttachmentSpec is used if the `Runtime` field is set to
PluginSpec *runtime.PluginSpec `json:",omitempty"` // `attachment`.
ContainerSpec *ContainerSpec `json:",omitempty"`
PluginSpec *runtime.PluginSpec `json:",omitempty"`
NetworkAttachmentSpec *NetworkAttachmentSpec `json:",omitempty"`
Resources *ResourceRequirements `json:",omitempty"` Resources *ResourceRequirements `json:",omitempty"`
RestartPolicy *RestartPolicy `json:",omitempty"` RestartPolicy *RestartPolicy `json:",omitempty"`
@ -120,6 +127,7 @@ type ResourceRequirements struct {
type Placement struct { type Placement struct {
Constraints []string `json:",omitempty"` Constraints []string `json:",omitempty"`
Preferences []PlacementPreference `json:",omitempty"` Preferences []PlacementPreference `json:",omitempty"`
MaxReplicas uint64 `json:",omitempty"`
// Platforms stores all the platforms that the image can run on. // Platforms stores all the platforms that the image can run on.
// This field is used in the platform filter for scheduling. If empty, // This field is used in the platform filter for scheduling. If empty,
@ -162,19 +170,19 @@ const (
// TaskStatus represents the status of a task. // TaskStatus represents the status of a task.
type TaskStatus struct { type TaskStatus struct {
Timestamp time.Time `json:",omitempty"` Timestamp time.Time `json:",omitempty"`
State TaskState `json:",omitempty"` State TaskState `json:",omitempty"`
Message string `json:",omitempty"` Message string `json:",omitempty"`
Err string `json:",omitempty"` Err string `json:",omitempty"`
ContainerStatus ContainerStatus `json:",omitempty"` ContainerStatus *ContainerStatus `json:",omitempty"`
PortStatus PortStatus `json:",omitempty"` PortStatus PortStatus `json:",omitempty"`
} }
// ContainerStatus represents the status of a container. // ContainerStatus represents the status of a container.
type ContainerStatus struct { type ContainerStatus struct {
ContainerID string `json:",omitempty"` ContainerID string
PID int `json:",omitempty"` PID int
ExitCode int `json:",omitempty"` ExitCode int
} }
// PortStatus represents the port status of a task's host ports whose // PortStatus represents the port status of a task's host ports whose

View File

@ -1,4 +1,4 @@
package time package time // import "github.com/docker/docker/api/types/time"
import ( import (
"strconv" "strconv"

View File

@ -1,4 +1,4 @@
package time package time // import "github.com/docker/docker/api/types/time"
import ( import (
"fmt" "fmt"
@ -82,11 +82,14 @@ func GetTimestamp(value string, reference time.Time) (string, error) {
} }
if err != nil { if err != nil {
// if there is a `-` then it's an RFC3339 like timestamp otherwise assume unixtimestamp // if there is a `-` then it's an RFC3339 like timestamp
if strings.Contains(value, "-") { if strings.Contains(value, "-") {
return "", err // was probably an RFC3339 like timestamp but the parser failed with an error return "", err // was probably an RFC3339 like timestamp but the parser failed with an error
} }
return value, nil // unixtimestamp in and out case (meaning: the value passed at the command line is already in the right format for passing to the server) if _, _, err := parseTimestamp(value); err != nil {
return "", fmt.Errorf("failed to parse value as time or duration: %q", value)
}
return value, nil // unix timestamp in and out case (meaning: the value passed at the command line is already in the right format for passing to the server)
} }
return fmt.Sprintf("%d.%09d", t.Unix(), int64(t.Nanosecond())), nil return fmt.Sprintf("%d.%09d", t.Unix(), int64(t.Nanosecond())), nil
@ -104,6 +107,10 @@ func ParseTimestamps(value string, def int64) (int64, int64, error) {
if value == "" { if value == "" {
return def, 0, nil return def, 0, nil
} }
return parseTimestamp(value)
}
func parseTimestamp(value string) (int64, int64, error) {
sa := strings.SplitN(value, ".", 2) sa := strings.SplitN(value, ".", 2)
s, err := strconv.ParseInt(sa[0], 10, 64) s, err := strconv.ParseInt(sa[0], 10, 64)
if err != nil { if err != nil {

View File

@ -1,4 +1,4 @@
package types package types // import "github.com/docker/docker/api/types"
import ( import (
"errors" "errors"
@ -102,14 +102,27 @@ type ContainerStats struct {
// Ping contains response of Engine API: // Ping contains response of Engine API:
// GET "/_ping" // GET "/_ping"
type Ping struct { type Ping struct {
APIVersion string APIVersion string
OSType string OSType string
Experimental bool Experimental bool
BuilderVersion BuilderVersion
}
// ComponentVersion describes the version information for a specific component.
type ComponentVersion struct {
Name string
Version string
Details map[string]string `json:",omitempty"`
} }
// Version contains response of Engine API: // Version contains response of Engine API:
// GET "/version" // GET "/version"
type Version struct { type Version struct {
Platform struct{ Name string } `json:",omitempty"`
Components []ComponentVersion `json:",omitempty"`
// The following fields are deprecated, they relate to the Engine component and are kept for backwards compatibility
Version string Version string
APIVersion string `json:"ApiVersion"` APIVersion string `json:"ApiVersion"`
MinAPIVersion string `json:"MinAPIVersion,omitempty"` MinAPIVersion string `json:"MinAPIVersion,omitempty"`
@ -133,6 +146,7 @@ type Commit struct {
// GET "/info" // GET "/info"
type Info struct { type Info struct {
ID string ID string
Builder BuilderVersion
Containers int Containers int
ContainersRunning int ContainersRunning int
ContainersPaused int ContainersPaused int
@ -145,10 +159,12 @@ type Info struct {
MemoryLimit bool MemoryLimit bool
SwapLimit bool SwapLimit bool
KernelMemory bool KernelMemory bool
KernelMemoryTCP bool
CPUCfsPeriod bool `json:"CpuCfsPeriod"` CPUCfsPeriod bool `json:"CpuCfsPeriod"`
CPUCfsQuota bool `json:"CpuCfsQuota"` CPUCfsQuota bool `json:"CpuCfsQuota"`
CPUShares bool CPUShares bool
CPUSet bool CPUSet bool
PidsLimit bool
IPv4Forwarding bool IPv4Forwarding bool
BridgeNfIptables bool BridgeNfIptables bool
BridgeNfIP6tables bool `json:"BridgeNfIp6tables"` BridgeNfIP6tables bool `json:"BridgeNfIp6tables"`
@ -192,6 +208,8 @@ type Info struct {
RuncCommit Commit RuncCommit Commit
InitCommit Commit InitCommit Commit
SecurityOptions []string SecurityOptions []string
ProductLicense string `json:",omitempty"`
Warnings []string
} }
// KeyValue holds a key/value pair // KeyValue holds a key/value pair
@ -500,7 +518,8 @@ type DiskUsage struct {
Images []*ImageSummary Images []*ImageSummary
Containers []*Container Containers []*Container
Volumes []*Volume Volumes []*Volume
BuilderSize int64 BuildCache []*BuildCache
BuilderSize int64 // deprecated
} }
// ContainersPruneReport contains the response for Engine API: // ContainersPruneReport contains the response for Engine API:
@ -527,6 +546,7 @@ type ImagesPruneReport struct {
// BuildCachePruneReport contains the response for Engine API: // BuildCachePruneReport contains the response for Engine API:
// POST "/build/prune" // POST "/build/prune"
type BuildCachePruneReport struct { type BuildCachePruneReport struct {
CachesDeleted []string
SpaceReclaimed uint64 SpaceReclaimed uint64
} }
@ -573,3 +593,24 @@ type PushResult struct {
type BuildResult struct { type BuildResult struct {
ID string ID string
} }
// BuildCache contains information about a build cache record
type BuildCache struct {
ID string
Parent string
Type string
Description string
InUse bool
Shared bool
Size int64
CreatedAt time.Time
LastUsedAt *time.Time
UsageCount int
}
// BuildCachePruneOptions hold parameters to prune the build cache
type BuildCachePruneOptions struct {
All bool
KeepStorage int64
Filters filters.Args
}

View File

@ -1,4 +1,4 @@
package versions package versions // import "github.com/docker/docker/api/types/versions"
import ( import (
"strconv" "strconv"

View File

@ -7,9 +7,9 @@ package volume
// See hack/generate-swagger-api.sh // See hack/generate-swagger-api.sh
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// VolumesCreateBody volumes create body // VolumeCreateBody Volume configuration
// swagger:model VolumesCreateBody // swagger:model VolumeCreateBody
type VolumesCreateBody struct { type VolumeCreateBody struct {
// Name of the volume driver to use. // Name of the volume driver to use.
// Required: true // Required: true

View File

@ -9,9 +9,9 @@ package volume
import "github.com/docker/docker/api/types" import "github.com/docker/docker/api/types"
// VolumesListOKBody volumes list o k body // VolumeListOKBody Volume list response
// swagger:model VolumesListOKBody // swagger:model VolumeListOKBody
type VolumesListOKBody struct { type VolumeListOKBody struct {
// List of volumes // List of volumes
// Required: true // Required: true

View File

@ -16,7 +16,7 @@ import (
) )
func main() { func main() {
cli, err := client.NewEnvClient() cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil { if err != nil {
panic(err) panic(err)
} }

20
vendor/github.com/docker/docker/client/build_cancel.go generated vendored Normal file
View File

@ -0,0 +1,20 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"net/url"
)
// BuildCancel requests the daemon to cancel ongoing build request
func (cli *Client) BuildCancel(ctx context.Context, id string) error {
query := url.Values{}
query.Set("id", id)
serverResp, err := cli.post(ctx, "/build/cancel", query, nil, nil)
if err != nil {
return err
}
defer ensureReaderClosed(serverResp)
return nil
}

View File

@ -1,22 +1,37 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"golang.org/x/net/context" "github.com/docker/docker/api/types/filters"
"github.com/pkg/errors"
) )
// BuildCachePrune requests the daemon to delete unused cache data // BuildCachePrune requests the daemon to delete unused cache data
func (cli *Client) BuildCachePrune(ctx context.Context) (*types.BuildCachePruneReport, error) { func (cli *Client) BuildCachePrune(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error) {
if err := cli.NewVersionError("1.31", "build prune"); err != nil { if err := cli.NewVersionError("1.31", "build prune"); err != nil {
return nil, err return nil, err
} }
report := types.BuildCachePruneReport{} report := types.BuildCachePruneReport{}
serverResp, err := cli.post(ctx, "/build/prune", nil, nil, nil) query := url.Values{}
if opts.All {
query.Set("all", "1")
}
query.Set("keep-storage", fmt.Sprintf("%d", opts.KeepStorage))
filters, err := filters.ToJSON(opts.Filters)
if err != nil {
return nil, errors.Wrap(err, "prune could not marshal filters option")
}
query.Set("filters", filters)
serverResp, err := cli.post(ctx, "/build/prune", query, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1,8 +1,9 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"golang.org/x/net/context"
) )
// CheckpointCreate creates a checkpoint from the given container with the given name // CheckpointCreate creates a checkpoint from the given container with the given name

View File

@ -1,10 +1,10 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"golang.org/x/net/context"
) )
// CheckpointDelete deletes the checkpoint with the given name from the given container // CheckpointDelete deletes the checkpoint with the given name from the given container

View File

@ -1,11 +1,11 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"golang.org/x/net/context"
) )
// CheckpointList returns the checkpoints of the given container in the docker host // CheckpointList returns the checkpoints of the given container in the docker host

View File

@ -23,7 +23,7 @@ For example, to list running containers (the equivalent of "docker ps"):
) )
func main() { func main() {
cli, err := client.NewEnvClient() cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -39,24 +39,22 @@ For example, to list running containers (the equivalent of "docker ps"):
} }
*/ */
package client package client // import "github.com/docker/docker/client"
import ( import (
"errors" "context"
"fmt" "fmt"
"net"
"net/http" "net/http"
"net/url" "net/url"
"os"
"path" "path"
"path/filepath"
"strings" "strings"
"github.com/docker/docker/api" "github.com/docker/docker/api"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
"github.com/docker/go-connections/sockets" "github.com/docker/go-connections/sockets"
"github.com/docker/go-connections/tlsconfig" "github.com/pkg/errors"
"golang.org/x/net/context"
) )
// ErrRedirect is the error returned by checkRedirect when the request is non-GET. // ErrRedirect is the error returned by checkRedirect when the request is non-GET.
@ -102,99 +100,62 @@ func CheckRedirect(req *http.Request, via []*http.Request) error {
return ErrRedirect return ErrRedirect
} }
// NewEnvClient initializes a new API client based on environment variables. // NewClientWithOpts initializes a new API client with default values. It takes functors
// Use DOCKER_HOST to set the url to the docker server. // to modify values when creating it, like `NewClientWithOpts(WithVersion(…))`
// Use DOCKER_API_VERSION to set the version of the API to reach, leave empty for latest.
// Use DOCKER_CERT_PATH to load the TLS certificates from.
// Use DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default.
func NewEnvClient() (*Client, error) {
var client *http.Client
if dockerCertPath := os.Getenv("DOCKER_CERT_PATH"); dockerCertPath != "" {
options := tlsconfig.Options{
CAFile: filepath.Join(dockerCertPath, "ca.pem"),
CertFile: filepath.Join(dockerCertPath, "cert.pem"),
KeyFile: filepath.Join(dockerCertPath, "key.pem"),
InsecureSkipVerify: os.Getenv("DOCKER_TLS_VERIFY") == "",
}
tlsc, err := tlsconfig.Client(options)
if err != nil {
return nil, err
}
client = &http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsc,
},
CheckRedirect: CheckRedirect,
}
}
host := os.Getenv("DOCKER_HOST")
if host == "" {
host = DefaultDockerHost
}
version := os.Getenv("DOCKER_API_VERSION")
if version == "" {
version = api.DefaultVersion
}
cli, err := NewClient(host, version, client, nil)
if err != nil {
return cli, err
}
if os.Getenv("DOCKER_API_VERSION") != "" {
cli.manualOverride = true
}
return cli, nil
}
// NewClient initializes a new API client for the given host and API version.
// It uses the given http client as transport.
// It also initializes the custom http headers to add to each request. // It also initializes the custom http headers to add to each request.
// //
// It won't send any version information if the version number is empty. It is // It won't send any version information if the version number is empty. It is
// highly recommended that you set a version or your client may break if the // highly recommended that you set a version or your client may break if the
// server is upgraded. // server is upgraded.
func NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) { func NewClientWithOpts(ops ...func(*Client) error) (*Client, error) {
hostURL, err := ParseHostURL(host) client, err := defaultHTTPClient(DefaultDockerHost)
if err != nil { if err != nil {
return nil, err return nil, err
} }
c := &Client{
host: DefaultDockerHost,
version: api.DefaultVersion,
client: client,
proto: defaultProto,
addr: defaultAddr,
}
if client != nil { for _, op := range ops {
if _, ok := client.Transport.(http.RoundTripper); !ok { if err := op(c); err != nil {
return nil, fmt.Errorf("unable to verify TLS configuration, invalid transport %v", client.Transport) return nil, err
}
} else {
transport := new(http.Transport)
sockets.ConfigureTransport(transport, hostURL.Scheme, hostURL.Host)
client = &http.Client{
Transport: transport,
CheckRedirect: CheckRedirect,
} }
} }
scheme := "http" if _, ok := c.client.Transport.(http.RoundTripper); !ok {
tlsConfig := resolveTLSConfig(client.Transport) return nil, fmt.Errorf("unable to verify TLS configuration, invalid transport %v", c.client.Transport)
if tlsConfig != nil { }
// TODO(stevvooe): This isn't really the right way to write clients in Go. if c.scheme == "" {
// `NewClient` should probably only take an `*http.Client` and work from there. c.scheme = "http"
// Unfortunately, the model of having a host-ish/url-thingy as the connection
// string has us confusing protocol and transport layers. We continue doing tlsConfig := resolveTLSConfig(c.client.Transport)
// this to avoid breaking existing clients but this should be addressed. if tlsConfig != nil {
scheme = "https" // TODO(stevvooe): This isn't really the right way to write clients in Go.
// `NewClient` should probably only take an `*http.Client` and work from there.
// Unfortunately, the model of having a host-ish/url-thingy as the connection
// string has us confusing protocol and transport layers. We continue doing
// this to avoid breaking existing clients but this should be addressed.
c.scheme = "https"
}
} }
// TODO: store URL instead of proto/addr/basePath return c, nil
return &Client{ }
scheme: scheme,
host: host, func defaultHTTPClient(host string) (*http.Client, error) {
proto: hostURL.Scheme, url, err := ParseHostURL(host)
addr: hostURL.Host, if err != nil {
basePath: hostURL.Path, return nil, err
client: client, }
version: version, transport := new(http.Transport)
customHTTPHeaders: httpHeaders, sockets.ConfigureTransport(transport, url.Scheme, url.Host)
return &http.Client{
Transport: transport,
CheckRedirect: CheckRedirect,
}, nil }, nil
} }
@ -259,15 +220,9 @@ func (cli *Client) DaemonHost() string {
return cli.host return cli.host
} }
// ParseHost parses a url string, validates the strings is a host url, and returns // HTTPClient returns a copy of the HTTP client bound to the server
// the parsed host as: protocol, address, and base path func (cli *Client) HTTPClient() *http.Client {
// Deprecated: use ParseHostURL return &*cli.client
func ParseHost(host string) (string, string, string, error) {
hostURL, err := ParseHostURL(host)
if err != nil {
return "", "", "", err
}
return hostURL.Scheme, hostURL.Host, hostURL.Path, nil
} }
// ParseHostURL parses a url string, validates the string is a host url, and // ParseHostURL parses a url string, validates the string is a host url, and
@ -305,6 +260,20 @@ func (cli *Client) CustomHTTPHeaders() map[string]string {
} }
// SetCustomHTTPHeaders that will be set on every HTTP request made by the client. // SetCustomHTTPHeaders that will be set on every HTTP request made by the client.
// Deprecated: use WithHTTPHeaders when creating the client.
func (cli *Client) SetCustomHTTPHeaders(headers map[string]string) { func (cli *Client) SetCustomHTTPHeaders(headers map[string]string) {
cli.customHTTPHeaders = headers cli.customHTTPHeaders = headers
} }
// Dialer returns a dialer for a raw stream connection, with HTTP/1.1 header, that can be used for proxying the daemon connection.
// Used by `docker dial-stdio` (docker/cli#889).
func (cli *Client) Dialer() func(context.Context) (net.Conn, error) {
return func(ctx context.Context) (net.Conn, error) {
if transport, ok := cli.client.Transport.(*http.Transport); ok {
if transport.DialContext != nil && transport.TLSClientConfig == nil {
return transport.DialContext(ctx, cli.proto, cli.addr)
}
}
return fallbackDial(cli.proto, cli.addr, resolveTLSConfig(cli.client.Transport))
}
}

View File

@ -0,0 +1,23 @@
package client
import "net/http"
// NewClient initializes a new API client for the given host and API version.
// It uses the given http client as transport.
// It also initializes the custom http headers to add to each request.
//
// It won't send any version information if the version number is empty. It is
// highly recommended that you set a version or your client may break if the
// server is upgraded.
// Deprecated: use NewClientWithOpts
func NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) {
return NewClientWithOpts(WithHost(host), WithVersion(version), WithHTTPClient(client), WithHTTPHeaders(httpHeaders))
}
// NewEnvClient initializes a new API client based on environment variables.
// See FromEnv for a list of support environment variables.
//
// Deprecated: use NewClientWithOpts(FromEnv)
func NewEnvClient() (*Client, error) {
return NewClientWithOpts(FromEnv)
}

View File

@ -1,6 +1,9 @@
// +build linux freebsd solaris openbsd darwin // +build linux freebsd openbsd darwin
package client package client // import "github.com/docker/docker/client"
// DefaultDockerHost defines os specific default if DOCKER_HOST is unset // DefaultDockerHost defines os specific default if DOCKER_HOST is unset
const DefaultDockerHost = "unix:///var/run/docker.sock" const DefaultDockerHost = "unix:///var/run/docker.sock"
const defaultProto = "unix"
const defaultAddr = "/var/run/docker.sock"

View File

@ -1,4 +1,7 @@
package client package client // import "github.com/docker/docker/client"
// DefaultDockerHost defines os specific default if DOCKER_HOST is unset // DefaultDockerHost defines os specific default if DOCKER_HOST is unset
const DefaultDockerHost = "npipe:////./pipe/docker_engine" const DefaultDockerHost = "npipe:////./pipe/docker_engine"
const defaultProto = "npipe"
const defaultAddr = "//./pipe/docker_engine"

View File

@ -1,11 +1,11 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context"
) )
// ConfigCreate creates a new Config. // ConfigCreate creates a new Config.

View File

@ -1,16 +1,19 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"bytes" "bytes"
"context"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context"
) )
// ConfigInspectWithRaw returns the config information with raw data // ConfigInspectWithRaw returns the config information with raw data
func (cli *Client) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.Config, []byte, error) { func (cli *Client) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.Config, []byte, error) {
if id == "" {
return swarm.Config{}, nil, objectNotFoundError{object: "config", id: id}
}
if err := cli.NewVersionError("1.30", "config inspect"); err != nil { if err := cli.NewVersionError("1.30", "config inspect"); err != nil {
return swarm.Config{}, nil, err return swarm.Config{}, nil, err
} }

View File

@ -1,13 +1,13 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context"
) )
// ConfigList returns the list of configs. // ConfigList returns the list of configs.

View File

@ -1,6 +1,6 @@
package client package client // import "github.com/docker/docker/client"
import "golang.org/x/net/context" import "context"
// ConfigRemove removes a Config. // ConfigRemove removes a Config.
func (cli *Client) ConfigRemove(ctx context.Context, id string) error { func (cli *Client) ConfigRemove(ctx context.Context, id string) error {

View File

@ -1,11 +1,11 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"net/url" "net/url"
"strconv" "strconv"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context"
) )
// ConfigUpdate attempts to update a Config // ConfigUpdate attempts to update a Config

View File

@ -1,10 +1,10 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"golang.org/x/net/context"
) )
// ContainerAttach attaches a connection to a container in the server. // ContainerAttach attaches a connection to a container in the server.

View File

@ -1,13 +1,13 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"errors" "errors"
"net/url" "net/url"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"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.

View File

@ -1,6 +1,7 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
@ -10,8 +11,6 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"golang.org/x/net/context"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
) )
@ -23,17 +22,17 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri
urlStr := "/containers/" + containerID + "/archive" urlStr := "/containers/" + containerID + "/archive"
response, err := cli.head(ctx, urlStr, query, nil) response, err := cli.head(ctx, urlStr, query, nil)
if err != nil { if err != nil {
return types.ContainerPathStat{}, err return types.ContainerPathStat{}, wrapResponseError(err, response, "container:path", containerID+":"+path)
} }
defer ensureReaderClosed(response) defer ensureReaderClosed(response)
return getContainerPathStatFromHeader(response.header) return getContainerPathStatFromHeader(response.header)
} }
// CopyToContainer copies content into the container filesystem. // CopyToContainer copies content into the container filesystem.
// Note that `content` must be a Reader for a TAR // Note that `content` must be a Reader for a TAR archive
func (cli *Client) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error { func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader, options types.CopyToContainerOptions) error {
query := url.Values{} query := url.Values{}
query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API. query.Set("path", filepath.ToSlash(dstPath)) // Normalize the paths used in the API.
// Do not allow for an existing directory to be overwritten by a non-directory and vice versa. // Do not allow for an existing directory to be overwritten by a non-directory and vice versa.
if !options.AllowOverwriteDirWithFile { if !options.AllowOverwriteDirWithFile {
query.Set("noOverwriteDirNonDir", "true") query.Set("noOverwriteDirNonDir", "true")
@ -43,11 +42,11 @@ func (cli *Client) CopyToContainer(ctx context.Context, container, path string,
query.Set("copyUIDGID", "true") query.Set("copyUIDGID", "true")
} }
apiPath := "/containers/" + container + "/archive" apiPath := "/containers/" + containerID + "/archive"
response, err := cli.putRaw(ctx, apiPath, query, content, nil) response, err := cli.putRaw(ctx, apiPath, query, content, nil)
if err != nil { if err != nil {
return err return wrapResponseError(err, response, "container:path", containerID+":"+dstPath)
} }
defer ensureReaderClosed(response) defer ensureReaderClosed(response)
@ -59,15 +58,15 @@ func (cli *Client) CopyToContainer(ctx context.Context, container, path string,
} }
// CopyFromContainer gets the content from the container and returns it as a Reader // CopyFromContainer gets the content from the container and returns it as a Reader
// to manipulate it in the host. It's up to the caller to close the reader. // for a TAR archive to manipulate it in the host. It's up to the caller to close the reader.
func (cli *Client) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) {
query := make(url.Values, 1) query := make(url.Values, 1)
query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API. query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API.
apiPath := "/containers/" + container + "/archive" apiPath := "/containers/" + containerID + "/archive"
response, err := cli.get(ctx, apiPath, query, nil) response, err := cli.get(ctx, apiPath, query, nil)
if err != nil { if err != nil {
return nil, types.ContainerPathStat{}, err return nil, types.ContainerPathStat{}, wrapResponseError(err, response, "container:path", containerID+":"+srcPath)
} }
if response.statusCode != http.StatusOK { if response.statusCode != http.StatusOK {

View File

@ -1,6 +1,7 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"net/url" "net/url"
"strings" "strings"
@ -8,7 +9,6 @@ import (
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
"golang.org/x/net/context"
) )
type configWrapper struct { type configWrapper struct {

View File

@ -1,11 +1,11 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"golang.org/x/net/context"
) )
// ContainerDiff shows differences in a container filesystem since it was started. // ContainerDiff shows differences in a container filesystem since it was started.

View File

@ -1,10 +1,10 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"golang.org/x/net/context"
) )
// ContainerExecCreate creates a new exec configuration to run an exec process. // ContainerExecCreate creates a new exec configuration to run an exec process.

View File

@ -1,10 +1,9 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"io" "io"
"net/url" "net/url"
"golang.org/x/net/context"
) )
// ContainerExport retrieves the raw contents of a container // ContainerExport retrieves the raw contents of a container

View File

@ -1,30 +1,36 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"bytes" "bytes"
"context"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"golang.org/x/net/context"
) )
// ContainerInspect returns the container information. // ContainerInspect returns the container information.
func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) { func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) {
if containerID == "" {
return types.ContainerJSON{}, objectNotFoundError{object: "container", id: containerID}
}
serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil) serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil)
if err != nil { if err != nil {
return types.ContainerJSON{}, wrapResponseError(err, serverResp, "container", containerID) return types.ContainerJSON{}, wrapResponseError(err, serverResp, "container", containerID)
} }
defer ensureReaderClosed(serverResp)
var response types.ContainerJSON var response types.ContainerJSON
err = json.NewDecoder(serverResp.body).Decode(&response) err = json.NewDecoder(serverResp.body).Decode(&response)
ensureReaderClosed(serverResp)
return response, err return response, err
} }
// ContainerInspectWithRaw returns the container information and its raw representation. // ContainerInspectWithRaw returns the container information and its raw representation.
func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool) (types.ContainerJSON, []byte, error) { func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool) (types.ContainerJSON, []byte, error) {
if containerID == "" {
return types.ContainerJSON{}, nil, objectNotFoundError{object: "container", id: containerID}
}
query := url.Values{} query := url.Values{}
if getSize { if getSize {
query.Set("size", "1") query.Set("size", "1")

View File

@ -1,9 +1,8 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"net/url" "net/url"
"golang.org/x/net/context"
) )
// ContainerKill terminates the container process but does not remove the container from the docker host. // ContainerKill terminates the container process but does not remove the container from the docker host.

View File

@ -1,13 +1,13 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"net/url" "net/url"
"strconv" "strconv"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"golang.org/x/net/context"
) )
// ContainerList returns the list of containers in the docker host. // ContainerList returns the list of containers in the docker host.

View File

@ -1,14 +1,14 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"io" "io"
"net/url" "net/url"
"time" "time"
"golang.org/x/net/context"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
timetypes "github.com/docker/docker/api/types/time" timetypes "github.com/docker/docker/api/types/time"
"github.com/pkg/errors"
) )
// ContainerLogs returns the logs generated by a container in an io.ReadCloser. // ContainerLogs returns the logs generated by a container in an io.ReadCloser.
@ -46,11 +46,19 @@ func (cli *Client) ContainerLogs(ctx context.Context, container string, options
if options.Since != "" { if options.Since != "" {
ts, err := timetypes.GetTimestamp(options.Since, time.Now()) ts, err := timetypes.GetTimestamp(options.Since, time.Now())
if err != nil { if err != nil {
return nil, err return nil, errors.Wrap(err, `invalid value for "since"`)
} }
query.Set("since", ts) query.Set("since", ts)
} }
if options.Until != "" {
ts, err := timetypes.GetTimestamp(options.Until, time.Now())
if err != nil {
return nil, errors.Wrap(err, `invalid value for "until"`)
}
query.Set("until", ts)
}
if options.Timestamps { if options.Timestamps {
query.Set("timestamps", "1") query.Set("timestamps", "1")
} }
@ -66,7 +74,7 @@ func (cli *Client) ContainerLogs(ctx context.Context, container string, options
resp, err := cli.get(ctx, "/containers/"+container+"/logs", query, nil) resp, err := cli.get(ctx, "/containers/"+container+"/logs", query, nil)
if err != nil { if err != nil {
return nil, err return nil, wrapResponseError(err, resp, "container", container)
} }
return resp.body, nil return resp.body, nil
} }

View File

@ -1,6 +1,6 @@
package client package client // import "github.com/docker/docker/client"
import "golang.org/x/net/context" import "context"
// ContainerPause pauses the main process of a given container without terminating it. // ContainerPause pauses the main process of a given container without terminating it.
func (cli *Client) ContainerPause(ctx context.Context, containerID string) error { func (cli *Client) ContainerPause(ctx context.Context, containerID string) error {

View File

@ -1,12 +1,12 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"golang.org/x/net/context"
) )
// ContainersPrune requests the daemon to delete unused data // ContainersPrune requests the daemon to delete unused data

View File

@ -1,10 +1,10 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"golang.org/x/net/context"
) )
// ContainerRemove kills and removes a container from the docker host. // ContainerRemove kills and removes a container from the docker host.

View File

@ -1,9 +1,8 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"net/url" "net/url"
"golang.org/x/net/context"
) )
// ContainerRename changes the name of a given container. // ContainerRename changes the name of a given container.

View File

@ -1,11 +1,11 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"net/url" "net/url"
"strconv" "strconv"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"golang.org/x/net/context"
) )
// ContainerResize changes the size of the tty for a container. // ContainerResize changes the size of the tty for a container.

View File

@ -1,11 +1,11 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"net/url" "net/url"
"time" "time"
timetypes "github.com/docker/docker/api/types/time" timetypes "github.com/docker/docker/api/types/time"
"golang.org/x/net/context"
) )
// ContainerRestart stops and starts a container again. // ContainerRestart stops and starts a container again.

View File

@ -1,10 +1,9 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"net/url" "net/url"
"golang.org/x/net/context"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
) )

View File

@ -1,10 +1,10 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"golang.org/x/net/context"
) )
// ContainerStats returns near realtime stats for a given container. // ContainerStats returns near realtime stats for a given container.

View File

@ -1,15 +1,20 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"net/url" "net/url"
"time" "time"
timetypes "github.com/docker/docker/api/types/time" timetypes "github.com/docker/docker/api/types/time"
"golang.org/x/net/context"
) )
// ContainerStop stops a container without terminating the process. // ContainerStop stops a container. In case the container fails to stop
// The process is blocked until the container stops or the timeout expires. // gracefully within a time frame specified by the timeout argument,
// it is forcefully terminated (killed).
//
// If the timeout is nil, the container's StopTimeout value is used, if set,
// otherwise the engine default. A negative timeout value can be specified,
// meaning no timeout, i.e. no forceful termination is performed.
func (cli *Client) ContainerStop(ctx context.Context, containerID string, timeout *time.Duration) error { func (cli *Client) ContainerStop(ctx context.Context, containerID string, timeout *time.Duration) error {
query := url.Values{} query := url.Values{}
if timeout != nil { if timeout != nil {

View File

@ -1,12 +1,12 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"net/url" "net/url"
"strings" "strings"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"golang.org/x/net/context"
) )
// ContainerTop shows process information from within a container. // ContainerTop shows process information from within a container.

View File

@ -1,6 +1,6 @@
package client package client // import "github.com/docker/docker/client"
import "golang.org/x/net/context" import "context"
// ContainerUnpause resumes the process execution within a container // ContainerUnpause resumes the process execution within a container
func (cli *Client) ContainerUnpause(ctx context.Context, containerID string) error { func (cli *Client) ContainerUnpause(ctx context.Context, containerID string) error {

View File

@ -1,10 +1,10 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"golang.org/x/net/context"
) )
// ContainerUpdate updates resources of a container // ContainerUpdate updates resources of a container

View File

@ -1,11 +1,10 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"net/url" "net/url"
"golang.org/x/net/context"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
) )

View File

@ -1,11 +1,11 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"golang.org/x/net/context"
) )
// DiskUsage requests the current data usage from the daemon // DiskUsage requests the current data usage from the daemon

View File

@ -1,17 +1,20 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"net/url" "net/url"
registrytypes "github.com/docker/docker/api/types/registry" registrytypes "github.com/docker/docker/api/types/registry"
"golang.org/x/net/context"
) )
// DistributionInspect returns the image digest with full Manifest // DistributionInspect returns the image digest with full Manifest
func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegistryAuth string) (registrytypes.DistributionInspect, error) { func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegistryAuth string) (registrytypes.DistributionInspect, error) {
// Contact the registry to retrieve digest and platform information // Contact the registry to retrieve digest and platform information
var distributionInspect registrytypes.DistributionInspect var distributionInspect registrytypes.DistributionInspect
if image == "" {
return distributionInspect, objectNotFoundError{object: "distribution", id: image}
}
if err := cli.NewVersionError("1.30", "distribution inspect"); err != nil { if err := cli.NewVersionError("1.30", "distribution inspect"); err != nil {
return distributionInspect, err return distributionInspect, err

View File

@ -1,8 +1,7 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"

View File

@ -1,12 +1,11 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"net/url" "net/url"
"time" "time"
"golang.org/x/net/context"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"

View File

@ -1,37 +1,21 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"bufio" "bufio"
"context"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
"net/http/httputil" "net/http/httputil"
"net/url" "net/url"
"strings"
"time" "time"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/go-connections/sockets" "github.com/docker/go-connections/sockets"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/net/context"
) )
// tlsClientCon holds tls information and a dialed connection.
type tlsClientCon struct {
*tls.Conn
rawConn net.Conn
}
func (c *tlsClientCon) CloseWrite() error {
// Go standard tls.Conn doesn't provide the CloseWrite() method so we do it
// on its underlying connection.
if conn, ok := c.rawConn.(types.CloseWriter); ok {
return conn.CloseWrite()
}
return nil
}
// postHijacked sends a POST request and hijacks the connection. // postHijacked sends a POST request and hijacks the connection.
func (cli *Client) postHijacked(ctx context.Context, path string, query url.Values, body interface{}, headers map[string][]string) (types.HijackedResponse, error) { func (cli *Client) postHijacked(ctx context.Context, path string, query url.Values, body interface{}, headers map[string][]string) (types.HijackedResponse, error) {
bodyEncoded, err := encodeData(body) bodyEncoded, err := encodeData(body)
@ -46,7 +30,7 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu
} }
req = cli.addHeaders(req, headers) req = cli.addHeaders(req, headers)
conn, err := cli.setupHijackConn(req, "tcp") conn, err := cli.setupHijackConn(ctx, req, "tcp")
if err != nil { if err != nil {
return types.HijackedResponse{}, err return types.HijackedResponse{}, err
} }
@ -54,96 +38,11 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu
return types.HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn)}, err return types.HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn)}, err
} }
func tlsDial(network, addr string, config *tls.Config) (net.Conn, error) { // fallbackDial is used when WithDialer() was not called.
return tlsDialWithDialer(new(net.Dialer), network, addr, config) // See cli.Dialer().
} func fallbackDial(proto, addr string, tlsConfig *tls.Config) (net.Conn, error) {
// We need to copy Go's implementation of tls.Dial (pkg/cryptor/tls/tls.go) in
// order to return our custom tlsClientCon struct which holds both the tls.Conn
// object _and_ its underlying raw connection. The rationale for this is that
// we need to be able to close the write end of the connection when attaching,
// which tls.Conn does not provide.
func tlsDialWithDialer(dialer *net.Dialer, network, addr string, config *tls.Config) (net.Conn, error) {
// We want the Timeout and Deadline values from dialer to cover the
// whole process: TCP connection and TLS handshake. This means that we
// also need to start our own timers now.
timeout := dialer.Timeout
if !dialer.Deadline.IsZero() {
deadlineTimeout := time.Until(dialer.Deadline)
if timeout == 0 || deadlineTimeout < timeout {
timeout = deadlineTimeout
}
}
var errChannel chan error
if timeout != 0 {
errChannel = make(chan error, 2)
time.AfterFunc(timeout, func() {
errChannel <- errors.New("")
})
}
proxyDialer, err := sockets.DialerFromEnvironment(dialer)
if err != nil {
return nil, err
}
rawConn, err := proxyDialer.Dial(network, addr)
if err != nil {
return nil, err
}
// When we set up a TCP connection for hijack, there could be long periods
// of inactivity (a long running command with no output) that in certain
// network setups may cause ECONNTIMEOUT, leaving the client in an unknown
// state. Setting TCP KeepAlive on the socket connection will prohibit
// ECONNTIMEOUT unless the socket connection truly is broken
if tcpConn, ok := rawConn.(*net.TCPConn); ok {
tcpConn.SetKeepAlive(true)
tcpConn.SetKeepAlivePeriod(30 * time.Second)
}
colonPos := strings.LastIndex(addr, ":")
if colonPos == -1 {
colonPos = len(addr)
}
hostname := addr[:colonPos]
// If no ServerName is set, infer the ServerName
// from the hostname we're connecting to.
if config.ServerName == "" {
// Make a copy to avoid polluting argument or default.
config = tlsConfigClone(config)
config.ServerName = hostname
}
conn := tls.Client(rawConn, config)
if timeout == 0 {
err = conn.Handshake()
} else {
go func() {
errChannel <- conn.Handshake()
}()
err = <-errChannel
}
if err != nil {
rawConn.Close()
return nil, err
}
// This is Docker difference with standard's crypto/tls package: returned a
// wrapper which holds both the TLS and raw connections.
return &tlsClientCon{conn, rawConn}, nil
}
func dial(proto, addr string, tlsConfig *tls.Config) (net.Conn, error) {
if tlsConfig != nil && proto != "unix" && proto != "npipe" { if tlsConfig != nil && proto != "unix" && proto != "npipe" {
// Notice this isn't Go standard's tls.Dial function return tls.Dial(proto, addr, tlsConfig)
return tlsDial(proto, addr, tlsConfig)
} }
if proto == "npipe" { if proto == "npipe" {
return sockets.DialPipe(addr, 32*time.Second) return sockets.DialPipe(addr, 32*time.Second)
@ -151,12 +50,13 @@ func dial(proto, addr string, tlsConfig *tls.Config) (net.Conn, error) {
return net.Dial(proto, addr) return net.Dial(proto, addr)
} }
func (cli *Client) setupHijackConn(req *http.Request, proto string) (net.Conn, error) { func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto string) (net.Conn, error) {
req.Host = cli.addr req.Host = cli.addr
req.Header.Set("Connection", "Upgrade") req.Header.Set("Connection", "Upgrade")
req.Header.Set("Upgrade", proto) req.Header.Set("Upgrade", proto)
conn, err := dial(cli.proto, cli.addr, resolveTLSConfig(cli.client.Transport)) dialer := cli.Dialer()
conn, err := dialer(ctx)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "cannot connect to the Docker daemon. Is 'docker daemon' running on this host?") return nil, errors.Wrap(err, "cannot connect to the Docker daemon. Is 'docker daemon' running on this host?")
} }
@ -188,8 +88,14 @@ func (cli *Client) setupHijackConn(req *http.Request, proto string) (net.Conn, e
c, br := clientconn.Hijack() c, br := clientconn.Hijack()
if br.Buffered() > 0 { if br.Buffered() > 0 {
// If there is buffered content, wrap the connection // If there is buffered content, wrap the connection. We return an
c = &hijackedConn{c, br} // object that implements CloseWrite iff the underlying connection
// implements it.
if _, ok := c.(types.CloseWriter); ok {
c = &hijackedConnCloseWriter{&hijackedConn{c, br}}
} else {
c = &hijackedConn{c, br}
}
} else { } else {
br.Reset(nil) br.Reset(nil)
} }
@ -197,6 +103,10 @@ func (cli *Client) setupHijackConn(req *http.Request, proto string) (net.Conn, e
return c, nil return c, nil
} }
// hijackedConn wraps a net.Conn and is returned by setupHijackConn in the case
// that a) there was already buffered data in the http layer when Hijack() was
// called, and b) the underlying net.Conn does *not* implement CloseWrite().
// hijackedConn does not implement CloseWrite() either.
type hijackedConn struct { type hijackedConn struct {
net.Conn net.Conn
r *bufio.Reader r *bufio.Reader
@ -205,3 +115,18 @@ type hijackedConn struct {
func (c *hijackedConn) Read(b []byte) (int, error) { func (c *hijackedConn) Read(b []byte) (int, error) {
return c.r.Read(b) return c.r.Read(b)
} }
// hijackedConnCloseWriter is a hijackedConn which additionally implements
// CloseWrite(). It is returned by setupHijackConn in the case that a) there
// was already buffered data in the http layer when Hijack() was called, and b)
// the underlying net.Conn *does* implement CloseWrite().
type hijackedConnCloseWriter struct {
*hijackedConn
}
var _ types.CloseWriter = &hijackedConnCloseWriter{}
func (c *hijackedConnCloseWriter) CloseWrite() error {
conn := c.Conn.(types.CloseWriter)
return conn.CloseWrite()
}

View File

@ -1,6 +1,7 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"io" "io"
@ -9,8 +10,6 @@ import (
"strconv" "strconv"
"strings" "strings"
"golang.org/x/net/context"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
) )
@ -31,12 +30,6 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio
} }
headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf)) headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf))
if options.Platform != "" {
if err := cli.NewVersionError("1.32", "platform"); err != nil {
return types.ImageBuildResponse{}, err
}
query.Set("platform", options.Platform)
}
headers.Set("Content-Type", "application/x-tar") headers.Set("Content-Type", "application/x-tar")
serverResp, err := cli.postRaw(ctx, "/build", query, buildContext, headers) serverResp, err := cli.postRaw(ctx, "/build", query, buildContext, headers)
@ -132,7 +125,14 @@ func (cli *Client) imageBuildOptionsToQuery(options types.ImageBuildOptions) (ur
query.Set("session", options.SessionID) query.Set("session", options.SessionID)
} }
if options.Platform != "" { if options.Platform != "" {
if err := cli.NewVersionError("1.32", "platform"); err != nil {
return query, err
}
query.Set("platform", strings.ToLower(options.Platform)) query.Set("platform", strings.ToLower(options.Platform))
} }
if options.BuildID != "" {
query.Set("buildid", options.BuildID)
}
query.Set("version", string(options.Version))
return query, nil return query, nil
} }

View File

@ -1,12 +1,11 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"io" "io"
"net/url" "net/url"
"strings" "strings"
"golang.org/x/net/context"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
) )

View File

@ -1,11 +1,11 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"golang.org/x/net/context"
) )
// ImageHistory returns the changes in an image in history format. // ImageHistory returns the changes in an image in history format.

View File

@ -1,12 +1,11 @@
package client package client // import "github.com/docker/docker/client"
import ( import (
"context"
"io" "io"
"net/url" "net/url"
"strings" "strings"
"golang.org/x/net/context"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
) )

Some files were not shown because too many files have changed in this diff Show More