mirror of https://github.com/docker/cli.git
vendor: github.com/docker/docker dab9ffb252186f4c47416addb136d579f9314c6a (25.0-dev)
full diff: 98d3da79ef...dab9ffb252
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
4d03b935c1
commit
1f87420b5b
|
@ -12,7 +12,7 @@ require (
|
||||||
github.com/containerd/containerd v1.6.21
|
github.com/containerd/containerd v1.6.21
|
||||||
github.com/creack/pty v1.1.18
|
github.com/creack/pty v1.1.18
|
||||||
github.com/docker/distribution v2.8.2+incompatible
|
github.com/docker/distribution v2.8.2+incompatible
|
||||||
github.com/docker/docker v24.0.0-rc.2.0.20230706181717-98d3da79ef9c+incompatible // master (v25.0.0-dev)
|
github.com/docker/docker v24.0.0-rc.2.0.20230714195812-dab9ffb25218+incompatible // master (v25.0.0-dev)
|
||||||
github.com/docker/docker-credential-helpers v0.7.0
|
github.com/docker/docker-credential-helpers v0.7.0
|
||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/docker/go-units v0.5.0
|
github.com/docker/go-units v0.5.0
|
||||||
|
|
|
@ -100,8 +100,8 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xb
|
||||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v24.0.0-rc.2.0.20230706181717-98d3da79ef9c+incompatible h1:XccikgvtGCEZE9ZQoaEApdx9ZvruGYakfi2tw4d/vUg=
|
github.com/docker/docker v24.0.0-rc.2.0.20230714195812-dab9ffb25218+incompatible h1:lQ7FvH3oFGtG/ODOr0oAlRHQxJJkkbG+RyNHmiMWdI8=
|
||||||
github.com/docker/docker v24.0.0-rc.2.0.20230706181717-98d3da79ef9c+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v24.0.0-rc.2.0.20230714195812-dab9ffb25218+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
|
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
|
||||||
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
|
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
|
||||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
||||||
|
|
|
@ -9900,7 +9900,9 @@ paths:
|
||||||
Id: "22be93d5babb089c5aab8dbc369042fad48ff791584ca2da2100db837a1c7c30"
|
Id: "22be93d5babb089c5aab8dbc369042fad48ff791584ca2da2100db837a1c7c30"
|
||||||
Warning: ""
|
Warning: ""
|
||||||
403:
|
403:
|
||||||
description: "operation not supported for pre-defined networks"
|
description: |
|
||||||
|
Forbidden operation. This happens when trying to create a network named after a pre-defined network,
|
||||||
|
or when trying to create an overlay network on a daemon which is not part of a Swarm cluster.
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/definitions/ErrorResponse"
|
$ref: "#/definitions/ErrorResponse"
|
||||||
404:
|
404:
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/docker/docker/api/types/container"
|
||||||
|
"github.com/docker/docker/api/types/registry"
|
||||||
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Info contains response of Engine API:
|
||||||
|
// GET "/info"
|
||||||
|
type Info struct {
|
||||||
|
ID string
|
||||||
|
Containers int
|
||||||
|
ContainersRunning int
|
||||||
|
ContainersPaused int
|
||||||
|
ContainersStopped int
|
||||||
|
Images int
|
||||||
|
Driver string
|
||||||
|
DriverStatus [][2]string
|
||||||
|
SystemStatus [][2]string `json:",omitempty"` // SystemStatus is only propagated by the Swarm standalone API
|
||||||
|
Plugins PluginsInfo
|
||||||
|
MemoryLimit bool
|
||||||
|
SwapLimit bool
|
||||||
|
KernelMemory bool `json:",omitempty"` // Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes
|
||||||
|
KernelMemoryTCP bool `json:",omitempty"` // KernelMemoryTCP is not supported on cgroups v2.
|
||||||
|
CPUCfsPeriod bool `json:"CpuCfsPeriod"`
|
||||||
|
CPUCfsQuota bool `json:"CpuCfsQuota"`
|
||||||
|
CPUShares bool
|
||||||
|
CPUSet bool
|
||||||
|
PidsLimit bool
|
||||||
|
IPv4Forwarding bool
|
||||||
|
BridgeNfIptables bool
|
||||||
|
BridgeNfIP6tables bool `json:"BridgeNfIp6tables"`
|
||||||
|
Debug bool
|
||||||
|
NFd int
|
||||||
|
OomKillDisable bool
|
||||||
|
NGoroutines int
|
||||||
|
SystemTime string
|
||||||
|
LoggingDriver string
|
||||||
|
CgroupDriver string
|
||||||
|
CgroupVersion string `json:",omitempty"`
|
||||||
|
NEventsListener int
|
||||||
|
KernelVersion string
|
||||||
|
OperatingSystem string
|
||||||
|
OSVersion string
|
||||||
|
OSType string
|
||||||
|
Architecture string
|
||||||
|
IndexServerAddress string
|
||||||
|
RegistryConfig *registry.ServiceConfig
|
||||||
|
NCPU int
|
||||||
|
MemTotal int64
|
||||||
|
GenericResources []swarm.GenericResource
|
||||||
|
DockerRootDir string
|
||||||
|
HTTPProxy string `json:"HttpProxy"`
|
||||||
|
HTTPSProxy string `json:"HttpsProxy"`
|
||||||
|
NoProxy string
|
||||||
|
Name string
|
||||||
|
Labels []string
|
||||||
|
ExperimentalBuild bool
|
||||||
|
ServerVersion string
|
||||||
|
Runtimes map[string]Runtime
|
||||||
|
DefaultRuntime string
|
||||||
|
Swarm swarm.Info
|
||||||
|
// LiveRestoreEnabled determines whether containers should be kept
|
||||||
|
// running when the daemon is shutdown or upon daemon start if
|
||||||
|
// running containers are detected
|
||||||
|
LiveRestoreEnabled bool
|
||||||
|
Isolation container.Isolation
|
||||||
|
InitBinary string
|
||||||
|
ContainerdCommit Commit
|
||||||
|
RuncCommit Commit
|
||||||
|
InitCommit Commit
|
||||||
|
SecurityOptions []string
|
||||||
|
ProductLicense string `json:",omitempty"`
|
||||||
|
DefaultAddressPools []NetworkAddressPool `json:",omitempty"`
|
||||||
|
|
||||||
|
// Legacy API fields for older API versions.
|
||||||
|
legacyFields
|
||||||
|
|
||||||
|
// Warnings contains a slice of warnings that occurred while collecting
|
||||||
|
// system information. These warnings are intended to be informational
|
||||||
|
// messages for the user, and are not intended to be parsed / used for
|
||||||
|
// other purposes, as they do not have a fixed format.
|
||||||
|
Warnings []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type legacyFields struct {
|
||||||
|
ExecutionDriver string `json:",omitempty"` // Deprecated: deprecated since API v1.25, but returned for older versions.
|
||||||
|
}
|
||||||
|
|
||||||
|
// PluginsInfo is a temp struct holding Plugins name
|
||||||
|
// registered with docker daemon. It is used by [Info] struct
|
||||||
|
type PluginsInfo struct {
|
||||||
|
// List of Volume plugins registered
|
||||||
|
Volume []string
|
||||||
|
// List of Network plugins registered
|
||||||
|
Network []string
|
||||||
|
// List of Authorization plugins registered
|
||||||
|
Authorization []string
|
||||||
|
// List of Log plugins registered
|
||||||
|
Log []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit holds the Git-commit (SHA1) that a binary was built from, as reported
|
||||||
|
// in the version-string of external tools, such as containerd, or runC.
|
||||||
|
type Commit struct {
|
||||||
|
ID string // ID is the actual commit ID of external tool.
|
||||||
|
Expected string // Expected is the commit ID of external tool expected by dockerd as set at build time.
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkAddressPool is a temp struct used by [Info] struct.
|
||||||
|
type NetworkAddressPool struct {
|
||||||
|
Base string
|
||||||
|
Size int
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package system
|
||||||
|
|
||||||
|
// Runtime describes an OCI runtime
|
||||||
|
type Runtime struct {
|
||||||
|
// "Legacy" runtime configuration for runc-compatible runtimes.
|
||||||
|
|
||||||
|
Path string `json:"path,omitempty"`
|
||||||
|
Args []string `json:"runtimeArgs,omitempty"`
|
||||||
|
|
||||||
|
// Shimv2 runtime configuration. Mutually exclusive with the legacy config above.
|
||||||
|
|
||||||
|
Type string `json:"runtimeType,omitempty"`
|
||||||
|
Options map[string]interface{} `json:"options,omitempty"`
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SecurityOpt contains the name and options of a security option
|
||||||
|
type SecurityOpt struct {
|
||||||
|
Name string
|
||||||
|
Options []KeyValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeSecurityOptions decodes a security options string slice to a
|
||||||
|
// type-safe [SecurityOpt].
|
||||||
|
func DecodeSecurityOptions(opts []string) ([]SecurityOpt, error) {
|
||||||
|
so := []SecurityOpt{}
|
||||||
|
for _, opt := range opts {
|
||||||
|
// support output from a < 1.13 docker daemon
|
||||||
|
if !strings.Contains(opt, "=") {
|
||||||
|
so = append(so, SecurityOpt{Name: opt})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
secopt := SecurityOpt{}
|
||||||
|
for _, s := range strings.Split(opt, ",") {
|
||||||
|
k, v, ok := strings.Cut(s, "=")
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("invalid security option %q", s)
|
||||||
|
}
|
||||||
|
if k == "" || v == "" {
|
||||||
|
return nil, errors.New("invalid empty security option")
|
||||||
|
}
|
||||||
|
if k == "name" {
|
||||||
|
secopt.Name = v
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
secopt.Options = append(secopt.Options, KeyValue{Key: k, Value: v})
|
||||||
|
}
|
||||||
|
so = append(so, secopt)
|
||||||
|
}
|
||||||
|
return so, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyValue holds a key/value pair.
|
||||||
|
type KeyValue struct {
|
||||||
|
Key, Value string
|
||||||
|
}
|
|
@ -1,18 +1,14 @@
|
||||||
package types // import "github.com/docker/docker/api/types"
|
package types // import "github.com/docker/docker/api/types"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/mount"
|
"github.com/docker/docker/api/types/mount"
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
"github.com/docker/docker/api/types/registry"
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/docker/api/types/volume"
|
"github.com/docker/docker/api/types/volume"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
|
@ -232,155 +228,6 @@ type Version struct {
|
||||||
BuildTime string `json:",omitempty"`
|
BuildTime string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit holds the Git-commit (SHA1) that a binary was built from, as reported
|
|
||||||
// in the version-string of external tools, such as containerd, or runC.
|
|
||||||
type Commit struct {
|
|
||||||
ID string // ID is the actual commit ID of external tool.
|
|
||||||
Expected string // Expected is the commit ID of external tool expected by dockerd as set at build time.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Info contains response of Engine API:
|
|
||||||
// GET "/info"
|
|
||||||
type Info struct {
|
|
||||||
ID string
|
|
||||||
Containers int
|
|
||||||
ContainersRunning int
|
|
||||||
ContainersPaused int
|
|
||||||
ContainersStopped int
|
|
||||||
Images int
|
|
||||||
Driver string
|
|
||||||
DriverStatus [][2]string
|
|
||||||
SystemStatus [][2]string `json:",omitempty"` // SystemStatus is only propagated by the Swarm standalone API
|
|
||||||
Plugins PluginsInfo
|
|
||||||
MemoryLimit bool
|
|
||||||
SwapLimit bool
|
|
||||||
KernelMemory bool `json:",omitempty"` // Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes
|
|
||||||
KernelMemoryTCP bool `json:",omitempty"` // KernelMemoryTCP is not supported on cgroups v2.
|
|
||||||
CPUCfsPeriod bool `json:"CpuCfsPeriod"`
|
|
||||||
CPUCfsQuota bool `json:"CpuCfsQuota"`
|
|
||||||
CPUShares bool
|
|
||||||
CPUSet bool
|
|
||||||
PidsLimit bool
|
|
||||||
IPv4Forwarding bool
|
|
||||||
BridgeNfIptables bool
|
|
||||||
BridgeNfIP6tables bool `json:"BridgeNfIp6tables"`
|
|
||||||
Debug bool
|
|
||||||
NFd int
|
|
||||||
OomKillDisable bool
|
|
||||||
NGoroutines int
|
|
||||||
SystemTime string
|
|
||||||
LoggingDriver string
|
|
||||||
CgroupDriver string
|
|
||||||
CgroupVersion string `json:",omitempty"`
|
|
||||||
NEventsListener int
|
|
||||||
KernelVersion string
|
|
||||||
OperatingSystem string
|
|
||||||
OSVersion string
|
|
||||||
OSType string
|
|
||||||
Architecture string
|
|
||||||
IndexServerAddress string
|
|
||||||
RegistryConfig *registry.ServiceConfig
|
|
||||||
NCPU int
|
|
||||||
MemTotal int64
|
|
||||||
GenericResources []swarm.GenericResource
|
|
||||||
DockerRootDir string
|
|
||||||
HTTPProxy string `json:"HttpProxy"`
|
|
||||||
HTTPSProxy string `json:"HttpsProxy"`
|
|
||||||
NoProxy string
|
|
||||||
Name string
|
|
||||||
Labels []string
|
|
||||||
ExperimentalBuild bool
|
|
||||||
ServerVersion string
|
|
||||||
Runtimes map[string]Runtime
|
|
||||||
DefaultRuntime string
|
|
||||||
Swarm swarm.Info
|
|
||||||
// LiveRestoreEnabled determines whether containers should be kept
|
|
||||||
// running when the daemon is shutdown or upon daemon start if
|
|
||||||
// running containers are detected
|
|
||||||
LiveRestoreEnabled bool
|
|
||||||
Isolation container.Isolation
|
|
||||||
InitBinary string
|
|
||||||
ContainerdCommit Commit
|
|
||||||
RuncCommit Commit
|
|
||||||
InitCommit Commit
|
|
||||||
SecurityOptions []string
|
|
||||||
ProductLicense string `json:",omitempty"`
|
|
||||||
DefaultAddressPools []NetworkAddressPool `json:",omitempty"`
|
|
||||||
|
|
||||||
// Legacy API fields for older API versions.
|
|
||||||
legacyFields
|
|
||||||
|
|
||||||
// Warnings contains a slice of warnings that occurred while collecting
|
|
||||||
// system information. These warnings are intended to be informational
|
|
||||||
// messages for the user, and are not intended to be parsed / used for
|
|
||||||
// other purposes, as they do not have a fixed format.
|
|
||||||
Warnings []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type legacyFields struct {
|
|
||||||
ExecutionDriver string `json:",omitempty"` // Deprecated: deprecated since API v1.25, but returned for older versions.
|
|
||||||
}
|
|
||||||
|
|
||||||
// KeyValue holds a key/value pair
|
|
||||||
type KeyValue struct {
|
|
||||||
Key, Value string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NetworkAddressPool is a temp struct used by Info struct
|
|
||||||
type NetworkAddressPool struct {
|
|
||||||
Base string
|
|
||||||
Size int
|
|
||||||
}
|
|
||||||
|
|
||||||
// SecurityOpt contains the name and options of a security option
|
|
||||||
type SecurityOpt struct {
|
|
||||||
Name string
|
|
||||||
Options []KeyValue
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeSecurityOptions decodes a security options string slice to a type safe
|
|
||||||
// SecurityOpt
|
|
||||||
func DecodeSecurityOptions(opts []string) ([]SecurityOpt, error) {
|
|
||||||
so := []SecurityOpt{}
|
|
||||||
for _, opt := range opts {
|
|
||||||
// support output from a < 1.13 docker daemon
|
|
||||||
if !strings.Contains(opt, "=") {
|
|
||||||
so = append(so, SecurityOpt{Name: opt})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
secopt := SecurityOpt{}
|
|
||||||
for _, s := range strings.Split(opt, ",") {
|
|
||||||
k, v, ok := strings.Cut(s, "=")
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid security option %q", s)
|
|
||||||
}
|
|
||||||
if k == "" || v == "" {
|
|
||||||
return nil, errors.New("invalid empty security option")
|
|
||||||
}
|
|
||||||
if k == "name" {
|
|
||||||
secopt.Name = v
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
secopt.Options = append(secopt.Options, KeyValue{Key: k, Value: v})
|
|
||||||
}
|
|
||||||
so = append(so, secopt)
|
|
||||||
}
|
|
||||||
return so, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PluginsInfo is a temp struct holding Plugins name
|
|
||||||
// registered with docker daemon. It is used by Info struct
|
|
||||||
type PluginsInfo struct {
|
|
||||||
// List of Volume plugins registered
|
|
||||||
Volume []string
|
|
||||||
// List of Network plugins registered
|
|
||||||
Network []string
|
|
||||||
// List of Authorization plugins registered
|
|
||||||
Authorization []string
|
|
||||||
// List of Log plugins registered
|
|
||||||
Log []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExecStartCheck is a temp struct used by execStart
|
// ExecStartCheck is a temp struct used by execStart
|
||||||
// Config fields is part of ExecConfig in runconfig package
|
// Config fields is part of ExecConfig in runconfig package
|
||||||
type ExecStartCheck struct {
|
type ExecStartCheck struct {
|
||||||
|
@ -652,19 +499,6 @@ type Checkpoint struct {
|
||||||
Name string // Name is the name of the checkpoint
|
Name string // Name is the name of the checkpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runtime describes an OCI runtime
|
|
||||||
type Runtime struct {
|
|
||||||
// "Legacy" runtime configuration for runc-compatible runtimes.
|
|
||||||
|
|
||||||
Path string `json:"path,omitempty"`
|
|
||||||
Args []string `json:"runtimeArgs,omitempty"`
|
|
||||||
|
|
||||||
// Shimv2 runtime configuration. Mutually exclusive with the legacy config above.
|
|
||||||
|
|
||||||
Type string `json:"runtimeType,omitempty"`
|
|
||||||
Options map[string]interface{} `json:"options,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DiskUsageObject represents an object type used for disk usage query filtering.
|
// DiskUsageObject represents an object type used for disk usage query filtering.
|
||||||
type DiskUsageObject string
|
type DiskUsageObject string
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package types
|
||||||
|
|
||||||
|
import "github.com/docker/docker/api/types/system"
|
||||||
|
|
||||||
|
// Info contains response of Engine API:
|
||||||
|
// GET "/info"
|
||||||
|
//
|
||||||
|
// Deprecated: use [system.Info].
|
||||||
|
type Info = system.Info
|
||||||
|
|
||||||
|
// Commit holds the Git-commit (SHA1) that a binary was built from, as reported
|
||||||
|
// in the version-string of external tools, such as containerd, or runC.
|
||||||
|
//
|
||||||
|
// Deprecated: use [system.Commit].
|
||||||
|
type Commit = system.Commit
|
||||||
|
|
||||||
|
// PluginsInfo is a temp struct holding Plugins name
|
||||||
|
// registered with docker daemon. It is used by [system.Info] struct
|
||||||
|
//
|
||||||
|
// Deprecated: use [system.PluginsInfo].
|
||||||
|
type PluginsInfo = system.PluginsInfo
|
||||||
|
|
||||||
|
// NetworkAddressPool is a temp struct used by [system.Info] struct.
|
||||||
|
//
|
||||||
|
// Deprecated: use [system.NetworkAddressPool].
|
||||||
|
type NetworkAddressPool = system.NetworkAddressPool
|
||||||
|
|
||||||
|
// Runtime describes an OCI runtime.
|
||||||
|
//
|
||||||
|
// Deprecated: use [system.Runtime].
|
||||||
|
type Runtime = system.Runtime
|
||||||
|
|
||||||
|
// SecurityOpt contains the name and options of a security option.
|
||||||
|
//
|
||||||
|
// Deprecated: use [system.SecurityOpt].
|
||||||
|
type SecurityOpt = system.SecurityOpt
|
||||||
|
|
||||||
|
// KeyValue holds a key/value pair.
|
||||||
|
//
|
||||||
|
// Deprecated: use [system.KeyValue].
|
||||||
|
type KeyValue = system.KeyValue
|
||||||
|
|
||||||
|
// DecodeSecurityOptions decodes a security options string slice to a type safe
|
||||||
|
// [system.SecurityOpt].
|
||||||
|
//
|
||||||
|
// Deprecated: use [system.DecodeSecurityOptions].
|
||||||
|
func DecodeSecurityOptions(opts []string) ([]system.SecurityOpt, error) {
|
||||||
|
return system.DecodeSecurityOptions(opts)
|
||||||
|
}
|
|
@ -56,6 +56,36 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DummyHost is a hostname used for local communication.
|
||||||
|
//
|
||||||
|
// It acts as a valid formatted hostname for local connections (such as "unix://"
|
||||||
|
// or "npipe://") which do not require a hostname. It should never be resolved,
|
||||||
|
// but uses the special-purpose ".localhost" TLD (as defined in [RFC 2606, Section 2]
|
||||||
|
// and [RFC 6761, Section 6.3]).
|
||||||
|
//
|
||||||
|
// [RFC 7230, Section 5.4] defines that an empty header must be used for such
|
||||||
|
// cases:
|
||||||
|
//
|
||||||
|
// If the authority component is missing or undefined for the target URI,
|
||||||
|
// then a client MUST send a Host header field with an empty field-value.
|
||||||
|
//
|
||||||
|
// However, [Go stdlib] enforces the semantics of HTTP(S) over TCP, does not
|
||||||
|
// allow an empty header to be used, and requires req.URL.Scheme to be either
|
||||||
|
// "http" or "https".
|
||||||
|
//
|
||||||
|
// For further details, refer to:
|
||||||
|
//
|
||||||
|
// - https://github.com/docker/engine-api/issues/189
|
||||||
|
// - https://github.com/golang/go/issues/13624
|
||||||
|
// - https://github.com/golang/go/issues/61076
|
||||||
|
// - https://github.com/moby/moby/issues/45935
|
||||||
|
//
|
||||||
|
// [RFC 2606, Section 2]: https://www.rfc-editor.org/rfc/rfc2606.html#section-2
|
||||||
|
// [RFC 6761, Section 6.3]: https://www.rfc-editor.org/rfc/rfc6761#section-6.3
|
||||||
|
// [RFC 7230, Section 5.4]: https://datatracker.ietf.org/doc/html/rfc7230#section-5.4
|
||||||
|
// [Go stdlib]: https://github.com/golang/go/blob/6244b1946bc2101b01955468f1be502dbadd6807/src/net/http/transport.go#L558-L569
|
||||||
|
const DummyHost = "api.moby.localhost"
|
||||||
|
|
||||||
// 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.
|
||||||
var ErrRedirect = errors.New("unexpected redirect in response")
|
var ErrRedirect = errors.New("unexpected redirect in response")
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package client // import "github.com/docker/docker/client"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
@ -52,8 +53,7 @@ func (cli *Client) ContainerAttach(ctx context.Context, container string, option
|
||||||
query.Set("logs", "1")
|
query.Set("logs", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
headers := map[string][]string{
|
return cli.postHijacked(ctx, "/containers/"+container+"/attach", query, nil, http.Header{
|
||||||
"Content-Type": {"text/plain"},
|
"Content-Type": {"text/plain"},
|
||||||
}
|
})
|
||||||
return cli.postHijacked(ctx, "/containers/"+container+"/attach", query, nil, headers)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"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"
|
||||||
|
@ -46,10 +47,9 @@ func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, confi
|
||||||
if versions.LessThan(cli.ClientVersion(), "1.42") {
|
if versions.LessThan(cli.ClientVersion(), "1.42") {
|
||||||
config.ConsoleSize = nil
|
config.ConsoleSize = nil
|
||||||
}
|
}
|
||||||
headers := map[string][]string{
|
return cli.postHijacked(ctx, "/exec/"+execID+"/start", nil, config, http.Header{
|
||||||
"Content-Type": {"application/json"},
|
"Content-Type": {"application/json"},
|
||||||
}
|
})
|
||||||
return cli.postHijacked(ctx, "/exec/"+execID+"/start", nil, config, headers)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerExecInspect returns information about a specific exec process on the docker host.
|
// ContainerExecInspect returns information about a specific exec process on the docker host.
|
||||||
|
|
|
@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/registry"
|
"github.com/docker/docker/api/types/registry"
|
||||||
|
@ -19,10 +20,10 @@ func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegist
|
||||||
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
|
||||||
}
|
}
|
||||||
var headers map[string][]string
|
|
||||||
|
|
||||||
|
var headers http.Header
|
||||||
if encodedRegistryAuth != "" {
|
if encodedRegistryAuth != "" {
|
||||||
headers = map[string][]string{
|
headers = http.Header{
|
||||||
registry.AuthHeader: {encodedRegistryAuth},
|
registry.AuthHeader: {encodedRegistryAuth},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,11 @@ func fallbackDial(proto, addr string, tlsConfig *tls.Config) (net.Conn, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto string) (net.Conn, string, error) {
|
func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto string) (net.Conn, string, error) {
|
||||||
req.Host = cli.addr
|
req.URL.Host = cli.addr
|
||||||
|
if cli.proto == "unix" || cli.proto == "npipe" {
|
||||||
|
// Override host header for non-tcp connections.
|
||||||
|
req.Host = DummyHost
|
||||||
|
}
|
||||||
req.Header.Set("Connection", "Upgrade")
|
req.Header.Set("Connection", "Upgrade")
|
||||||
req.Header.Set("Upgrade", proto)
|
req.Header.Set("Upgrade", proto)
|
||||||
|
|
||||||
|
|
|
@ -23,13 +23,13 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio
|
||||||
return types.ImageBuildResponse{}, err
|
return types.ImageBuildResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
headers := http.Header(make(map[string][]string))
|
|
||||||
buf, err := json.Marshal(options.AuthConfigs)
|
buf, err := json.Marshal(options.AuthConfigs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.ImageBuildResponse{}, err
|
return types.ImageBuildResponse{}, err
|
||||||
}
|
}
|
||||||
headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf))
|
|
||||||
|
|
||||||
|
headers := http.Header{}
|
||||||
|
headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf))
|
||||||
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)
|
||||||
|
@ -37,11 +37,9 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio
|
||||||
return types.ImageBuildResponse{}, err
|
return types.ImageBuildResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
osType := getDockerOS(serverResp.header.Get("Server"))
|
|
||||||
|
|
||||||
return types.ImageBuildResponse{
|
return types.ImageBuildResponse{
|
||||||
Body: serverResp.body,
|
Body: serverResp.body,
|
||||||
OSType: osType,
|
OSType: getDockerOS(serverResp.header.Get("Server")),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -33,6 +34,7 @@ func (cli *Client) ImageCreate(ctx context.Context, parentReference string, opti
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
|
func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
|
||||||
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
|
return cli.post(ctx, "/images/create", query, nil, http.Header{
|
||||||
return cli.post(ctx, "/images/create", query, nil, headers)
|
registry.AuthHeader: {registryAuth},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
@ -17,8 +18,9 @@ func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (
|
||||||
if quiet {
|
if quiet {
|
||||||
v.Set("quiet", "1")
|
v.Set("quiet", "1")
|
||||||
}
|
}
|
||||||
headers := map[string][]string{"Content-Type": {"application/x-tar"}}
|
resp, err := cli.postRaw(ctx, "/images/load", v, input, http.Header{
|
||||||
resp, err := cli.postRaw(ctx, "/images/load", v, input, headers)
|
"Content-Type": {"application/x-tar"},
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.ImageLoadResponse{}, err
|
return types.ImageLoadResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
|
@ -50,6 +51,7 @@ func (cli *Client) ImagePush(ctx context.Context, image string, options types.Im
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.Values, registryAuth string) (serverResponse, error) {
|
func (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.Values, registryAuth string) (serverResponse, error) {
|
||||||
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
|
return cli.post(ctx, "/images/"+imageID+"/push", query, nil, http.Header{
|
||||||
return cli.post(ctx, "/images/"+imageID+"/push", query, nil, headers)
|
registry.AuthHeader: {registryAuth},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
@ -48,6 +49,7 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options types.I
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
|
func (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
|
||||||
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
|
return cli.get(ctx, "/images/search", query, http.Header{
|
||||||
return cli.get(ctx, "/images/search", query, headers)
|
registry.AuthHeader: {registryAuth},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,12 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Info returns information about the docker server.
|
// Info returns information about the docker server.
|
||||||
func (cli *Client) Info(ctx context.Context) (types.Info, error) {
|
func (cli *Client) Info(ctx context.Context) (system.Info, error) {
|
||||||
var info types.Info
|
var info system.Info
|
||||||
serverResp, err := cli.get(ctx, "/info", url.Values{}, nil)
|
serverResp, err := cli.get(ctx, "/info", url.Values{}, nil)
|
||||||
defer ensureReaderClosed(serverResp)
|
defer ensureReaderClosed(serverResp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
"github.com/docker/docker/api/types/registry"
|
"github.com/docker/docker/api/types/registry"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/api/types/system"
|
||||||
"github.com/docker/docker/api/types/volume"
|
"github.com/docker/docker/api/types/volume"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
@ -165,7 +166,7 @@ type SwarmAPIClient interface {
|
||||||
// SystemAPIClient defines API client methods for the system
|
// SystemAPIClient defines API client methods for the system
|
||||||
type SystemAPIClient interface {
|
type SystemAPIClient interface {
|
||||||
Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error)
|
Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error)
|
||||||
Info(ctx context.Context) (types.Info, error)
|
Info(ctx context.Context) (system.Info, error)
|
||||||
RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error)
|
RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error)
|
||||||
DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error)
|
DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error)
|
||||||
Ping(ctx context.Context) (types.Ping, error)
|
Ping(ctx context.Context) (types.Ping, error)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
|
@ -68,13 +69,15 @@ func (cli *Client) PluginInstall(ctx context.Context, name string, options types
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) tryPluginPrivileges(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
|
func (cli *Client) tryPluginPrivileges(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
|
||||||
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
|
return cli.get(ctx, "/plugins/privileges", query, http.Header{
|
||||||
return cli.get(ctx, "/plugins/privileges", query, headers)
|
registry.AuthHeader: {registryAuth},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, privileges types.PluginPrivileges, registryAuth string) (serverResponse, error) {
|
func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, privileges types.PluginPrivileges, registryAuth string) (serverResponse, error) {
|
||||||
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
|
return cli.post(ctx, "/plugins/pull", query, privileges, http.Header{
|
||||||
return cli.post(ctx, "/plugins/pull", query, privileges, headers)
|
registry.AuthHeader: {registryAuth},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, options types.PluginInstallOptions) (types.PluginPrivileges, error) {
|
func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, options types.PluginInstallOptions) (types.PluginPrivileges, error) {
|
||||||
|
|
|
@ -3,14 +3,16 @@ package client // import "github.com/docker/docker/client"
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/registry"
|
"github.com/docker/docker/api/types/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PluginPush pushes a plugin to a registry
|
// PluginPush pushes a plugin to a registry
|
||||||
func (cli *Client) PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error) {
|
func (cli *Client) PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error) {
|
||||||
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
|
resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, http.Header{
|
||||||
resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, headers)
|
registry.AuthHeader: {registryAuth},
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client"
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
|
@ -35,6 +36,7 @@ func (cli *Client) PluginUpgrade(ctx context.Context, name string, options types
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) tryPluginUpgrade(ctx context.Context, query url.Values, privileges types.PluginPrivileges, name, registryAuth string) (serverResponse, error) {
|
func (cli *Client) tryPluginUpgrade(ctx context.Context, query url.Values, privileges types.PluginPrivileges, name, registryAuth string) (serverResponse, error) {
|
||||||
headers := map[string][]string{registry.AuthHeader: {registryAuth}}
|
return cli.post(ctx, "/plugins/"+name+"/upgrade", query, privileges, http.Header{
|
||||||
return cli.post(ctx, "/plugins/"+name+"/upgrade", query, privileges, headers)
|
registry.AuthHeader: {registryAuth},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,17 +28,17 @@ type serverResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// head sends an http request to the docker API using the method HEAD.
|
// head sends an http request to the docker API using the method HEAD.
|
||||||
func (cli *Client) head(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) {
|
func (cli *Client) head(ctx context.Context, path string, query url.Values, headers http.Header) (serverResponse, error) {
|
||||||
return cli.sendRequest(ctx, http.MethodHead, path, query, nil, headers)
|
return cli.sendRequest(ctx, http.MethodHead, path, query, nil, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get sends an http request to the docker API using the method GET with a specific Go context.
|
// get sends an http request to the docker API using the method GET with a specific Go context.
|
||||||
func (cli *Client) get(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) {
|
func (cli *Client) get(ctx context.Context, path string, query url.Values, headers http.Header) (serverResponse, error) {
|
||||||
return cli.sendRequest(ctx, http.MethodGet, path, query, nil, headers)
|
return cli.sendRequest(ctx, http.MethodGet, path, query, nil, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// post sends an http request to the docker API using the method POST with a specific Go context.
|
// post sends an http request to the docker API using the method POST with a specific Go context.
|
||||||
func (cli *Client) post(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) {
|
func (cli *Client) post(ctx context.Context, path string, query url.Values, obj interface{}, headers http.Header) (serverResponse, error) {
|
||||||
body, headers, err := encodeBody(obj, headers)
|
body, headers, err := encodeBody(obj, headers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return serverResponse{}, err
|
return serverResponse{}, err
|
||||||
|
@ -46,11 +46,11 @@ func (cli *Client) post(ctx context.Context, path string, query url.Values, obj
|
||||||
return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers)
|
return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) {
|
func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers http.Header) (serverResponse, error) {
|
||||||
return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers)
|
return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) {
|
func (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers http.Header) (serverResponse, error) {
|
||||||
body, headers, err := encodeBody(obj, headers)
|
body, headers, err := encodeBody(obj, headers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return serverResponse{}, err
|
return serverResponse{}, err
|
||||||
|
@ -59,7 +59,7 @@ func (cli *Client) put(ctx context.Context, path string, query url.Values, obj i
|
||||||
}
|
}
|
||||||
|
|
||||||
// putRaw sends an http request to the docker API using the method PUT.
|
// putRaw sends an http request to the docker API using the method PUT.
|
||||||
func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) {
|
func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers http.Header) (serverResponse, error) {
|
||||||
// PUT requests are expected to always have a body (apparently)
|
// PUT requests are expected to always have a body (apparently)
|
||||||
// so explicitly pass an empty body to sendRequest to signal that
|
// so explicitly pass an empty body to sendRequest to signal that
|
||||||
// it should set the Content-Type header if not already present.
|
// it should set the Content-Type header if not already present.
|
||||||
|
@ -70,13 +70,11 @@ func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, bo
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete sends an http request to the docker API using the method DELETE.
|
// delete sends an http request to the docker API using the method DELETE.
|
||||||
func (cli *Client) delete(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) {
|
func (cli *Client) delete(ctx context.Context, path string, query url.Values, headers http.Header) (serverResponse, error) {
|
||||||
return cli.sendRequest(ctx, http.MethodDelete, path, query, nil, headers)
|
return cli.sendRequest(ctx, http.MethodDelete, path, query, nil, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
type headers map[string][]string
|
func encodeBody(obj interface{}, headers http.Header) (io.Reader, http.Header, error) {
|
||||||
|
|
||||||
func encodeBody(obj interface{}, headers headers) (io.Reader, headers, error) {
|
|
||||||
if obj == nil {
|
if obj == nil {
|
||||||
return nil, headers, nil
|
return nil, headers, nil
|
||||||
}
|
}
|
||||||
|
@ -98,32 +96,27 @@ func encodeBody(obj interface{}, headers headers) (io.Reader, headers, error) {
|
||||||
return body, headers, nil
|
return body, headers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) buildRequest(method, path string, body io.Reader, headers headers) (*http.Request, error) {
|
func (cli *Client) buildRequest(method, path string, body io.Reader, headers http.Header) (*http.Request, error) {
|
||||||
req, err := http.NewRequest(method, path, body)
|
req, err := http.NewRequest(method, path, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
req = cli.addHeaders(req, headers)
|
req = cli.addHeaders(req, headers)
|
||||||
|
req.URL.Scheme = cli.scheme
|
||||||
|
req.URL.Host = cli.addr
|
||||||
|
|
||||||
if cli.proto == "unix" || cli.proto == "npipe" {
|
if cli.proto == "unix" || cli.proto == "npipe" {
|
||||||
// For local communications, it doesn't matter what the host is. We just
|
// Override host header for non-tcp connections.
|
||||||
// need a valid and meaningful host name. For details, see:
|
req.Host = DummyHost
|
||||||
//
|
|
||||||
// - https://github.com/docker/engine-api/issues/189
|
|
||||||
// - https://github.com/golang/go/issues/13624
|
|
||||||
req.Host = "docker"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
req.URL.Host = cli.addr
|
|
||||||
req.URL.Scheme = cli.scheme
|
|
||||||
|
|
||||||
if body != nil && req.Header.Get("Content-Type") == "" {
|
if body != nil && req.Header.Get("Content-Type") == "" {
|
||||||
req.Header.Set("Content-Type", "text/plain")
|
req.Header.Set("Content-Type", "text/plain")
|
||||||
}
|
}
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers headers) (serverResponse, error) {
|
func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers http.Header) (serverResponse, error) {
|
||||||
req, err := cli.buildRequest(method, cli.getAPIPath(ctx, path, query), body, headers)
|
req, err := cli.buildRequest(method, cli.getAPIPath(ctx, path, query), body, headers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return serverResponse{}, err
|
return serverResponse{}, err
|
||||||
|
@ -161,19 +154,19 @@ func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResp
|
||||||
return serverResp, err
|
return serverResp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if nErr, ok := err.(*url.Error); ok {
|
if uErr, ok := err.(*url.Error); ok {
|
||||||
if nErr, ok := nErr.Err.(*net.OpError); ok {
|
if nErr, ok := uErr.Err.(*net.OpError); ok {
|
||||||
if os.IsPermission(nErr.Err) {
|
if os.IsPermission(nErr.Err) {
|
||||||
return serverResp, errors.Wrapf(err, "permission denied while trying to connect to the Docker daemon socket at %v", cli.host)
|
return serverResp, errors.Wrapf(err, "permission denied while trying to connect to the Docker daemon socket at %v", cli.host)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err, ok := err.(net.Error); ok {
|
if nErr, ok := err.(net.Error); ok {
|
||||||
if err.Timeout() {
|
if nErr.Timeout() {
|
||||||
return serverResp, ErrorConnectionFailed(cli.host)
|
return serverResp, ErrorConnectionFailed(cli.host)
|
||||||
}
|
}
|
||||||
if strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "dial unix") {
|
if strings.Contains(nErr.Error(), "connection refused") || strings.Contains(nErr.Error(), "dial unix") {
|
||||||
return serverResp, ErrorConnectionFailed(cli.host)
|
return serverResp, ErrorConnectionFailed(cli.host)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,7 +246,7 @@ func (cli *Client) checkResponseErr(serverResp serverResponse) error {
|
||||||
return errors.Wrap(errors.New(errorMessage), "Error response from daemon")
|
return errors.Wrap(errors.New(errorMessage), "Error response from daemon")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) addHeaders(req *http.Request, headers headers) *http.Request {
|
func (cli *Client) addHeaders(req *http.Request, headers http.Header) *http.Request {
|
||||||
// Add CLI Config's HTTP Headers BEFORE we set the Docker headers
|
// Add CLI Config's HTTP Headers BEFORE we set the Docker headers
|
||||||
// then the user can't change OUR headers
|
// then the user can't change OUR headers
|
||||||
for k, v := range cli.customHTTPHeaders {
|
for k, v := range cli.customHTTPHeaders {
|
||||||
|
|
|
@ -4,12 +4,14 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/registry"
|
"github.com/docker/docker/api/types/registry"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/api/types/versions"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -17,13 +19,6 @@ import (
|
||||||
// ServiceCreate creates a new service.
|
// ServiceCreate creates a new service.
|
||||||
func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (types.ServiceCreateResponse, error) {
|
func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (types.ServiceCreateResponse, error) {
|
||||||
var response types.ServiceCreateResponse
|
var response types.ServiceCreateResponse
|
||||||
headers := map[string][]string{
|
|
||||||
"version": {cli.version},
|
|
||||||
}
|
|
||||||
|
|
||||||
if options.EncodedRegistryAuth != "" {
|
|
||||||
headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure containerSpec is not nil when no runtime is set or the runtime is set to container
|
// Make sure containerSpec is not nil when no runtime is set or the runtime is set to container
|
||||||
if service.TaskTemplate.ContainerSpec == nil && (service.TaskTemplate.Runtime == "" || service.TaskTemplate.Runtime == swarm.RuntimeContainer) {
|
if service.TaskTemplate.ContainerSpec == nil && (service.TaskTemplate.Runtime == "" || service.TaskTemplate.Runtime == swarm.RuntimeContainer) {
|
||||||
|
@ -53,6 +48,16 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
headers := http.Header{}
|
||||||
|
if versions.LessThan(cli.version, "1.30") {
|
||||||
|
// the custom "version" header was used by engine API before 20.10
|
||||||
|
// (API 1.30) to switch between client- and server-side lookup of
|
||||||
|
// image digests.
|
||||||
|
headers["version"] = []string{cli.version}
|
||||||
|
}
|
||||||
|
if options.EncodedRegistryAuth != "" {
|
||||||
|
headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth}
|
||||||
|
}
|
||||||
resp, err := cli.post(ctx, "/services/create", nil, service, headers)
|
resp, err := cli.post(ctx, "/services/create", nil, service, headers)
|
||||||
defer ensureReaderClosed(resp)
|
defer ensureReaderClosed(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -3,11 +3,13 @@ package client // import "github.com/docker/docker/client"
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/registry"
|
"github.com/docker/docker/api/types/registry"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/api/types/versions"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServiceUpdate updates a Service. The version number is required to avoid conflicting writes.
|
// ServiceUpdate updates a Service. The version number is required to avoid conflicting writes.
|
||||||
|
@ -19,14 +21,6 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version
|
||||||
response = types.ServiceUpdateResponse{}
|
response = types.ServiceUpdateResponse{}
|
||||||
)
|
)
|
||||||
|
|
||||||
headers := map[string][]string{
|
|
||||||
"version": {cli.version},
|
|
||||||
}
|
|
||||||
|
|
||||||
if options.EncodedRegistryAuth != "" {
|
|
||||||
headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth}
|
|
||||||
}
|
|
||||||
|
|
||||||
if options.RegistryAuthFrom != "" {
|
if options.RegistryAuthFrom != "" {
|
||||||
query.Set("registryAuthFrom", options.RegistryAuthFrom)
|
query.Set("registryAuthFrom", options.RegistryAuthFrom)
|
||||||
}
|
}
|
||||||
|
@ -60,6 +54,16 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
headers := http.Header{}
|
||||||
|
if versions.LessThan(cli.version, "1.30") {
|
||||||
|
// the custom "version" header was used by engine API before 20.10
|
||||||
|
// (API 1.30) to switch between client- and server-side lookup of
|
||||||
|
// image digests.
|
||||||
|
headers["version"] = []string{cli.version}
|
||||||
|
}
|
||||||
|
if options.EncodedRegistryAuth != "" {
|
||||||
|
headers[registry.AuthHeader] = []string{options.EncodedRegistryAuth}
|
||||||
|
}
|
||||||
resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, service, headers)
|
resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, service, headers)
|
||||||
defer ensureReaderClosed(resp)
|
defer ensureReaderClosed(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -439,10 +439,5 @@ func ParseRepositoryInfo(reposName reference.Named) (*RepositoryInfo, error) {
|
||||||
// for that.
|
// for that.
|
||||||
func ParseSearchIndexInfo(reposName string) (*registry.IndexInfo, error) {
|
func ParseSearchIndexInfo(reposName string) (*registry.IndexInfo, error) {
|
||||||
indexName, _ := splitReposSearchTerm(reposName)
|
indexName, _ := splitReposSearchTerm(reposName)
|
||||||
|
return newIndexInfo(emptyServiceConfig, indexName)
|
||||||
indexInfo, err := newIndexInfo(emptyServiceConfig, indexName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return indexInfo, nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/cookiejar"
|
"net/http/cookiejar"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
@ -192,8 +193,8 @@ func (r *session) searchRepositories(term string, limit int) (*registry.SearchRe
|
||||||
if limit < 1 || limit > 100 {
|
if limit < 1 || limit > 100 {
|
||||||
return nil, invalidParamf("limit %d is outside the range of [1, 100]", limit)
|
return nil, invalidParamf("limit %d is outside the range of [1, 100]", limit)
|
||||||
}
|
}
|
||||||
log.G(context.TODO()).Debugf("Index server: %s", r.indexEndpoint)
|
|
||||||
u := r.indexEndpoint.String() + "search?q=" + url.QueryEscape(term) + "&n=" + url.QueryEscape(fmt.Sprintf("%d", limit))
|
u := r.indexEndpoint.String() + "search?q=" + url.QueryEscape(term) + "&n=" + url.QueryEscape(fmt.Sprintf("%d", limit))
|
||||||
|
log.G(context.TODO()).WithField("url", u).Debug("searchRepositories")
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, u, nil)
|
req, err := http.NewRequest(http.MethodGet, u, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -208,10 +209,14 @@ func (r *session) searchRepositories(term string, limit int) (*registry.SearchRe
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
if res.StatusCode != http.StatusOK {
|
if res.StatusCode != http.StatusOK {
|
||||||
return nil, errdefs.Unknown(&jsonmessage.JSONError{
|
return nil, errdefs.Unknown(&jsonmessage.JSONError{
|
||||||
Message: fmt.Sprintf("Unexpected status code %d", res.StatusCode),
|
Message: "Unexpected status code " + strconv.Itoa(res.StatusCode),
|
||||||
Code: res.StatusCode,
|
Code: res.StatusCode,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
result := new(registry.SearchResults)
|
result := ®istry.SearchResults{}
|
||||||
return result, errors.Wrap(json.NewDecoder(res.Body).Decode(result), "error decoding registry search results")
|
err = json.NewDecoder(res.Body).Decode(result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errdefs.System(errors.Wrap(err, "error decoding registry search results"))
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ github.com/docker/distribution/registry/client/transport
|
||||||
github.com/docker/distribution/registry/storage/cache
|
github.com/docker/distribution/registry/storage/cache
|
||||||
github.com/docker/distribution/registry/storage/cache/memory
|
github.com/docker/distribution/registry/storage/cache/memory
|
||||||
github.com/docker/distribution/uuid
|
github.com/docker/distribution/uuid
|
||||||
# github.com/docker/docker v24.0.0-rc.2.0.20230706181717-98d3da79ef9c+incompatible
|
# github.com/docker/docker v24.0.0-rc.2.0.20230714195812-dab9ffb25218+incompatible
|
||||||
## explicit
|
## explicit
|
||||||
github.com/docker/docker/api
|
github.com/docker/docker/api
|
||||||
github.com/docker/docker/api/types
|
github.com/docker/docker/api/types
|
||||||
|
@ -61,6 +61,7 @@ github.com/docker/docker/api/types/registry
|
||||||
github.com/docker/docker/api/types/strslice
|
github.com/docker/docker/api/types/strslice
|
||||||
github.com/docker/docker/api/types/swarm
|
github.com/docker/docker/api/types/swarm
|
||||||
github.com/docker/docker/api/types/swarm/runtime
|
github.com/docker/docker/api/types/swarm/runtime
|
||||||
|
github.com/docker/docker/api/types/system
|
||||||
github.com/docker/docker/api/types/time
|
github.com/docker/docker/api/types/time
|
||||||
github.com/docker/docker/api/types/versions
|
github.com/docker/docker/api/types/versions
|
||||||
github.com/docker/docker/api/types/volume
|
github.com/docker/docker/api/types/volume
|
||||||
|
|
Loading…
Reference in New Issue