Docker, containerd and runc dependencies upgraded

This commit is contained in:
Raj Chaudhuri committed 2023-03-29 12:12:48 +05:30
1 parent 1bb1f02b1d
commit 88d8bb648f
1570 files changed
+159499 -23474

No files matched your search

+483 -63
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -176,7 +176,7 @@
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");
you may not use this file except in compliance with the License.
+1 -1
View File
@@ -3,7 +3,7 @@ Copyright 2012-2017 Docker, Inc.
This product includes software developed at Docker, Inc. (https://www.docker.com).
This product contains software (https://github.com/kr/pty) developed
This product contains software (https://github.com/creack/pty) developed
by Keith Rarick, licensed under the MIT License.
The following is courtesy of our legal counsel:
+2 -2
View File
@@ -3,9 +3,9 @@ package api // import "github.com/docker/docker/api"
// Common constants for daemon and client.
const (
// DefaultVersion of Current REST API
DefaultVersion string = "1.37"
DefaultVersion = "1.42"
// NoBaseImageSpecifier is the symbol used by the FROM
// command to specify that no base image is to be used.
NoBaseImageSpecifier string = "scratch"
NoBaseImageSpecifier = "scratch"
)
+2 -1
View File
@@ -1,6 +1,7 @@
//go:build !windows
// +build !windows
package api // import "github.com/docker/docker/api"
// MinVersion represents Minimum REST API version supported
const MinVersion string = "1.12"
const MinVersion = "1.12"
+3142 -1060
View File
File diff suppressed because it is too large. Load diff
+60 -7
View File
@@ -50,7 +50,7 @@ type ContainerCommitOptions struct {
// ContainerExecInspect holds information returned by exec inspect.
type ContainerExecInspect struct {
ExecID string
ExecID string `json:"ID"`
ContainerID string
Running bool
ExitCode int
@@ -59,7 +59,6 @@ type ContainerExecInspect struct {
// ContainerListOptions holds parameters to list containers with.
type ContainerListOptions struct {
Quiet bool
Size bool
All bool
Latest bool
@@ -113,10 +112,16 @@ type NetworkListOptions struct {
Filters filters.Args
}
// NewHijackedResponse intializes a HijackedResponse type
func NewHijackedResponse(conn net.Conn, mediaType string) HijackedResponse {
return HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn), mediaType: mediaType}
}
// HijackedResponse holds connection information for a hijacked request.
type HijackedResponse struct {
Conn net.Conn
Reader *bufio.Reader
mediaType string
Conn net.Conn
Reader *bufio.Reader
}
// Close closes the hijacked connection and reader.
@@ -124,6 +129,15 @@ func (h *HijackedResponse) Close() {
h.Conn.Close()
}
// MediaType let client know if HijackedResponse hold a raw or multiplexed stream.
// returns false if HTTP Content-Type is not relevant, and container must be inspected
func (h *HijackedResponse) MediaType() (string, bool) {
if h.mediaType == "" {
return "", false
}
return h.mediaType, true
}
// CloseWriter is an interface that implements structs
// that close input streams to prevent from writing.
type CloseWriter interface {
@@ -181,8 +195,33 @@ type ImageBuildOptions struct {
Target string
SessionID 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
// Outputs defines configurations for exporting build results. Only supported
// in BuildKit mode
Outputs []ImageBuildOutput
}
// ImageBuildOutput defines configuration for exporting a build result
type ImageBuildOutput struct {
Type string
Attrs map[string]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 BuilderVersion = "2"
)
// ImageBuildResponse holds information
// returned by a server after building
// an image.
@@ -211,10 +250,20 @@ type ImageImportOptions struct {
Platform string // Platform is the target platform of the image
}
// ImageListOptions holds parameters to filter the list of images with.
// ImageListOptions holds parameters to list images with.
type ImageListOptions struct {
All bool
// All controls whether all images in the graph are filtered, or just
// the heads.
All bool
// Filters is a JSON-encoded set of filter arguments.
Filters filters.Args
// SharedSize indicates whether the shared size of images should be computed.
SharedSize bool
// ContainerCount indicates whether container count should be computed.
ContainerCount bool
}
// ImageLoadResponse returns information to the client about a load process.
@@ -240,7 +289,7 @@ type ImagePullOptions struct {
// if the privilege request fails.
type RequestPrivilegeFunc func() (string, error)
//ImagePushOptions holds information to push images.
// ImagePushOptions holds information to push images.
type ImagePushOptions ImagePullOptions
// ImageRemoveOptions holds parameters to remove images.
@@ -338,6 +387,10 @@ type ServiceUpdateOptions struct {
// ServiceListOptions holds parameters to list services with.
type ServiceListOptions struct {
Filters filters.Args
// Status indicates whether the server should include the service task
// count of running and desired tasks.
Status bool
}
// ServiceInspectOptions holds parameters related to the "service inspect"
+10
View File
@@ -3,6 +3,7 @@ package types // import "github.com/docker/docker/api/types"
import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
specs "github.com/opencontainers/image-spec/specs-go/v1"
)
// configs holds structs used for internal communication between the
@@ -15,6 +16,7 @@ type ContainerCreateConfig struct {
Config *container.Config
HostConfig *container.HostConfig
NetworkingConfig *network.NetworkingConfig
Platform *specs.Platform
AdjustCPUShares bool
}
@@ -31,6 +33,7 @@ type ExecConfig struct {
User string // User that will run the command
Privileged bool // Is the container in privileged mode
Tty bool // Attach standard streams to a tty.
ConsoleSize *[2]uint `json:",omitempty"` // Initial console size [height, width]
AttachStdin bool // Attach the standard input, makes possible user interaction
AttachStderr bool // Attach the standard error
AttachStdout bool // Attach the standard output
@@ -55,3 +58,10 @@ type PluginEnableConfig struct {
type PluginDisableConfig struct {
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
}
+28 -1
View File
@@ -1,6 +1,7 @@
package container // import "github.com/docker/docker/api/types/container"
import (
"io"
"time"
"github.com/docker/docker/api/types/strslice"
@@ -13,6 +14,24 @@ import (
// Docker interprets it as 3 nanoseconds.
const MinimumDuration = 1 * time.Millisecond
// StopOptions holds the options to stop or restart a container.
type StopOptions struct {
// Signal (optional) is the signal to send to the container to (gracefully)
// stop it before forcibly terminating the container with SIGKILL after the
// timeout expires. If not value is set, the default (SIGTERM) is used.
Signal string `json:",omitempty"`
// Timeout (optional) is the timeout (in seconds) to wait for the container
// to stop gracefully before forcibly terminating it with SIGKILL.
//
// - Use nil to use the default timeout (10 seconds).
// - Use '-1' to wait indefinitely.
// - Use '0' to not wait for the container to exit gracefully, and
// immediately proceeds to forcibly terminating the container.
// - Other positive values are used as timeout (in seconds).
Timeout *int `json:",omitempty"`
}
// HealthConfig holds configuration settings for the HEALTHCHECK feature.
type HealthConfig struct {
// Test is the test to perform to check that the container is healthy.
@@ -34,6 +53,14 @@ type HealthConfig struct {
Retries int `json:",omitempty"`
}
// ExecStartOptions holds the options to start container's exec.
type ExecStartOptions struct {
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
ConsoleSize *[2]uint `json:",omitempty"`
}
// Config contains the configuration data about a container.
// It should hold only portable information about the container.
// Here, "portable" means "independent from the host we are running on".
@@ -54,7 +81,7 @@ type Config struct {
Env []string // List of environment variable to set in the container
Cmd strslice.StrSlice // Command to run when starting the container
Healthcheck *HealthConfig `json:",omitempty"` // Healthcheck describes how to check the container is healthy
ArgsEscaped bool `json:",omitempty"` // True if command is already escaped (Windows specific)
ArgsEscaped bool `json:",omitempty"` // True if command is already escaped (meaning treat as a command line) (Windows specific).
Image string // Name of the image as it was passed by the operator (e.g. could be symbolic)
Volumes map[string]struct{} // List of volumes (mounts) used for the container
WorkingDir string // Current directory (PWD) in the command will be launched
+2 -3
View File
@@ -1,8 +1,7 @@
package container
package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
// Code generated by `swagger generate operation`. DO NOT EDIT.
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
@@ -1,21 +0,0 @@
package container
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
// ContainerCreateCreatedBody OK response to ContainerCreate operation
// swagger:model ContainerCreateCreatedBody
type ContainerCreateCreatedBody struct {
// The ID of the created container
// Required: true
ID string `json:"Id"`
// Warnings encountered when creating the container
// Required: true
Warnings []string `json:"Warnings"`
}
+5 -4
View File
@@ -1,8 +1,7 @@
package container
package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
// Code generated by `swagger generate operation`. DO NOT EDIT.
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
@@ -11,7 +10,9 @@ package container
// swagger:model ContainerTopOKBody
type ContainerTopOKBody struct {
// Each process running in the container, where each is process is an array of values corresponding to the titles
// Each process running in the container, where each is process
// is an array of values corresponding to the titles.
//
// Required: true
Processes [][]string `json:"Processes"`
+2 -3
View File
@@ -1,8 +1,7 @@
package container
package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
// Code generated by `swagger generate operation`. DO NOT EDIT.
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
-29
View File
@@ -1,29 +0,0 @@
package container
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
// 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
type ContainerWaitOKBody struct {
// error
// Required: true
Error *ContainerWaitOKBodyError `json:"Error"`
// Exit code of the container
// Required: true
StatusCode int64 `json:"StatusCode"`
}
+19
View File
@@ -0,0 +1,19 @@
package container
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// CreateResponse ContainerCreateResponse
//
// OK response to ContainerCreate operation
// swagger:model CreateResponse
type CreateResponse struct {
// The ID of the created container
// Required: true
ID string `json:"Id"`
// Warnings encountered when creating the container
// Required: true
Warnings []string `json:"Warnings"`
}
+16
View File
@@ -0,0 +1,16 @@
package container // import "github.com/docker/docker/api/types/container"
// ContainerCreateCreatedBody OK response to ContainerCreate operation
//
// Deprecated: use CreateResponse
type ContainerCreateCreatedBody = CreateResponse
// ContainerWaitOKBody OK response to ContainerWait operation
//
// Deprecated: use WaitResponse
type ContainerWaitOKBody = WaitResponse
// ContainerWaitOKBodyError container waiting error, if any
//
// Deprecated: use WaitExitError
type ContainerWaitOKBodyError = WaitExitError
+95 -36
View File
@@ -7,67 +7,106 @@ import (
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/strslice"
"github.com/docker/go-connections/nat"
"github.com/docker/go-units"
units "github.com/docker/go-units"
)
// CgroupnsMode represents the cgroup namespace mode of the container
type CgroupnsMode string
// cgroup namespace modes for containers
const (
CgroupnsModeEmpty CgroupnsMode = ""
CgroupnsModePrivate CgroupnsMode = "private"
CgroupnsModeHost CgroupnsMode = "host"
)
// IsPrivate indicates whether the container uses its own private cgroup namespace
func (c CgroupnsMode) IsPrivate() bool {
return c == CgroupnsModePrivate
}
// IsHost indicates whether the container shares the host's cgroup namespace
func (c CgroupnsMode) IsHost() bool {
return c == CgroupnsModeHost
}
// IsEmpty indicates whether the container cgroup namespace mode is unset
func (c CgroupnsMode) IsEmpty() bool {
return c == CgroupnsModeEmpty
}
// Valid indicates whether the cgroup namespace mode is valid
func (c CgroupnsMode) Valid() bool {
return c.IsEmpty() || c.IsPrivate() || c.IsHost()
}
// Isolation represents the isolation technology of a container. The supported
// values are platform specific
type Isolation string
// Isolation modes for containers
const (
IsolationEmpty Isolation = "" // IsolationEmpty is unspecified (same behavior as default)
IsolationDefault Isolation = "default" // IsolationDefault is the default isolation mode on current daemon
IsolationProcess Isolation = "process" // IsolationProcess is process isolation mode
IsolationHyperV Isolation = "hyperv" // IsolationHyperV is HyperV isolation mode
)
// IsDefault indicates the default isolation technology of a container. On Linux this
// is the native driver. On Windows, this is a Windows Server Container.
func (i Isolation) IsDefault() bool {
return strings.ToLower(string(i)) == "default" || string(i) == ""
// TODO consider making isolation-mode strict (case-sensitive)
v := Isolation(strings.ToLower(string(i)))
return v == IsolationDefault || v == IsolationEmpty
}
// IsHyperV indicates the use of a Hyper-V partition for isolation
func (i Isolation) IsHyperV() bool {
return strings.ToLower(string(i)) == "hyperv"
// TODO consider making isolation-mode strict (case-sensitive)
return Isolation(strings.ToLower(string(i))) == IsolationHyperV
}
// IsProcess indicates the use of process isolation
func (i Isolation) IsProcess() bool {
return strings.ToLower(string(i)) == "process"
// TODO consider making isolation-mode strict (case-sensitive)
return Isolation(strings.ToLower(string(i))) == IsolationProcess
}
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.
type IpcMode string
// IpcMode constants
const (
IPCModeNone IpcMode = "none"
IPCModeHost IpcMode = "host"
IPCModeContainer IpcMode = "container"
IPCModePrivate IpcMode = "private"
IPCModeShareable IpcMode = "shareable"
)
// IsPrivate indicates whether the container uses its own private ipc namespace which can not be shared.
func (n IpcMode) IsPrivate() bool {
return n == "private"
return n == IPCModePrivate
}
// IsHost indicates whether the container shares the host's ipc namespace.
func (n IpcMode) IsHost() bool {
return n == "host"
return n == IPCModeHost
}
// IsShareable indicates whether the container's ipc namespace can be shared with another container.
func (n IpcMode) IsShareable() bool {
return n == "shareable"
return n == IPCModeShareable
}
// IsContainer indicates whether the container uses another container's ipc namespace.
func (n IpcMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
return len(parts) > 1 && parts[0] == "container"
return strings.HasPrefix(string(n), string(IPCModeContainer)+":")
}
// IsNone indicates whether container IpcMode is set to "none".
func (n IpcMode) IsNone() bool {
return n == "none"
return n == IPCModeNone
}
// IsEmpty indicates whether container IpcMode is empty
@@ -82,9 +121,8 @@ func (n IpcMode) Valid() bool {
// Container returns the name of the container ipc stack is going to be used.
func (n IpcMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
if len(parts) > 1 && parts[0] == "container" {
return parts[1]
if n.IsContainer() {
return strings.TrimPrefix(string(n), string(IPCModeContainer)+":")
}
return ""
}
@@ -122,7 +160,7 @@ func (n NetworkMode) ConnectedContainer() string {
return ""
}
//UserDefined indicates user-created network
// UserDefined indicates user-created network
func (n NetworkMode) UserDefined() string {
if n.IsUserDefined() {
return string(n)
@@ -244,6 +282,16 @@ func (n PidMode) Container() string {
return ""
}
// DeviceRequest represents a request for devices from a device driver.
// Used by GPU device drivers.
type DeviceRequest struct {
Driver string // Name of device driver
Count int // Number of devices to request (-1 = All)
DeviceIDs []string // List of device IDs as recognizable by the device driver
Capabilities [][]string // An OR list of AND lists of device capabilities (e.g. "gpu")
Options map[string]string // Options to pass onto the device driver
}
// DeviceMapping represents the device mapping between the host and the container.
type DeviceMapping struct {
PathOnHost string
@@ -293,7 +341,7 @@ type LogMode string
// Available logging modes
const (
LogModeUnset = ""
LogModeUnset LogMode = ""
LogModeBlocking LogMode = "blocking"
LogModeNonBlock LogMode = "non-blocking"
)
@@ -327,14 +375,18 @@ type Resources struct {
CpusetMems string // CpusetMems 0-2, 0,1
Devices []DeviceMapping // List of devices to map inside the container
DeviceCgroupRules []string // List of rule to be added to the device cgroup
DiskQuota int64 // Disk limit (in bytes)
KernelMemory int64 // Kernel memory limit (in bytes)
MemoryReservation int64 // Memory soft limit (in bytes)
MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap
MemorySwappiness *int64 // Tuning container memory swappiness behaviour
OomKillDisable *bool // Whether to disable OOM Killer or not
PidsLimit int64 // Setting pids limit for a container
Ulimits []*units.Ulimit // List of ulimits to be set in the container
DeviceRequests []DeviceRequest // List of device requests for device drivers
// KernelMemory specifies the kernel memory limit (in bytes) for the container.
// Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes.
KernelMemory int64 `json:",omitempty"`
KernelMemoryTCP int64 `json:",omitempty"` // Hard limit for kernel TCP buffer memory (in bytes)
MemoryReservation int64 // Memory soft limit (in bytes)
MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap
MemorySwappiness *int64 // Tuning container memory swappiness behaviour
OomKillDisable *bool // Whether to disable OOM Killer or not
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
// Applicable to Windows
CPUCount int64 `json:"CpuCount"` // CPU count
@@ -365,10 +417,12 @@ type HostConfig struct {
AutoRemove bool // Automatically remove container when it exits
VolumeDriver string // Name of the volume driver used to mount volumes
VolumesFrom []string // List of volumes to take from other container
ConsoleSize [2]uint // Initial console size (height,width)
// Applicable to UNIX platforms
CapAdd strslice.StrSlice // List of kernel capabilities to add to the container
CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container
CgroupnsMode CgroupnsMode // Cgroup namespace mode to use for the container
DNS []string `json:"Dns"` // List of DNS server to lookup
DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for
DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for
@@ -392,8 +446,7 @@ type HostConfig struct {
Runtime string `json:",omitempty"` // Runtime to use with this container
// Applicable to Windows
ConsoleSize [2]uint // Initial console size (height,width)
Isolation Isolation // Isolation technology of the container (e.g. default, hyperv)
Isolation Isolation // Isolation technology of the container (e.g. default, hyperv)
// Contains container's resources (cgroups, ulimits)
Resources
@@ -401,6 +454,12 @@ type HostConfig struct {
// Mounts specs used by the container
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
Init *bool `json:",omitempty"`
}
@@ -1,3 +1,4 @@
//go:build !windows
// +build !windows
package container // import "github.com/docker/docker/api/types/container"
+12
View File
@@ -0,0 +1,12 @@
package container
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// WaitExitError container waiting error, if any
// swagger:model WaitExitError
type WaitExitError struct {
// Details of an error
Message string `json:"Message,omitempty"`
}
+18
View File
@@ -0,0 +1,18 @@
package container
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// WaitResponse ContainerWaitResponse
//
// OK response to ContainerWait operation
// swagger:model WaitResponse
type WaitResponse struct {
// error
Error *WaitExitError `json:"Error,omitempty"`
// Exit code of the container
// Required: true
StatusCode int64 `json:"StatusCode"`
}
+14
View File
@@ -0,0 +1,14 @@
package types // import "github.com/docker/docker/api/types"
import "github.com/docker/docker/api/types/volume"
// Volume volume
//
// Deprecated: use github.com/docker/docker/api/types/volume.Volume
type Volume = volume.Volume
// VolumeUsageData Usage details about the volume. This information is used by the
// `GET /system/df` endpoint, and omitted in other endpoints.
//
// Deprecated: use github.com/docker/docker/api/types/volume.UsageData
type VolumeUsageData = volume.UsageData
+6
View File
@@ -0,0 +1,6 @@
package types
// Error returns the error message
func (e ErrorResponse) Error() string {
return e.Message
}
+20 -25
View File
@@ -1,31 +1,26 @@
package events // import "github.com/docker/docker/api/types/events"
// Type is used for event-types.
type Type = string
// List of known event types.
const (
// ContainerEventType is the event type that containers generate
ContainerEventType = "container"
// DaemonEventType is the event type that daemon generate
DaemonEventType = "daemon"
// ImageEventType is the event type that images generate
ImageEventType = "image"
// NetworkEventType is the event type that networks generate
NetworkEventType = "network"
// PluginEventType is the event type that plugins generate
PluginEventType = "plugin"
// VolumeEventType is the event type that volumes generate
VolumeEventType = "volume"
// ServiceEventType is the event type that services generate
ServiceEventType = "service"
// NodeEventType is the event type that nodes generate
NodeEventType = "node"
// SecretEventType is the event type that secrets generate
SecretEventType = "secret"
// ConfigEventType is the event type that configs generate
ConfigEventType = "config"
BuilderEventType Type = "builder" // BuilderEventType is the event type that the builder generates.
ConfigEventType Type = "config" // ConfigEventType is the event type that configs generate.
ContainerEventType Type = "container" // ContainerEventType is the event type that containers generate.
DaemonEventType Type = "daemon" // DaemonEventType is the event type that daemon generate.
ImageEventType Type = "image" // ImageEventType is the event type that images generate.
NetworkEventType Type = "network" // NetworkEventType is the event type that networks generate.
NodeEventType Type = "node" // NodeEventType is the event type that nodes generate.
PluginEventType Type = "plugin" // PluginEventType is the event type that plugins generate.
SecretEventType Type = "secret" // SecretEventType is the event type that secrets generate.
ServiceEventType Type = "service" // ServiceEventType is the event type that services generate.
VolumeEventType Type = "volume" // VolumeEventType is the event type that volumes generate.
)
// Actor describes something that generates events,
// like a container, or a network, or a volume.
// It has a defined name and a set or attributes.
// It has a defined name and a set of attributes.
// The container attributes are its labels, other actors
// can generate these attributes from other properties.
type Actor struct {
@@ -37,11 +32,11 @@ type Actor struct {
type Message struct {
// Deprecated information from JSONMessage.
// With data only in container events.
Status string `json:"status,omitempty"`
ID string `json:"id,omitempty"`
From string `json:"from,omitempty"`
Status string `json:"status,omitempty"` // Deprecated: use Action instead.
ID string `json:"id,omitempty"` // Deprecated: use Actor.ID instead.
From string `json:"from,omitempty"` // Deprecated: use Actor.Attributes["image"] instead.
Type string
Type Type
Action string
Actor Actor
// Engine events are local scope. Cluster events are swarm scope.
+34 -61
View File
@@ -1,15 +1,16 @@
/*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.
*/
package filters // import "github.com/docker/docker/api/types/filters"
import (
"encoding/json"
"errors"
"regexp"
"strings"
"github.com/docker/docker/api/types/versions"
"github.com/pkg/errors"
)
// Args stores a mapping of keys to a set of multiple values.
@@ -37,45 +38,19 @@ func NewArgs(initialArgs ...KeyValuePair) Args {
return args
}
// ParseFlag parses a key=value string and adds it to an Args.
//
// Deprecated: Use Args.Add()
func ParseFlag(arg string, prev Args) (Args, error) {
filters := prev
if len(arg) == 0 {
return filters, nil
// Keys returns all the keys in list of Args
func (args Args) Keys() []string {
keys := make([]string, 0, len(args.fields))
for k := range args.fields {
keys = append(keys, k)
}
if !strings.Contains(arg, "=") {
return filters, ErrBadFormat
}
f := strings.SplitN(arg, "=", 2)
name := strings.ToLower(strings.TrimSpace(f[0]))
value := strings.TrimSpace(f[1])
filters.Add(name, value)
return filters, nil
}
// ErrBadFormat is an error returned when a filter is not in the form key=value
//
// Deprecated: this error will be removed in a future version
var ErrBadFormat = errors.New("bad format of filter (expected name=value)")
// ToParam encodes the Args as args JSON encoded string
//
// Deprecated: use ToJSON
func ToParam(a Args) (string, error) {
return ToJSON(a)
return keys
}
// MarshalJSON returns a JSON byte representation of the Args
func (args Args) MarshalJSON() ([]byte, error) {
if len(args.fields) == 0 {
return []byte{}, nil
return []byte("{}"), nil
}
return json.Marshal(args.fields)
}
@@ -93,7 +68,7 @@ func ToJSON(a Args) (string, error) {
// then the encoded format will use an older legacy format where the values are a
// list of strings, instead of a set.
//
// Deprecated: Use ToJSON
// Deprecated: do not use in any new code; use ToJSON instead
func ToParamWithVersion(version string, a Args) (string, error) {
if a.Len() == 0 {
return "", nil
@@ -107,13 +82,6 @@ func ToParamWithVersion(version string, a Args) (string, error) {
return ToJSON(a)
}
// FromParam decodes a JSON encoded string into Args
//
// Deprecated: use FromJSON
func FromParam(p string) (Args, error) {
return FromJSON(p)
}
// FromJSON decodes a JSON encoded string into Args
func FromJSON(p string) (Args, error) {
args := NewArgs()
@@ -131,7 +99,7 @@ func FromJSON(p string) (Args, error) {
// Fallback to parsing arguments in the legacy slice format
deprecated := map[string][]string{}
if legacyErr := json.Unmarshal(raw, &deprecated); legacyErr != nil {
return args, err
return args, invalidFilter{errors.Wrap(err, "invalid filter")}
}
args.fields = deprecatedArgs(deprecated)
@@ -140,9 +108,6 @@ func FromJSON(p string) (Args, error) {
// UnmarshalJSON populates the Args from JSON encode bytes
func (args Args) UnmarshalJSON(raw []byte) error {
if len(raw) == 0 {
return nil
}
return json.Unmarshal(raw, &args.fields)
}
@@ -188,7 +153,7 @@ func (args Args) Len() int {
func (args Args) MatchKVList(key string, sources map[string]string) bool {
fieldValues := args.fields[key]
//do not filter if there is no filter set or cannot determine filter
// do not filter if there is no filter set or cannot determine filter
if len(fieldValues) == 0 {
return true
}
@@ -234,7 +199,7 @@ func (args Args) Match(field, source string) bool {
// ExactMatch returns true if the source matches exactly one of the values.
func (args Args) ExactMatch(key, source string) bool {
fieldValues, ok := args.fields[key]
//do not filter if there is no filter set or cannot determine filter
// do not filter if there is no filter set or cannot determine filter
if !ok || len(fieldValues) == 0 {
return true
}
@@ -247,7 +212,7 @@ func (args Args) ExactMatch(key, source string) bool {
// matches exactly the value.
func (args Args) UniqueExactMatch(key, source string) bool {
fieldValues := args.fields[key]
//do not filter if there is no filter set or cannot determine filter
// do not filter if there is no filter set or cannot determine filter
if len(fieldValues) == 0 {
return true
}
@@ -275,24 +240,16 @@ func (args Args) FuzzyMatch(key, source string) bool {
return false
}
// Include returns true if the key exists in the mapping
//
// Deprecated: use Contains
func (args Args) Include(field string) bool {
_, ok := args.fields[field]
return ok
}
// Contains returns true if the key exists in the mapping
func (args Args) Contains(field string) bool {
_, ok := args.fields[field]
return ok
}
type invalidFilter string
type invalidFilter struct{ error }
func (e invalidFilter) Error() string {
return "Invalid filter '" + string(e) + "'"
return e.error.Error()
}
func (invalidFilter) InvalidParameter() {}
@@ -302,7 +259,7 @@ func (invalidFilter) InvalidParameter() {}
func (args Args) Validate(accepted map[string]bool) error {
for name := range args.fields {
if !accepted[name] {
return invalidFilter(name)
return invalidFilter{errors.New("invalid filter '" + name + "'")}
}
}
return nil
@@ -323,6 +280,22 @@ func (args Args) WalkValues(field string, op func(value string) error) error {
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 {
m := map[string]map[string]bool{}
for k, v := range d {
+9 -3
View File
@@ -3,15 +3,21 @@ package types
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// GraphDriverData Information about a container's graph driver.
// GraphDriverData Information about the storage driver used to store the container's and
// image's filesystem.
//
// swagger:model GraphDriverData
type GraphDriverData struct {
// data
// Low-level storage metadata, provided as key/value pairs.
//
// This information is driver-specific, and depends on the storage-driver
// in use, and should be used for informational purposes only.
//
// Required: true
Data map[string]string `json:"Data"`
// name
// Name of the storage driver.
// Required: true
Name string `json:"Name"`
}
+2 -3
View File
@@ -1,8 +1,7 @@
package image
package image // import "github.com/docker/docker/api/types/image"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
// Code generated by `swagger generate operation`. DO NOT EDIT.
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
+58 -10
View File
@@ -7,43 +7,91 @@ package types
// swagger:model ImageSummary
type ImageSummary struct {
// containers
// Number of containers using this image. Includes both stopped and running
// containers.
//
// This size is not calculated by default, and depends on which API endpoint
// is used. `-1` indicates that the value has not been set / calculated.
//
// Required: true
Containers int64 `json:"Containers"`
// created
// Date and time at which the image was created as a Unix timestamp
// (number of seconds sinds EPOCH).
//
// Required: true
Created int64 `json:"Created"`
// Id
// ID is the content-addressable ID of an image.
//
// This identifier is a content-addressable digest calculated from the
// image's configuration (which includes the digests of layers used by
// the image).
//
// Note that this digest differs from the `RepoDigests` below, which
// holds digests of image manifests that reference the image.
//
// Required: true
ID string `json:"Id"`
// labels
// User-defined key/value metadata.
// Required: true
Labels map[string]string `json:"Labels"`
// parent Id
// ID of the parent image.
//
// Depending on how the image was created, this field may be empty and
// is only set for images that were built/created locally. This field
// is empty if the image was pulled from an image registry.
//
// Required: true
ParentID string `json:"ParentId"`
// repo digests
// List of content-addressable digests of locally available image manifests
// that the image is referenced from. Multiple manifests can refer to the
// same image.
//
// These digests are usually only available if the image was either pulled
// from a registry, or if the image was pushed to a registry, which is when
// the manifest is generated and its digest calculated.
//
// Required: true
RepoDigests []string `json:"RepoDigests"`
// repo tags
// List of image names/tags in the local image cache that reference this
// image.
//
// Multiple image tags can refer to the same image, and this list may be
// empty if no tags reference the image, in which case the image is
// "untagged", in which case it can still be referenced by its ID.
//
// Required: true
RepoTags []string `json:"RepoTags"`
// shared size
// Total size of image layers that are shared between this image and other
// images.
//
// This size is not calculated by default. `-1` indicates that the value
// has not been set / calculated.
//
// Required: true
SharedSize int64 `json:"SharedSize"`
// size
// Total size of the image including all layers it is composed of.
//
// Required: true
Size int64 `json:"Size"`
// virtual size
// Total size of the image including all layers it is composed of.
//
// In versions of Docker before v1.10, this field was calculated from
// the image itself and all of its parent images. Docker v1.10 and up
// store images self-contained, and no longer use a parent-chain, making
// this field an equivalent of the Size field.
//
// This field is kept for backward compatibility, but may be removed in
// a future version of the API.
//
// Required: true
VirtualSize int64 `json:"VirtualSize"`
}
+15 -5
View File
@@ -17,6 +17,8 @@ const (
TypeTmpfs Type = "tmpfs"
// TypeNamedPipe is the type for mounting Windows named pipes
TypeNamedPipe Type = "npipe"
// TypeCluster is the type for Swarm Cluster Volumes.
TypeCluster Type = "cluster"
)
// Mount represents a mount (volume).
@@ -30,9 +32,10 @@ type Mount struct {
ReadOnly bool `json:",omitempty"`
Consistency Consistency `json:",omitempty"`
BindOptions *BindOptions `json:",omitempty"`
VolumeOptions *VolumeOptions `json:",omitempty"`
TmpfsOptions *TmpfsOptions `json:",omitempty"`
BindOptions *BindOptions `json:",omitempty"`
VolumeOptions *VolumeOptions `json:",omitempty"`
TmpfsOptions *TmpfsOptions `json:",omitempty"`
ClusterOptions *ClusterOptions `json:",omitempty"`
}
// Propagation represents the propagation of a mount.
@@ -79,7 +82,9 @@ const (
// BindOptions defines options specific to mounts of type "bind".
type BindOptions struct {
Propagation Propagation `json:",omitempty"`
Propagation Propagation `json:",omitempty"`
NonRecursive bool `json:",omitempty"`
CreateMountpoint bool `json:",omitempty"`
}
// VolumeOptions represents the options for a mount of type volume.
@@ -112,7 +117,7 @@ type TmpfsOptions struct {
// TODO(stevvooe): There are several more tmpfs flags, specified in the
// daemon, that are accepted. Only the most basic are added for now.
//
// From docker/docker/pkg/mount/flags.go:
// From https://github.com/moby/sys/blob/mount/v0.1.1/mount/flags.go#L47-L56
//
// var validFlags = map[string]bool{
// "": true,
@@ -128,3 +133,8 @@ type TmpfsOptions struct {
// Some of these may be straightforward to add, but others, such as
// uid/gid have implications in a clustered system.
}
// ClusterOptions specifies options for a Cluster volume.
type ClusterOptions struct {
// intentionally empty
}
+19 -1
View File
@@ -1,4 +1,7 @@
package network // import "github.com/docker/docker/api/types/network"
import (
"github.com/docker/docker/api/types/filters"
)
// Address represents an IP address
type Address struct {
@@ -9,7 +12,7 @@ type Address struct {
// IPAM represents IP Address Management
type IPAM struct {
Driver string
Options map[string]string //Per network IPAM driver options
Options map[string]string // Per network IPAM driver options
Config []IPAMConfig
}
@@ -106,3 +109,18 @@ type NetworkingConfig struct {
type ConfigReference struct {
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 filter.Validate(acceptedFilters)
}
+3
View File
@@ -121,6 +121,9 @@ type PluginConfigArgs struct {
// swagger:model PluginConfigInterface
type PluginConfigInterface struct {
// Protocol to use for clients connecting to the plugin.
ProtocolScheme string `json:"ProtocolScheme,omitempty"`
// socket
// Required: true
Socket string `json:"Socket"`
+1 -1
View File
@@ -7,7 +7,7 @@ package types
// swagger:model Port
type Port struct {
// IP
// Host IP address that the container's port is mapped to
IP string `json:"IP,omitempty"`
// Port on the container
+26 -25
View File
@@ -4,7 +4,7 @@ import (
"encoding/json"
"net"
"github.com/opencontainers/image-spec/specs-go/v1"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
// ServiceConfig stores daemon registry services configuration.
@@ -45,31 +45,32 @@ func (ipnet *NetIPNet) UnmarshalJSON(b []byte) (err error) {
// IndexInfo contains information about a registry
//
// RepositoryInfo Examples:
// {
// "Index" : {
// "Name" : "docker.io",
// "Mirrors" : ["https://registry-2.docker.io/v1/", "https://registry-3.docker.io/v1/"],
// "Secure" : true,
// "Official" : true,
// },
// "RemoteName" : "library/debian",
// "LocalName" : "debian",
// "CanonicalName" : "docker.io/debian"
// "Official" : true,
// }
//
// {
// "Index" : {
// "Name" : "127.0.0.1:5000",
// "Mirrors" : [],
// "Secure" : false,
// "Official" : false,
// },
// "RemoteName" : "user/repo",
// "LocalName" : "127.0.0.1:5000/user/repo",
// "CanonicalName" : "127.0.0.1:5000/user/repo",
// "Official" : false,
// }
// {
// "Index" : {
// "Name" : "docker.io",
// "Mirrors" : ["https://registry-2.docker.io/v1/", "https://registry-3.docker.io/v1/"],
// "Secure" : true,
// "Official" : true,
// },
// "RemoteName" : "library/debian",
// "LocalName" : "debian",
// "CanonicalName" : "docker.io/debian"
// "Official" : true,
// }
//
// {
// "Index" : {
// "Name" : "127.0.0.1:5000",
// "Mirrors" : [],
// "Secure" : false,
// "Official" : false,
// },
// "RemoteName" : "user/repo",
// "LocalName" : "127.0.0.1:5000/user/repo",
// "CanonicalName" : "127.0.0.1:5000/user/repo",
// "Official" : false,
// }
type IndexInfo struct {
// Name is the name of the registry, such as "docker.io"
Name string
-93
View File
@@ -1,93 +0,0 @@
package types // import "github.com/docker/docker/api/types"
// Seccomp represents the config for a seccomp profile for syscall restriction.
type Seccomp struct {
DefaultAction Action `json:"defaultAction"`
// Architectures is kept to maintain backward compatibility with the old
// seccomp profile.
Architectures []Arch `json:"architectures,omitempty"`
ArchMap []Architecture `json:"archMap,omitempty"`
Syscalls []*Syscall `json:"syscalls"`
}
// Architecture is used to represent a specific architecture
// and its sub-architectures
type Architecture struct {
Arch Arch `json:"architecture"`
SubArches []Arch `json:"subArchitectures"`
}
// Arch used for architectures
type Arch string
// Additional architectures permitted to be used for system calls
// By default only the native architecture of the kernel is permitted
const (
ArchX86 Arch = "SCMP_ARCH_X86"
ArchX86_64 Arch = "SCMP_ARCH_X86_64"
ArchX32 Arch = "SCMP_ARCH_X32"
ArchARM Arch = "SCMP_ARCH_ARM"
ArchAARCH64 Arch = "SCMP_ARCH_AARCH64"
ArchMIPS Arch = "SCMP_ARCH_MIPS"
ArchMIPS64 Arch = "SCMP_ARCH_MIPS64"
ArchMIPS64N32 Arch = "SCMP_ARCH_MIPS64N32"
ArchMIPSEL Arch = "SCMP_ARCH_MIPSEL"
ArchMIPSEL64 Arch = "SCMP_ARCH_MIPSEL64"
ArchMIPSEL64N32 Arch = "SCMP_ARCH_MIPSEL64N32"
ArchPPC Arch = "SCMP_ARCH_PPC"
ArchPPC64 Arch = "SCMP_ARCH_PPC64"
ArchPPC64LE Arch = "SCMP_ARCH_PPC64LE"
ArchS390 Arch = "SCMP_ARCH_S390"
ArchS390X Arch = "SCMP_ARCH_S390X"
)
// Action taken upon Seccomp rule match
type Action string
// Define actions for Seccomp rules
const (
ActKill Action = "SCMP_ACT_KILL"
ActTrap Action = "SCMP_ACT_TRAP"
ActErrno Action = "SCMP_ACT_ERRNO"
ActTrace Action = "SCMP_ACT_TRACE"
ActAllow Action = "SCMP_ACT_ALLOW"
)
// Operator used to match syscall arguments in Seccomp
type Operator string
// Define operators for syscall arguments in Seccomp
const (
OpNotEqual Operator = "SCMP_CMP_NE"
OpLessThan Operator = "SCMP_CMP_LT"
OpLessEqual Operator = "SCMP_CMP_LE"
OpEqualTo Operator = "SCMP_CMP_EQ"
OpGreaterEqual Operator = "SCMP_CMP_GE"
OpGreaterThan Operator = "SCMP_CMP_GT"
OpMaskedEqual Operator = "SCMP_CMP_MASKED_EQ"
)
// Arg used for matching specific syscall arguments in Seccomp
type Arg struct {
Index uint `json:"index"`
Value uint64 `json:"value"`
ValueTwo uint64 `json:"valueTwo"`
Op Operator `json:"op"`
}
// Filter is used to conditionally apply Seccomp rules
type Filter struct {
Caps []string `json:"caps,omitempty"`
Arches []string `json:"arches,omitempty"`
}
// Syscall is used to match a group of syscalls in Seccomp
type Syscall struct {
Name string `json:"name,omitempty"`
Names []string `json:"names,omitempty"`
Action Action `json:"action"`
Args []*Arg `json:"args"`
Comment string `json:"comment"`
Includes Filter `json:"includes"`
Excludes Filter `json:"excludes"`
}
+2 -2
View File
@@ -120,7 +120,7 @@ type NetworkStats struct {
RxBytes uint64 `json:"rx_bytes"`
// Packets received. Windows and Linux.
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.
RxErrors uint64 `json:"rx_errors"`
// Incoming packets dropped. Windows and Linux.
@@ -129,7 +129,7 @@ type NetworkStats struct {
TxBytes uint64 `json:"tx_bytes"`
// Packets sent. Windows and Linux.
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.
TxErrors uint64 `json:"tx_errors"`
// Outgoing packets dropped. Windows and Linux.
+9 -1
View File
@@ -1,12 +1,20 @@
package swarm // import "github.com/docker/docker/api/types/swarm"
import "time"
import (
"strconv"
"time"
)
// Version represents the internal object version.
type Version struct {
Index uint64 `json:",omitempty"`
}
// String implements fmt.Stringer interface.
func (v Version) String() string {
return strconv.FormatUint(v.Index, 10)
}
// Meta is a base object inherited by most of the other once.
type Meta struct {
Version Version `json:",omitempty"`
+6 -1
View File
@@ -27,9 +27,14 @@ type ConfigReferenceFileTarget struct {
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
type ConfigReference struct {
File *ConfigReferenceFileTarget
File *ConfigReferenceFileTarget `json:",omitempty"`
Runtime *ConfigReferenceRuntimeTarget `json:",omitempty"`
ConfigID string
ConfigName string
}
+12 -5
View File
@@ -5,6 +5,7 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/mount"
"github.com/docker/go-units"
)
// DNSConfig specifies DNS related configurations in resolver configuration file (resolv.conf)
@@ -33,6 +34,7 @@ type SELinuxContext struct {
// CredentialSpec for managed service account (Windows only)
type CredentialSpec struct {
Config string
File string
Registry string
}
@@ -55,6 +57,7 @@ type ContainerSpec struct {
User string `json:",omitempty"`
Groups []string `json:",omitempty"`
Privileges *Privileges `json:",omitempty"`
Init *bool `json:",omitempty"`
StopSignal string `json:",omitempty"`
TTY bool `json:",omitempty"`
OpenStdin bool `json:",omitempty"`
@@ -65,9 +68,13 @@ type ContainerSpec struct {
// The format of extra hosts on swarmkit is specified in:
// http://man7.org/linux/man-pages/man5/hosts.5.html
// IP_address canonical_hostname [aliases...]
Hosts []string `json:",omitempty"`
DNSConfig *DNSConfig `json:",omitempty"`
Secrets []*SecretReference `json:",omitempty"`
Configs []*ConfigReference `json:",omitempty"`
Isolation container.Isolation `json:",omitempty"`
Hosts []string `json:",omitempty"`
DNSConfig *DNSConfig `json:",omitempty"`
Secrets []*SecretReference `json:",omitempty"`
Configs []*ConfigReference `json:",omitempty"`
Isolation container.Isolation `json:",omitempty"`
Sysctls map[string]string `json:",omitempty"`
CapabilityAdd []string `json:",omitempty"`
CapabilityDrop []string `json:",omitempty"`
Ulimits []*units.Ulimit `json:",omitempty"`
}
+24
View File
@@ -53,6 +53,7 @@ type NodeDescription struct {
Resources Resources `json:",omitempty"`
Engine EngineDescription `json:",omitempty"`
TLSInfo TLSInfo `json:",omitempty"`
CSIInfo []NodeCSIInfo `json:",omitempty"`
}
// Platform represents the platform (Arch/OS).
@@ -68,6 +69,21 @@ type EngineDescription struct {
Plugins []PluginDescription `json:",omitempty"`
}
// NodeCSIInfo represents information about a CSI plugin available on the node
type NodeCSIInfo struct {
// PluginName is the name of the CSI plugin.
PluginName string `json:",omitempty"`
// NodeID is the ID of the node as reported by the CSI plugin. This is
// different from the swarm node ID.
NodeID string `json:",omitempty"`
// MaxVolumesPerNode is the maximum number of volumes that may be published
// to this node
MaxVolumesPerNode int64 `json:",omitempty"`
// AccessibleTopology indicates the location of this node in the CSI
// plugin's topology
AccessibleTopology *Topology `json:",omitempty"`
}
// PluginDescription represents the description of an engine plugin.
type PluginDescription struct {
Type string `json:",omitempty"`
@@ -113,3 +129,11 @@ const (
// NodeStateDisconnected DISCONNECTED
NodeStateDisconnected NodeState = "disconnected"
)
// Topology defines the CSI topology of this node. This type is a duplicate of
// github.com/docker/docker/api/types.Topology. Because the type definition
// is so simple and to avoid complicated structure or circular imports, we just
// duplicate it here. See that type for full documentation
type Topology struct {
Segments map[string]string `json:",omitempty"`
}
+8
View File
@@ -11,9 +11,17 @@ const (
RuntimeContainer RuntimeType = "container"
// RuntimePlugin is the plugin based runtime
RuntimePlugin RuntimeType = "plugin"
// RuntimeNetworkAttachment is the network attachment runtime
RuntimeNetworkAttachment RuntimeType = "attachment"
// RuntimeURLContainer is the proto url for the container type
RuntimeURLContainer RuntimeURL = "types.docker.com/RuntimeContainer"
// RuntimeURLPlugin is the proto url for the plugin type
RuntimeURLPlugin RuntimeURL = "types.docker.com/RuntimePlugin"
)
// NetworkAttachmentSpec represents the runtime spec type for network
// attachment tasks
type NetworkAttachmentSpec struct {
ContainerID string
}
+76 -34
View File
@@ -1,6 +1,5 @@
// Code generated by protoc-gen-gogo.
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: plugin.proto
// DO NOT EDIT!
/*
Package runtime is a generated protocol buffer package.
@@ -38,6 +37,7 @@ type PluginSpec struct {
Remote string `protobuf:"bytes,2,opt,name=remote,proto3" json:"remote,omitempty"`
Privileges []*PluginPrivilege `protobuf:"bytes,3,rep,name=privileges" json:"privileges,omitempty"`
Disabled bool `protobuf:"varint,4,opt,name=disabled,proto3" json:"disabled,omitempty"`
Env []string `protobuf:"bytes,5,rep,name=env" json:"env,omitempty"`
}
func (m *PluginSpec) Reset() { *m = PluginSpec{} }
@@ -73,6 +73,13 @@ func (m *PluginSpec) GetDisabled() bool {
return false
}
func (m *PluginSpec) GetEnv() []string {
if m != nil {
return m.Env
}
return nil
}
// PluginPrivilege describes a permission the user has to accept
// upon installing a plugin.
type PluginPrivilege struct {
@@ -160,6 +167,21 @@ func (m *PluginSpec) MarshalTo(dAtA []byte) (int, error) {
}
i++
}
if len(m.Env) > 0 {
for _, s := range m.Env {
dAtA[i] = 0x2a
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
return i, nil
}
@@ -208,24 +230,6 @@ func (m *PluginPrivilege) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func encodeFixed64Plugin(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Plugin(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintPlugin(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
@@ -255,6 +259,12 @@ func (m *PluginSpec) Size() (n int) {
if m.Disabled {
n += 2
}
if len(m.Env) > 0 {
for _, s := range m.Env {
l = len(s)
n += 1 + l + sovPlugin(uint64(l))
}
}
return n
}
@@ -429,6 +439,35 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
}
}
m.Disabled = bool(v != 0)
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlugin
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPlugin
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Env = append(m.Env, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPlugin(dAtA[iNdEx:])
@@ -695,18 +734,21 @@ var (
func init() { proto.RegisterFile("plugin.proto", fileDescriptorPlugin) }
var fileDescriptorPlugin = []byte{
// 196 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0xc8, 0x29, 0x4d,
0xcf, 0xcc, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x6a, 0x63, 0xe4, 0xe2, 0x0a, 0x00, 0x0b,
0x04, 0x17, 0xa4, 0x26, 0x0b, 0x09, 0x71, 0xb1, 0xe4, 0x25, 0xe6, 0xa6, 0x4a, 0x30, 0x2a, 0x30,
0x6a, 0x70, 0x06, 0x81, 0xd9, 0x42, 0x62, 0x5c, 0x6c, 0x45, 0xa9, 0xb9, 0xf9, 0x25, 0xa9, 0x12,
0x4c, 0x60, 0x51, 0x28, 0x4f, 0xc8, 0x80, 0x8b, 0xab, 0xa0, 0x28, 0xb3, 0x2c, 0x33, 0x27, 0x35,
0x3d, 0xb5, 0x58, 0x82, 0x59, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x40, 0x0f, 0x62, 0x58, 0x00, 0x4c,
0x22, 0x08, 0x49, 0x8d, 0x90, 0x14, 0x17, 0x47, 0x4a, 0x66, 0x71, 0x62, 0x52, 0x4e, 0x6a, 0x8a,
0x04, 0x8b, 0x02, 0xa3, 0x06, 0x47, 0x10, 0x9c, 0xaf, 0x14, 0xcb, 0xc5, 0x8f, 0xa6, 0x15, 0xab,
0x63, 0x14, 0xb8, 0xb8, 0x53, 0x52, 0x8b, 0x93, 0x8b, 0x32, 0x0b, 0x4a, 0x32, 0xf3, 0xf3, 0xa0,
0x2e, 0x42, 0x16, 0x12, 0x12, 0xe1, 0x62, 0x2d, 0x4b, 0xcc, 0x29, 0x4d, 0x05, 0xbb, 0x88, 0x33,
0x08, 0xc2, 0x71, 0xe2, 0x39, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4,
0x18, 0x93, 0xd8, 0xc0, 0x9e, 0x37, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xb8, 0x84, 0xad, 0x79,
0x0c, 0x01, 0x00, 0x00,
// 256 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x4d, 0x4b, 0xc3, 0x30,
0x18, 0xc7, 0x89, 0xdd, 0xc6, 0xfa, 0x4c, 0x70, 0x04, 0x91, 0xe2, 0xa1, 0x94, 0x9d, 0x7a, 0x6a,
0x45, 0x2f, 0x82, 0x37, 0x0f, 0x9e, 0x47, 0xbc, 0x09, 0x1e, 0xd2, 0xf6, 0xa1, 0x06, 0x9b, 0x17,
0x92, 0xb4, 0xe2, 0x37, 0xf1, 0x23, 0x79, 0xf4, 0x23, 0x48, 0x3f, 0x89, 0x98, 0x75, 0x32, 0x64,
0xa7, 0xff, 0x4b, 0xc2, 0x9f, 0x1f, 0x0f, 0x9c, 0x9a, 0xae, 0x6f, 0x85, 0x2a, 0x8c, 0xd5, 0x5e,
0x6f, 0x3e, 0x08, 0xc0, 0x36, 0x14, 0x8f, 0x06, 0x6b, 0x4a, 0x61, 0xa6, 0xb8, 0xc4, 0x84, 0x64,
0x24, 0x8f, 0x59, 0xf0, 0xf4, 0x02, 0x16, 0x16, 0xa5, 0xf6, 0x98, 0x9c, 0x84, 0x76, 0x4a, 0xf4,
0x0a, 0xc0, 0x58, 0x31, 0x88, 0x0e, 0x5b, 0x74, 0x49, 0x94, 0x45, 0xf9, 0xea, 0x7a, 0x5d, 0xec,
0xc6, 0xb6, 0xfb, 0x07, 0x76, 0xf0, 0x87, 0x5e, 0xc2, 0xb2, 0x11, 0x8e, 0x57, 0x1d, 0x36, 0xc9,
0x2c, 0x23, 0xf9, 0x92, 0xfd, 0x65, 0xba, 0x86, 0x08, 0xd5, 0x90, 0xcc, 0xb3, 0x28, 0x8f, 0xd9,
0xaf, 0xdd, 0x3c, 0xc3, 0xd9, 0xbf, 0xb1, 0xa3, 0x78, 0x19, 0xac, 0x1a, 0x74, 0xb5, 0x15, 0xc6,
0x0b, 0xad, 0x26, 0xc6, 0xc3, 0x8a, 0x9e, 0xc3, 0x7c, 0xe0, 0x5d, 0x8f, 0x81, 0x31, 0x66, 0xbb,
0x70, 0xff, 0xf0, 0x39, 0xa6, 0xe4, 0x6b, 0x4c, 0xc9, 0xf7, 0x98, 0x92, 0xa7, 0xdb, 0x56, 0xf8,
0x97, 0xbe, 0x2a, 0x6a, 0x2d, 0xcb, 0x46, 0xd7, 0xaf, 0x68, 0xf7, 0xc2, 0x8d, 0x28, 0xfd, 0xbb,
0x41, 0x57, 0xba, 0x37, 0x6e, 0x65, 0x69, 0x7b, 0xe5, 0x85, 0xc4, 0xbb, 0x49, 0xab, 0x45, 0x38,
0xe4, 0xcd, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x99, 0xa8, 0xd9, 0x9b, 0x58, 0x01, 0x00, 0x00,
}
+1
View File
@@ -9,6 +9,7 @@ message PluginSpec {
string remote = 2;
repeated PluginPrivilege privileges = 3;
bool disabled = 4;
repeated string env = 5;
}
// PluginPrivilege describes a permission the user has to accept
+80 -2
View File
@@ -10,6 +10,17 @@ type Service struct {
PreviousSpec *ServiceSpec `json:",omitempty"`
Endpoint Endpoint `json:",omitempty"`
UpdateStatus *UpdateStatus `json:",omitempty"`
// ServiceStatus is an optional, extra field indicating the number of
// desired and running tasks. It is provided primarily as a shortcut to
// calculating these values client-side, which otherwise would require
// listing all tasks for a service, an operation that could be
// computation and network expensive.
ServiceStatus *ServiceStatus `json:",omitempty"`
// JobStatus is the status of a Service which is in one of ReplicatedJob or
// GlobalJob modes. It is absent on Replicated and Global services.
JobStatus *JobStatus `json:",omitempty"`
}
// ServiceSpec represents the spec of a service.
@@ -32,8 +43,10 @@ type ServiceSpec struct {
// ServiceMode represents the mode of a service.
type ServiceMode struct {
Replicated *ReplicatedService `json:",omitempty"`
Global *GlobalService `json:",omitempty"`
Replicated *ReplicatedService `json:",omitempty"`
Global *GlobalService `json:",omitempty"`
ReplicatedJob *ReplicatedJob `json:",omitempty"`
GlobalJob *GlobalJob `json:",omitempty"`
}
// UpdateState is the state of a service update.
@@ -70,6 +83,32 @@ type ReplicatedService struct {
// GlobalService is a kind of ServiceMode.
type GlobalService struct{}
// ReplicatedJob is the a type of Service which executes a defined Tasks
// in parallel until the specified number of Tasks have succeeded.
type ReplicatedJob struct {
// MaxConcurrent indicates the maximum number of Tasks that should be
// executing simultaneously for this job at any given time. There may be
// fewer Tasks that MaxConcurrent executing simultaneously; for example, if
// there are fewer than MaxConcurrent tasks needed to reach
// TotalCompletions.
//
// If this field is empty, it will default to a max concurrency of 1.
MaxConcurrent *uint64 `json:",omitempty"`
// TotalCompletions is the total number of Tasks desired to run to
// completion.
//
// If this field is empty, the value of MaxConcurrent will be used.
TotalCompletions *uint64 `json:",omitempty"`
}
// GlobalJob is the type of a Service which executes a Task on every Node
// matching the Service's placement constraints. These tasks run to completion
// and then exit.
//
// This type is deliberately empty.
type GlobalJob struct{}
const (
// UpdateFailureActionPause PAUSE
UpdateFailureActionPause = "pause"
@@ -122,3 +161,42 @@ type UpdateConfig struct {
// started, or the new task is started before the old task is shut down.
Order string
}
// ServiceStatus represents the number of running tasks in a service and the
// number of tasks desired to be running.
type ServiceStatus struct {
// RunningTasks is the number of tasks for the service actually in the
// Running state
RunningTasks uint64
// DesiredTasks is the number of tasks desired to be running by the
// service. For replicated services, this is the replica count. For global
// services, this is computed by taking the number of tasks with desired
// state of not-Shutdown.
DesiredTasks uint64
// CompletedTasks is the number of tasks in the state Completed, if this
// service is in ReplicatedJob or GlobalJob mode. This field must be
// cross-referenced with the service type, because the default value of 0
// may mean that a service is not in a job mode, or it may mean that the
// job has yet to complete any tasks.
CompletedTasks uint64
}
// JobStatus is the status of a job-type service.
type JobStatus struct {
// JobIteration is a value increased each time a Job is executed,
// successfully or otherwise. "Executed", in this case, means the job as a
// whole has been started, not that an individual Task has been launched. A
// job is "Executed" when its ServiceSpec is updated. JobIteration can be
// used to disambiguate Tasks belonging to different executions of a job.
//
// Though JobIteration will increase with each subsequent execution, it may
// not necessarily increase by 1, and so JobIteration should not be used to
// keep track of the number of times a job has been executed.
JobIteration Version
// LastExecution is the time that the job was last executed, as observed by
// Swarm manager.
LastExecution time.Time `json:",omitempty"`
}
+21 -1
View File
@@ -1,6 +1,8 @@
package swarm // import "github.com/docker/docker/api/types/swarm"
import "time"
import (
"time"
)
// ClusterInfo represents info about the cluster for outputting in "info"
// it contains the same information as "Swarm", but without the JoinTokens
@@ -10,6 +12,9 @@ type ClusterInfo struct {
Spec Spec
TLSInfo TLSInfo
RootRotationInProgress bool
DefaultAddrPool []string
SubnetSize uint32
DataPathPort uint32
}
// Swarm represents a swarm.
@@ -149,10 +154,13 @@ type InitRequest struct {
ListenAddr string
AdvertiseAddr string
DataPathAddr string
DataPathPort uint32
ForceNewCluster bool
Spec Spec
AutoLockManagers bool
Availability NodeAvailability
DefaultAddrPool []string
SubnetSize uint32
}
// JoinRequest is the request used to join a swarm.
@@ -201,6 +209,18 @@ type Info struct {
Managers int `json:",omitempty"`
Cluster *ClusterInfo `json:",omitempty"`
Warnings []string `json:",omitempty"`
}
// Status provides information about the current swarm status and role,
// obtained from the "Swarm" header in the API response.
type Status struct {
// NodeState represents the state of the node.
NodeState LocalNodeState
// ControlAvailable indicates if the node is a swarm manager.
ControlAvailable bool
}
// Peer represents a peer.
+43 -6
View File
@@ -56,14 +56,28 @@ type Task struct {
DesiredState TaskState `json:",omitempty"`
NetworksAttachments []NetworkAttachment `json:",omitempty"`
GenericResources []GenericResource `json:",omitempty"`
// JobIteration is the JobIteration of the Service that this Task was
// spawned from, if the Service is a ReplicatedJob or GlobalJob. This is
// used to determine which Tasks belong to which run of the job. This field
// is absent if the Service mode is Replicated or Global.
JobIteration *Version `json:",omitempty"`
// Volumes is the list of VolumeAttachments for this task. It specifies
// which particular volumes are to be used by this particular task, and
// fulfilling what mounts in the spec.
Volumes []VolumeAttachment
}
// TaskSpec represents the spec of a task.
type TaskSpec struct {
// ContainerSpec and PluginSpec are mutually exclusive.
// PluginSpec will only be used when the `Runtime` field is set to `plugin`
ContainerSpec *ContainerSpec `json:",omitempty"`
PluginSpec *runtime.PluginSpec `json:",omitempty"`
// ContainerSpec, NetworkAttachmentSpec, and PluginSpec are mutually exclusive.
// PluginSpec is only used when the `Runtime` field is set to `plugin`
// NetworkAttachmentSpec is used if the `Runtime` field is set to
// `attachment`.
ContainerSpec *ContainerSpec `json:",omitempty"`
PluginSpec *runtime.PluginSpec `json:",omitempty"`
NetworkAttachmentSpec *NetworkAttachmentSpec `json:",omitempty"`
Resources *ResourceRequirements `json:",omitempty"`
RestartPolicy *RestartPolicy `json:",omitempty"`
@@ -82,13 +96,21 @@ type TaskSpec struct {
Runtime RuntimeType `json:",omitempty"`
}
// Resources represents resources (CPU/Memory).
// Resources represents resources (CPU/Memory) which can be advertised by a
// node and requested to be reserved for a task.
type Resources struct {
NanoCPUs int64 `json:",omitempty"`
MemoryBytes int64 `json:",omitempty"`
GenericResources []GenericResource `json:",omitempty"`
}
// Limit describes limits on resources which can be requested by a task.
type Limit struct {
NanoCPUs int64 `json:",omitempty"`
MemoryBytes int64 `json:",omitempty"`
Pids int64 `json:",omitempty"`
}
// GenericResource represents a "user defined" resource which can
// be either an integer (e.g: SSD=3) or a string (e.g: SSD=sda1)
type GenericResource struct {
@@ -116,7 +138,7 @@ type DiscreteGenericResource struct {
// ResourceRequirements represents resources requirements.
type ResourceRequirements struct {
Limits *Resources `json:",omitempty"`
Limits *Limit `json:",omitempty"`
Reservations *Resources `json:",omitempty"`
}
@@ -124,6 +146,7 @@ type ResourceRequirements struct {
type Placement struct {
Constraints []string `json:",omitempty"`
Preferences []PlacementPreference `json:",omitempty"`
MaxReplicas uint64 `json:",omitempty"`
// Platforms stores all the platforms that the image can run on.
// This field is used in the platform filter for scheduling. If empty,
@@ -186,3 +209,17 @@ type ContainerStatus struct {
type PortStatus struct {
Ports []PortConfig `json:",omitempty"`
}
// VolumeAttachment contains the associating a Volume to a Task.
type VolumeAttachment struct {
// ID is the Swarmkit ID of the Volume. This is not the CSI VolumeId.
ID string `json:",omitempty"`
// Source, together with Target, indicates the Mount, as specified in the
// ContainerSpec, that this volume fulfills.
Source string `json:",omitempty"`
// Target, together with Source, indicates the Mount, as specified
// in the ContainerSpec, that this volume fulfills.
Target string `json:",omitempty"`
}
-12
View File
@@ -1,12 +0,0 @@
package time // import "github.com/docker/docker/api/types/time"
import (
"strconv"
"time"
)
// DurationToSecondsString converts the specified duration to the number
// seconds it represents, formatted as a string.
func DurationToSecondsString(duration time.Duration) string {
return strconv.FormatFloat(duration.Seconds(), 'f', 0, 64)
}
+13 -4
View File
@@ -82,11 +82,14 @@ func GetTimestamp(value string, reference time.Time) (string, error) {
}
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, "-") {
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
@@ -97,13 +100,19 @@ func GetTimestamp(value string, reference time.Time) (string, error) {
// if the incoming nanosecond portion is longer or shorter than 9 digits it is
// converted to nanoseconds. The expectation is that the seconds and
// seconds will be used to create a time variable. For example:
// seconds, nanoseconds, err := ParseTimestamp("1136073600.000000001",0)
// if err == nil since := time.Unix(seconds, nanoseconds)
//
// seconds, nanoseconds, err := ParseTimestamp("1136073600.000000001",0)
// if err == nil since := time.Unix(seconds, nanoseconds)
//
// returns seconds as def(aultSeconds) if value == ""
func ParseTimestamps(value string, def int64) (int64, int64, error) {
if value == "" {
return def, 0, nil
}
return parseTimestamp(value)
}
func parseTimestamp(value string) (int64, int64, error) {
sa := strings.SplitN(value, ".", 2)
s, err := strconv.ParseInt(sa[0], 10, 64)
if err != nil {
+267 -45
View File
@@ -14,42 +14,136 @@ import (
"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/volume"
"github.com/docker/go-connections/nat"
)
const (
// MediaTypeRawStream is vendor specific MIME-Type set for raw TTY streams
MediaTypeRawStream = "application/vnd.docker.raw-stream"
// MediaTypeMultiplexedStream is vendor specific MIME-Type set for stdin/stdout/stderr multiplexed streams
MediaTypeMultiplexedStream = "application/vnd.docker.multiplexed-stream"
)
// RootFS returns Image's RootFS description including the layer IDs.
type RootFS struct {
Type string
Layers []string `json:",omitempty"`
BaseLayer string `json:",omitempty"`
Type string `json:",omitempty"`
Layers []string `json:",omitempty"`
}
// ImageInspect contains response of Engine API:
// GET "/images/{name:.*}/json"
type ImageInspect struct {
ID string `json:"Id"`
RepoTags []string
RepoDigests []string
Parent string
Comment string
Created string
Container string
// ID is the content-addressable ID of an image.
//
// This identifier is a content-addressable digest calculated from the
// image's configuration (which includes the digests of layers used by
// the image).
//
// Note that this digest differs from the `RepoDigests` below, which
// holds digests of image manifests that reference the image.
ID string `json:"Id"`
// RepoTags is a list of image names/tags in the local image cache that
// reference this image.
//
// Multiple image tags can refer to the same image, and this list may be
// empty if no tags reference the image, in which case the image is
// "untagged", in which case it can still be referenced by its ID.
RepoTags []string
// RepoDigests is a list of content-addressable digests of locally available
// image manifests that the image is referenced from. Multiple manifests can
// refer to the same image.
//
// These digests are usually only available if the image was either pulled
// from a registry, or if the image was pushed to a registry, which is when
// the manifest is generated and its digest calculated.
RepoDigests []string
// Parent is the ID of the parent image.
//
// Depending on how the image was created, this field may be empty and
// is only set for images that were built/created locally. This field
// is empty if the image was pulled from an image registry.
Parent string
// Comment is an optional message that can be set when committing or
// importing the image.
Comment string
// Created is the date and time at which the image was created, formatted in
// RFC 3339 nano-seconds (time.RFC3339Nano).
Created string
// Container is the ID of the container that was used to create the image.
//
// Depending on how the image was created, this field may be empty.
Container string
// ContainerConfig is an optional field containing the configuration of the
// container that was last committed when creating the image.
//
// Previous versions of Docker builder used this field to store build cache,
// and it is not in active use anymore.
ContainerConfig *container.Config
DockerVersion string
Author string
Config *container.Config
Architecture string
Os string
OsVersion string `json:",omitempty"`
Size int64
VirtualSize int64
GraphDriver GraphDriverData
RootFS RootFS
Metadata ImageMetadata
// DockerVersion is the version of Docker that was used to build the image.
//
// Depending on how the image was created, this field may be empty.
DockerVersion string
// Author is the name of the author that was specified when committing the
// image, or as specified through MAINTAINER (deprecated) in the Dockerfile.
Author string
Config *container.Config
// Architecture is the hardware CPU architecture that the image runs on.
Architecture string
// Variant is the CPU architecture variant (presently ARM-only).
Variant string `json:",omitempty"`
// OS is the Operating System the image is built to run on.
Os string
// OsVersion is the version of the Operating System the image is built to
// run on (especially for Windows).
OsVersion string `json:",omitempty"`
// Size is the total size of the image including all layers it is composed of.
Size int64
// VirtualSize is the total size of the image including all layers it is
// composed of.
//
// In versions of Docker before v1.10, this field was calculated from
// the image itself and all of its parent images. Docker v1.10 and up
// store images self-contained, and no longer use a parent-chain, making
// this field an equivalent of the Size field.
//
// This field is kept for backward compatibility, but may be removed in
// a future version of the API.
VirtualSize int64 // TODO(thaJeztah): deprecate this field
// GraphDriver holds information about the storage driver used to store the
// container's and image's filesystem.
GraphDriver GraphDriverData
// RootFS contains information about the image's RootFS, including the
// layer IDs.
RootFS RootFS
// Metadata of the image in the local cache.
//
// This information is local to the daemon, and not part of the image itself.
Metadata ImageMetadata
}
// ImageMetadata contains engine-local data about the image
type ImageMetadata struct {
// LastTagTime is the date and time at which the image was last tagged.
LastTagTime time.Time `json:",omitempty"`
}
@@ -102,9 +196,19 @@ type ContainerStats struct {
// Ping contains response of Engine API:
// GET "/_ping"
type Ping struct {
APIVersion string
OSType string
Experimental bool
APIVersion string
OSType string
Experimental bool
BuilderVersion BuilderVersion
// SwarmStatus provides information about the current swarm status of the
// engine, obtained from the "Swarm" header in the API response.
//
// It can be a nil struct if the API version does not provide this header
// in the ping response, or if an error occurred, in which case the client
// should use other ways to get the current swarm status, such as the /swarm
// endpoint.
SwarmStatus *swarm.Status
}
// ComponentVersion describes the version information for a specific component.
@@ -152,15 +256,17 @@ type Info struct {
Images int
Driver string
DriverStatus [][2]string
SystemStatus [][2]string
SystemStatus [][2]string `json:",omitempty"` // SystemStatus is only propagated by the Swarm standalone API
Plugins PluginsInfo
MemoryLimit bool
SwapLimit bool
KernelMemory 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"`
@@ -171,9 +277,11 @@ type Info struct {
SystemTime string
LoggingDriver string
CgroupDriver string
CgroupVersion string `json:",omitempty"`
NEventsListener int
KernelVersion string
OperatingSystem string
OSVersion string
OSType string
Architecture string
IndexServerAddress string
@@ -189,21 +297,29 @@ type Info struct {
Labels []string
ExperimentalBuild bool
ServerVersion string
ClusterStore string
ClusterAdvertise string
ClusterStore string `json:",omitempty"` // Deprecated: host-discovery and overlay networks with external k/v stores are deprecated
ClusterAdvertise string `json:",omitempty"` // Deprecated: host-discovery and overlay networks with external k/v stores are deprecated
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
LiveRestoreEnabled bool
Isolation container.Isolation
InitBinary string
ContainerdCommit Commit
RuncCommit Commit
InitCommit Commit
SecurityOptions []string
ProductLicense string `json:",omitempty"`
DefaultAddressPools []NetworkAddressPool `json:",omitempty"`
// 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
}
// KeyValue holds a key/value pair
@@ -211,6 +327,12 @@ 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
@@ -268,6 +390,8 @@ type ExecStartCheck struct {
Detach bool
// Check if there's a tty
Tty bool
// Terminal size [height, width], unused if Tty == false
ConsoleSize *[2]uint `json:",omitempty"`
}
// HealthcheckResult stores information about a single run of a healthcheck probe
@@ -311,7 +435,7 @@ type ContainerState struct {
}
// ContainerNode stores information about the node that a container
// is running on. It's only available in Docker Swarm
// is running on. It's only used by the Docker Swarm standalone API
type ContainerNode struct {
ID string
IPAddress string `json:"IP"`
@@ -335,7 +459,7 @@ type ContainerJSONBase struct {
HostnamePath string
HostsPath string
LogPath string
Node *ContainerNode `json:",omitempty"`
Node *ContainerNode `json:",omitempty"` // Node is only propagated by Docker Swarm standalone API
Name string
RestartCount int
Driver string
@@ -401,13 +525,44 @@ type DefaultNetworkSettings struct {
// MountPoint represents a mount point configuration inside the container.
// This is used for reporting the mountpoints in use by a container.
type MountPoint struct {
Type mount.Type `json:",omitempty"`
Name string `json:",omitempty"`
Source string
// Type is the type of mount, see `Type<foo>` definitions in
// github.com/docker/docker/api/types/mount.Type
Type mount.Type `json:",omitempty"`
// Name is the name reference to the underlying data defined by `Source`
// e.g., the volume name.
Name string `json:",omitempty"`
// Source is the source location of the mount.
//
// For volumes, this contains the storage location of the volume (within
// `/var/lib/docker/volumes/`). For bind-mounts, and `npipe`, this contains
// the source (host) part of the bind-mount. For `tmpfs` mount points, this
// field is empty.
Source string
// Destination is the path relative to the container root (`/`) where the
// Source is mounted inside the container.
Destination string
Driver string `json:",omitempty"`
Mode string
RW bool
// Driver is the volume driver used to create the volume (if it is a volume).
Driver string `json:",omitempty"`
// Mode is a comma separated list of options supplied by the user when
// creating the bind/volume mount.
//
// The default is platform-specific (`"z"` on Linux, empty on Windows).
Mode string
// RW indicates whether the mount is mounted writable (read-write).
RW bool
// Propagation describes how mounts are propagated from the host into the
// mount point, and vice-versa. Refer to the Linux kernel documentation
// for details:
// https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt
//
// This field is not used on Windows.
Propagation mount.Propagation
}
@@ -503,6 +658,37 @@ type Checkpoint struct {
type Runtime struct {
Path string `json:"path"`
Args []string `json:"runtimeArgs,omitempty"`
// This is exposed here only for internal use
// It is not currently supported to specify custom shim configs
Shim *ShimConfig `json:"-"`
}
// ShimConfig is used by runtime to configure containerd shims
type ShimConfig struct {
Binary string
Opts interface{}
}
// DiskUsageObject represents an object type used for disk usage query filtering.
type DiskUsageObject string
const (
// ContainerObject represents a container DiskUsageObject.
ContainerObject DiskUsageObject = "container"
// ImageObject represents an image DiskUsageObject.
ImageObject DiskUsageObject = "image"
// VolumeObject represents a volume DiskUsageObject.
VolumeObject DiskUsageObject = "volume"
// BuildCacheObject represents a build-cache DiskUsageObject.
BuildCacheObject DiskUsageObject = "build-cache"
)
// DiskUsageOptions holds parameters for system disk usage query.
type DiskUsageOptions struct {
// Types specifies what object types to include in the response. If empty,
// all object types are returned.
Types []DiskUsageObject
}
// DiskUsage contains response of Engine API:
@@ -511,8 +697,9 @@ type DiskUsage struct {
LayersSize int64
Images []*ImageSummary
Containers []*Container
Volumes []*Volume
BuilderSize int64
Volumes []*volume.Volume
BuildCache []*BuildCache
BuilderSize int64 `json:",omitempty"` // Deprecated: deprecated in API 1.38, and no longer used since API 1.40.
}
// ContainersPruneReport contains the response for Engine API:
@@ -539,6 +726,7 @@ type ImagesPruneReport struct {
// BuildCachePruneReport contains the response for Engine API:
// POST "/build/prune"
type BuildCachePruneReport struct {
CachesDeleted []string
SpaceReclaimed uint64
}
@@ -585,3 +773,37 @@ type PushResult struct {
type BuildResult struct {
ID string
}
// BuildCache contains information about a build cache record.
type BuildCache struct {
// ID is the unique ID of the build cache record.
ID string
// Parent is the ID of the parent build cache record.
//
// Deprecated: deprecated in API v1.42 and up, as it was deprecated in BuildKit; use Parents instead.
Parent string `json:"Parent,omitempty"`
// Parents is the list of parent build cache record IDs.
Parents []string `json:" Parents,omitempty"`
// Type is the cache record type.
Type string
// Description is a description of the build-step that produced the build cache.
Description string
// InUse indicates if the build cache is in use.
InUse bool
// Shared indicates if the build cache is shared.
Shared bool
// Size is the amount of disk space used by the build cache (in bytes).
Size int64
// CreatedAt is the date and time at which the build cache was created.
CreatedAt time.Time
// LastUsedAt is the date and time at which the build cache was last used.
LastUsedAt *time.Time
UsageCount int
}
// BuildCachePruneOptions hold parameters to prune the build cache
type BuildCachePruneOptions struct {
All bool
KeepStorage int64
Filters filters.Args
}
+3
View File
@@ -8,6 +8,9 @@ import (
// compare compares two version strings
// returns -1 if v1 < v2, 1 if v1 > v2, 0 otherwise.
func compare(v1, v2 string) int {
if v1 == v2 {
return 0
}
var (
currTab = strings.Split(v1, ".")
otherTab = strings.Split(v2, ".")
+420
View File
@@ -0,0 +1,420 @@
package volume
import (
"github.com/docker/docker/api/types/swarm"
)
// ClusterVolume contains options and information specific to, and only present
// on, Swarm CSI cluster volumes.
type ClusterVolume struct {
// ID is the Swarm ID of the volume. Because cluster volumes are Swarm
// objects, they have an ID, unlike non-cluster volumes, which only have a
// Name. This ID can be used to refer to the cluster volume.
ID string
// Meta is the swarm metadata about this volume.
swarm.Meta
// Spec is the cluster-specific options from which this volume is derived.
Spec ClusterVolumeSpec
// PublishStatus contains the status of the volume as it pertains to its
// publishing on Nodes.
PublishStatus []*PublishStatus `json:",omitempty"`
// Info is information about the global status of the volume.
Info *Info `json:",omitempty"`
}
// ClusterVolumeSpec contains the spec used to create this volume.
type ClusterVolumeSpec struct {
// Group defines the volume group of this volume. Volumes belonging to the
// same group can be referred to by group name when creating Services.
// Referring to a volume by group instructs swarm to treat volumes in that
// group interchangeably for the purpose of scheduling. Volumes with an
// empty string for a group technically all belong to the same, emptystring
// group.
Group string `json:",omitempty"`
// AccessMode defines how the volume is used by tasks.
AccessMode *AccessMode `json:",omitempty"`
// AccessibilityRequirements specifies where in the cluster a volume must
// be accessible from.
//
// This field must be empty if the plugin does not support
// VOLUME_ACCESSIBILITY_CONSTRAINTS capabilities. If it is present but the
// plugin does not support it, volume will not be created.
//
// If AccessibilityRequirements is empty, but the plugin does support
// VOLUME_ACCESSIBILITY_CONSTRAINTS, then Swarmkit will assume the entire
// cluster is a valid target for the volume.
AccessibilityRequirements *TopologyRequirement `json:",omitempty"`
// CapacityRange defines the desired capacity that the volume should be
// created with. If nil, the plugin will decide the capacity.
CapacityRange *CapacityRange `json:",omitempty"`
// Secrets defines Swarm Secrets that are passed to the CSI storage plugin
// when operating on this volume.
Secrets []Secret `json:",omitempty"`
// Availability is the Volume's desired availability. Analogous to Node
// Availability, this allows the user to take volumes offline in order to
// update or delete them.
Availability Availability `json:",omitempty"`
}
// Availability specifies the availability of the volume.
type Availability string
const (
// AvailabilityActive indicates that the volume is active and fully
// schedulable on the cluster.
AvailabilityActive Availability = "active"
// AvailabilityPause indicates that no new workloads should use the
// volume, but existing workloads can continue to use it.
AvailabilityPause Availability = "pause"
// AvailabilityDrain indicates that all workloads using this volume
// should be rescheduled, and the volume unpublished from all nodes.
AvailabilityDrain Availability = "drain"
)
// AccessMode defines the access mode of a volume.
type AccessMode struct {
// Scope defines the set of nodes this volume can be used on at one time.
Scope Scope `json:",omitempty"`
// Sharing defines the number and way that different tasks can use this
// volume at one time.
Sharing SharingMode `json:",omitempty"`
// MountVolume defines options for using this volume as a Mount-type
// volume.
//
// Either BlockVolume or MountVolume, but not both, must be present.
MountVolume *TypeMount `json:",omitempty"`
// BlockVolume defines options for using this volume as a Block-type
// volume.
//
// Either BlockVolume or MountVolume, but not both, must be present.
BlockVolume *TypeBlock `json:",omitempty"`
}
// Scope defines the Scope of a Cluster Volume. This is how many nodes a
// Volume can be accessed simultaneously on.
type Scope string
const (
// ScopeSingleNode indicates the volume can be used on one node at a
// time.
ScopeSingleNode Scope = "single"
// ScopeMultiNode indicates the volume can be used on many nodes at
// the same time.
ScopeMultiNode Scope = "multi"
)
// SharingMode defines the Sharing of a Cluster Volume. This is how Tasks using a
// Volume at the same time can use it.
type SharingMode string
const (
// SharingNone indicates that only one Task may use the Volume at a
// time.
SharingNone SharingMode = "none"
// SharingReadOnly indicates that the Volume may be shared by any
// number of Tasks, but they must be read-only.
SharingReadOnly SharingMode = "readonly"
// SharingOneWriter indicates that the Volume may be shared by any
// number of Tasks, but all after the first must be read-only.
SharingOneWriter SharingMode = "onewriter"
// SharingAll means that the Volume may be shared by any number of
// Tasks, as readers or writers.
SharingAll SharingMode = "all"
)
// TypeBlock defines options for using a volume as a block-type volume.
//
// Intentionally empty.
type TypeBlock struct{}
// TypeMount contains options for using a volume as a Mount-type
// volume.
type TypeMount struct {
// FsType specifies the filesystem type for the mount volume. Optional.
FsType string `json:",omitempty"`
// MountFlags defines flags to pass when mounting the volume. Optional.
MountFlags []string `json:",omitempty"`
}
// TopologyRequirement expresses the user's requirements for a volume's
// accessible topology.
type TopologyRequirement struct {
// Requisite specifies a list of Topologies, at least one of which the
// volume must be accessible from.
//
// Taken verbatim from the CSI Spec:
//
// Specifies the list of topologies the provisioned volume MUST be
// accessible from.
// This field is OPTIONAL. If TopologyRequirement is specified either
// requisite or preferred or both MUST be specified.
//
// If requisite is specified, the provisioned volume MUST be
// accessible from at least one of the requisite topologies.
//
// Given
// x = number of topologies provisioned volume is accessible from
// n = number of requisite topologies
// The CO MUST ensure n >= 1. The SP MUST ensure x >= 1
// If x==n, then the SP MUST make the provisioned volume available to
// all topologies from the list of requisite topologies. If it is
// unable to do so, the SP MUST fail the CreateVolume call.
// For example, if a volume should be accessible from a single zone,
// and requisite =
// {"region": "R1", "zone": "Z2"}
// then the provisioned volume MUST be accessible from the "region"
// "R1" and the "zone" "Z2".
// Similarly, if a volume should be accessible from two zones, and
// requisite =
// {"region": "R1", "zone": "Z2"},
// {"region": "R1", "zone": "Z3"}
// then the provisioned volume MUST be accessible from the "region"
// "R1" and both "zone" "Z2" and "zone" "Z3".
//
// If x<n, then the SP SHALL choose x unique topologies from the list
// of requisite topologies. If it is unable to do so, the SP MUST fail
// the CreateVolume call.
// For example, if a volume should be accessible from a single zone,
// and requisite =
// {"region": "R1", "zone": "Z2"},
// {"region": "R1", "zone": "Z3"}
// then the SP may choose to make the provisioned volume available in
// either the "zone" "Z2" or the "zone" "Z3" in the "region" "R1".
// Similarly, if a volume should be accessible from two zones, and
// requisite =
// {"region": "R1", "zone": "Z2"},
// {"region": "R1", "zone": "Z3"},
// {"region": "R1", "zone": "Z4"}
// then the provisioned volume MUST be accessible from any combination
// of two unique topologies: e.g. "R1/Z2" and "R1/Z3", or "R1/Z2" and
// "R1/Z4", or "R1/Z3" and "R1/Z4".
//
// If x>n, then the SP MUST make the provisioned volume available from
// all topologies from the list of requisite topologies and MAY choose
// the remaining x-n unique topologies from the list of all possible
// topologies. If it is unable to do so, the SP MUST fail the
// CreateVolume call.
// For example, if a volume should be accessible from two zones, and
// requisite =
// {"region": "R1", "zone": "Z2"}
// then the provisioned volume MUST be accessible from the "region"
// "R1" and the "zone" "Z2" and the SP may select the second zone
// independently, e.g. "R1/Z4".
Requisite []Topology `json:",omitempty"`
// Preferred is a list of Topologies that the volume should attempt to be
// provisioned in.
//
// Taken from the CSI spec:
//
// Specifies the list of topologies the CO would prefer the volume to
// be provisioned in.
//
// This field is OPTIONAL. If TopologyRequirement is specified either
// requisite or preferred or both MUST be specified.
//
// An SP MUST attempt to make the provisioned volume available using
// the preferred topologies in order from first to last.
//
// If requisite is specified, all topologies in preferred list MUST
// also be present in the list of requisite topologies.
//
// If the SP is unable to to make the provisioned volume available
// from any of the preferred topologies, the SP MAY choose a topology
// from the list of requisite topologies.
// If the list of requisite topologies is not specified, then the SP
// MAY choose from the list of all possible topologies.
// If the list of requisite topologies is specified and the SP is
// unable to to make the provisioned volume available from any of the
// requisite topologies it MUST fail the CreateVolume call.
//
// Example 1:
// Given a volume should be accessible from a single zone, and
// requisite =
// {"region": "R1", "zone": "Z2"},
// {"region": "R1", "zone": "Z3"}
// preferred =
// {"region": "R1", "zone": "Z3"}
// then the the SP SHOULD first attempt to make the provisioned volume
// available from "zone" "Z3" in the "region" "R1" and fall back to
// "zone" "Z2" in the "region" "R1" if that is not possible.
//
// Example 2:
// Given a volume should be accessible from a single zone, and
// requisite =
// {"region": "R1", "zone": "Z2"},
// {"region": "R1", "zone": "Z3"},
// {"region": "R1", "zone": "Z4"},
// {"region": "R1", "zone": "Z5"}
// preferred =
// {"region": "R1", "zone": "Z4"},
// {"region": "R1", "zone": "Z2"}
// then the the SP SHOULD first attempt to make the provisioned volume
// accessible from "zone" "Z4" in the "region" "R1" and fall back to
// "zone" "Z2" in the "region" "R1" if that is not possible. If that
// is not possible, the SP may choose between either the "zone"
// "Z3" or "Z5" in the "region" "R1".
//
// Example 3:
// Given a volume should be accessible from TWO zones (because an
// opaque parameter in CreateVolumeRequest, for example, specifies
// the volume is accessible from two zones, aka synchronously
// replicated), and
// requisite =
// {"region": "R1", "zone": "Z2"},
// {"region": "R1", "zone": "Z3"},
// {"region": "R1", "zone": "Z4"},
// {"region": "R1", "zone": "Z5"}
// preferred =
// {"region": "R1", "zone": "Z5"},
// {"region": "R1", "zone": "Z3"}
// then the the SP SHOULD first attempt to make the provisioned volume
// accessible from the combination of the two "zones" "Z5" and "Z3" in
// the "region" "R1". If that's not possible, it should fall back to
// a combination of "Z5" and other possibilities from the list of
// requisite. If that's not possible, it should fall back to a
// combination of "Z3" and other possibilities from the list of
// requisite. If that's not possible, it should fall back to a
// combination of other possibilities from the list of requisite.
Preferred []Topology `json:",omitempty"`
}
// Topology is a map of topological domains to topological segments.
//
// This description is taken verbatim from the CSI Spec:
//
// A topological domain is a sub-division of a cluster, like "region",
// "zone", "rack", etc.
// A topological segment is a specific instance of a topological domain,
// like "zone3", "rack3", etc.
// For example {"com.company/zone": "Z1", "com.company/rack": "R3"}
// Valid keys have two segments: an OPTIONAL prefix and name, separated
// by a slash (/), for example: "com.company.example/zone".
// The key name segment is REQUIRED. The prefix is OPTIONAL.
// The key name MUST be 63 characters or less, begin and end with an
// alphanumeric character ([a-z0-9A-Z]), and contain only dashes (-),
// underscores (_), dots (.), or alphanumerics in between, for example
// "zone".
// The key prefix MUST be 63 characters or less, begin and end with a
// lower-case alphanumeric character ([a-z0-9]), contain only
// dashes (-), dots (.), or lower-case alphanumerics in between, and
// follow domain name notation format
// (https://tools.ietf.org/html/rfc1035#section-2.3.1).
// The key prefix SHOULD include the plugin's host company name and/or
// the plugin name, to minimize the possibility of collisions with keys
// from other plugins.
// If a key prefix is specified, it MUST be identical across all
// topology keys returned by the SP (across all RPCs).
// Keys MUST be case-insensitive. Meaning the keys "Zone" and "zone"
// MUST not both exist.
// Each value (topological segment) MUST contain 1 or more strings.
// Each string MUST be 63 characters or less and begin and end with an
// alphanumeric character with '-', '_', '.', or alphanumerics in
// between.
type Topology struct {
Segments map[string]string `json:",omitempty"`
}
// CapacityRange describes the minimum and maximum capacity a volume should be
// created with
type CapacityRange struct {
// RequiredBytes specifies that a volume must be at least this big. The
// value of 0 indicates an unspecified minimum.
RequiredBytes int64
// LimitBytes specifies that a volume must not be bigger than this. The
// value of 0 indicates an unspecified maximum
LimitBytes int64
}
// Secret represents a Swarm Secret value that must be passed to the CSI
// storage plugin when operating on this Volume. It represents one key-value
// pair of possibly many.
type Secret struct {
// Key is the name of the key of the key-value pair passed to the plugin.
Key string
// Secret is the swarm Secret object from which to read data. This can be a
// Secret name or ID. The Secret data is retrieved by Swarm and used as the
// value of the key-value pair passed to the plugin.
Secret string
}
// PublishState represents the state of a Volume as it pertains to its
// use on a particular Node.
type PublishState string
const (
// StatePending indicates that the volume should be published on
// this node, but the call to ControllerPublishVolume has not been
// successfully completed yet and the result recorded by swarmkit.
StatePending PublishState = "pending-publish"
// StatePublished means the volume is published successfully to the node.
StatePublished PublishState = "published"
// StatePendingNodeUnpublish indicates that the Volume should be
// unpublished on the Node, and we're waiting for confirmation that it has
// done so. After the Node has confirmed that the Volume has been
// unpublished, the state will move to StatePendingUnpublish.
StatePendingNodeUnpublish PublishState = "pending-node-unpublish"
// StatePendingUnpublish means the volume is still published to the node
// by the controller, awaiting the operation to unpublish it.
StatePendingUnpublish PublishState = "pending-controller-unpublish"
)
// PublishStatus represents the status of the volume as published to an
// individual node
type PublishStatus struct {
// NodeID is the ID of the swarm node this Volume is published to.
NodeID string `json:",omitempty"`
// State is the publish state of the volume.
State PublishState `json:",omitempty"`
// PublishContext is the PublishContext returned by the CSI plugin when
// a volume is published.
PublishContext map[string]string `json:",omitempty"`
}
// Info contains information about the Volume as a whole as provided by
// the CSI storage plugin.
type Info struct {
// CapacityBytes is the capacity of the volume in bytes. A value of 0
// indicates that the capacity is unknown.
CapacityBytes int64 `json:",omitempty"`
// VolumeContext is the context originating from the CSI storage plugin
// when the Volume is created.
VolumeContext map[string]string `json:",omitempty"`
// VolumeID is the ID of the Volume as seen by the CSI storage plugin. This
// is distinct from the Volume's Swarm ID, which is the ID used by all of
// the Docker Engine to refer to the Volume. If this field is blank, then
// the Volume has not been successfully created yet.
VolumeID string `json:",omitempty"`
// AccessibleTopolgoy is the topology this volume is actually accessible
// from.
AccessibleTopology []Topology `json:",omitempty"`
}
+29
View File
@@ -0,0 +1,29 @@
package volume
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// CreateOptions VolumeConfig
//
// Volume configuration
// swagger:model CreateOptions
type CreateOptions struct {
// cluster volume spec
ClusterVolumeSpec *ClusterVolumeSpec `json:"ClusterVolumeSpec,omitempty"`
// Name of the volume driver to use.
Driver string `json:"Driver,omitempty"`
// A mapping of driver options and values. These options are
// passed directly to the driver and are driver specific.
//
DriverOpts map[string]string `json:"DriverOpts,omitempty"`
// User-defined key/value metadata.
Labels map[string]string `json:"Labels,omitempty"`
// The new volume's name. If not specified, Docker generates a name.
//
Name string `json:"Name,omitempty"`
}
+11
View File
@@ -0,0 +1,11 @@
package volume // import "github.com/docker/docker/api/types/volume"
// VolumeCreateBody Volume configuration
//
// Deprecated: use CreateOptions
type VolumeCreateBody = CreateOptions
// VolumeListOKBody Volume list response
//
// Deprecated: use ListResponse
type VolumeListOKBody = ListResponse
+18
View File
@@ -0,0 +1,18 @@
package volume
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// ListResponse VolumeListResponse
//
// Volume list response
// swagger:model ListResponse
type ListResponse struct {
// List of volumes
Volumes []*Volume `json:"Volumes"`
// Warnings that occurred when fetching the list of volumes.
//
Warnings []string `json:"Warnings"`
}
+8
View File
@@ -0,0 +1,8 @@
package volume // import "github.com/docker/docker/api/types/volume"
import "github.com/docker/docker/api/types/filters"
// ListOptions holds parameters to list volumes.
type ListOptions struct {
Filters filters.Args
}
@@ -1,4 +1,4 @@
package types
package volume
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
@@ -7,6 +7,9 @@ package types
// swagger:model Volume
type Volume struct {
// cluster volume
ClusterVolume *ClusterVolume `json:"ClusterVolume,omitempty"`
// Date/Time the volume was created.
CreatedAt string `json:"CreatedAt,omitempty"`
@@ -27,10 +30,13 @@ type Volume struct {
Name string `json:"Name"`
// The driver specific options used when creating the volume.
//
// Required: true
Options map[string]string `json:"Options"`
// The level at which the volume exists. Either `global` for cluster-wide, or `local` for machine level.
// The level at which the volume exists. Either `global` for cluster-wide,
// or `local` for machine level.
//
// Required: true
Scope string `json:"Scope"`
@@ -44,14 +50,14 @@ type Volume struct {
Status map[string]interface{} `json:"Status,omitempty"`
// usage data
UsageData *VolumeUsageData `json:"UsageData,omitempty"`
UsageData *UsageData `json:"UsageData,omitempty"`
}
// VolumeUsageData Usage details about the volume. This information is used by the
// UsageData Usage details about the volume. This information is used by the
// `GET /system/df` endpoint, and omitted in other endpoints.
//
// swagger:model VolumeUsageData
type VolumeUsageData struct {
// swagger:model UsageData
type UsageData struct {
// The number of containers referencing this volume. This field
// is set to `-1` if the reference-count is not available.
+7
View File
@@ -0,0 +1,7 @@
package volume // import "github.com/docker/docker/api/types/volume"
// UpdateOptions is configuration to update a Volume with.
type UpdateOptions struct {
// Spec is the ClusterVolumeSpec to update the volume to.
Spec *ClusterVolumeSpec `json:"Spec,omitempty"`
}
-29
View File
@@ -1,29 +0,0 @@
package volume // import "github.com/docker/docker/api/types/volume"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
// VolumesCreateBody volumes create body
// swagger:model VolumesCreateBody
type VolumesCreateBody struct {
// Name of the volume driver to use.
// Required: true
Driver string `json:"Driver"`
// A mapping of driver options and values. These options are passed directly to the driver and are driver specific.
// Required: true
DriverOpts map[string]string `json:"DriverOpts"`
// User-defined key/value metadata.
// Required: true
Labels map[string]string `json:"Labels"`
// The new volume's name. If not specified, Docker generates a name.
// Required: true
Name string `json:"Name"`
}
-23
View File
@@ -1,23 +0,0 @@
package volume // import "github.com/docker/docker/api/types/volume"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
import "github.com/docker/docker/api/types"
// VolumesListOKBody volumes list o k body
// swagger:model VolumesListOKBody
type VolumesListOKBody struct {
// List of volumes
// Required: true
Volumes []*types.Volume `json:"Volumes"`
// Warnings that occurred when fetching the list of volumes
// Required: true
Warnings []string `json:"Warnings"`
}
+1 -1
View File
@@ -16,7 +16,7 @@ import (
)
func main() {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
panic(err)
}
+16
View File
@@ -0,0 +1,16 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"net/url"
)
// BuildCancel requests the daemon to cancel the 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)
ensureReaderClosed(serverResp)
return err
}
+19 -4
View File
@@ -1,26 +1,41 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"fmt"
"net/url"
"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
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 {
return nil, err
}
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)
defer ensureReaderClosed(serverResp)
if err != nil {
return nil, err
}
defer ensureReaderClosed(serverResp)
if err := json.NewDecoder(serverResp.body).Decode(&report); err != nil {
return nil, fmt.Errorf("Error retrieving disk usage: %v", err)
+2 -1
View File
@@ -1,8 +1,9 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"github.com/docker/docker/api/types"
"golang.org/x/net/context"
)
// CheckpointCreate creates a checkpoint from the given container with the given name
+1 -1
View File
@@ -1,10 +1,10 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"net/url"
"github.com/docker/docker/api/types"
"golang.org/x/net/context"
)
// CheckpointDelete deletes the checkpoint with the given name from the given container
+3 -3
View File
@@ -1,11 +1,11 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"net/url"
"github.com/docker/docker/api/types"
"golang.org/x/net/context"
)
// CheckpointList returns the checkpoints of the given container in the docker host
@@ -18,11 +18,11 @@ func (cli *Client) CheckpointList(ctx context.Context, container string, options
}
resp, err := cli.get(ctx, "/containers/"+container+"/checkpoints", query, nil)
defer ensureReaderClosed(resp)
if err != nil {
return checkpoints, wrapResponseError(err, resp, "container", container)
return checkpoints, err
}
err = json.NewDecoder(resp.body).Decode(&checkpoints)
ensureReaderClosed(resp)
return checkpoints, err
}
+127 -204
View File
@@ -2,13 +2,13 @@
Package client is a Go client for the Docker Engine API.
For more information about the Engine API, see the documentation:
https://docs.docker.com/engine/reference/api/
https://docs.docker.com/engine/api/
Usage
# Usage
You use the library by creating a client object and calling methods on it. The
client can be created either from environment variables with NewEnvClient, or
configured manually with NewClient.
client can be created either from environment variables with NewClientWithOpts(client.FromEnv),
or configured manually with NewClient().
For example, to list running containers (the equivalent of "docker ps"):
@@ -23,7 +23,7 @@ For example, to list running containers (the equivalent of "docker ps"):
)
func main() {
cli, err := client.NewEnvClient()
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
panic(err)
}
@@ -37,27 +37,22 @@ For example, to list running containers (the equivalent of "docker ps"):
fmt.Printf("%s %s\n", container.ID[:10], container.Image)
}
}
*/
package client // import "github.com/docker/docker/client"
import (
"fmt"
"context"
"net"
"net/http"
"net/url"
"os"
"path"
"path/filepath"
"strings"
"github.com/docker/docker/api"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/versions"
"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.
@@ -84,18 +79,30 @@ type Client struct {
customHTTPHeaders map[string]string
// manualOverride is set to true when the version was set by users.
manualOverride bool
// negotiateVersion indicates if the client should automatically negotiate
// the API version to use when making requests. API version negotiation is
// performed on the first request, after which negotiated is set to "true"
// so that subsequent requests do not re-negotiate.
negotiateVersion bool
// negotiated indicates that API version negotiation took place
negotiated bool
}
// CheckRedirect specifies the policy for dealing with redirect responses:
// If the request is non-GET return `ErrRedirect`. Otherwise use the last response.
// If the request is non-GET return ErrRedirect, otherwise use the last response.
//
// Go 1.8 changes behavior for HTTP redirects (specifically 301, 307, and 308) in the client .
// The Docker client (and by extension docker API client) can be made to to send a request
// like POST /containers//start where what would normally be in the name section of the URL is empty.
// This triggers an HTTP 301 from the daemon.
// In go 1.8 this 301 will be converted to a GET request, and ends up getting a 404 from the daemon.
// This behavior change manifests in the client in that before the 301 was not followed and
// the client did not generate an error, but now results in a message like Error response from daemon: page not found.
// Go 1.8 changes behavior for HTTP redirects (specifically 301, 307, and 308)
// in the client. The Docker client (and by extension docker API client) can be
// made to send a request like POST /containers//start where what would normally
// be in the name section of the URL is empty. This triggers an HTTP 301 from
// the daemon.
//
// In go 1.8 this 301 will be converted to a GET request, and ends up getting
// a 404 from the daemon. This behavior change manifests in the client in that
// before, the 301 was not followed and the client did not generate an error,
// but now results in a message like Error response from daemon: page not found.
func CheckRedirect(req *http.Request, via []*http.Request) error {
if via[0].Method == http.MethodGet {
return http.ErrUseLastResponse
@@ -103,138 +110,21 @@ func CheckRedirect(req *http.Request, via []*http.Request) error {
return ErrRedirect
}
// NewEnvClient initializes a new API client based on environment variables.
// See FromEnv for a list of support environment variables.
// NewClientWithOpts initializes a new API client with a default HTTPClient, and
// default API host and version. It also initializes the custom HTTP headers to
// add to each request.
//
// Deprecated: use NewClientWithOpts(FromEnv)
func NewEnvClient() (*Client, error) {
return NewClientWithOpts(FromEnv)
}
// FromEnv configures the client with values from environment variables.
// It takes an optional list of Opt functional arguments, which are applied in
// the order they're provided, which allows modifying the defaults when creating
// the client. For example, the following initializes a client that configures
// itself with values from environment variables (client.FromEnv), and has
// automatic API version negotiation enabled (client.WithAPIVersionNegotiation()).
//
// Supported environment variables:
// DOCKER_HOST to set the url to the docker server.
// DOCKER_API_VERSION to set the version of the API to reach, leave empty for latest.
// DOCKER_CERT_PATH to load the TLS certificates from.
// DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default.
func FromEnv(c *Client) error {
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 err
}
c.client = &http.Client{
Transport: &http.Transport{TLSClientConfig: tlsc},
CheckRedirect: CheckRedirect,
}
}
if host := os.Getenv("DOCKER_HOST"); host != "" {
if err := WithHost(host)(c); err != nil {
return err
}
}
if version := os.Getenv("DOCKER_API_VERSION"); version != "" {
c.version = version
c.manualOverride = true
}
return nil
}
// WithTLSClientConfig applies a tls config to the client transport.
func WithTLSClientConfig(cacertPath, certPath, keyPath string) func(*Client) error {
return func(c *Client) error {
opts := tlsconfig.Options{
CAFile: cacertPath,
CertFile: certPath,
KeyFile: keyPath,
ExclusiveRootPools: true,
}
config, err := tlsconfig.Client(opts)
if err != nil {
return errors.Wrap(err, "failed to create tls config")
}
if transport, ok := c.client.Transport.(*http.Transport); ok {
transport.TLSClientConfig = config
return nil
}
return errors.Errorf("cannot apply tls config to transport: %T", c.client.Transport)
}
}
// WithDialer applies the dialer.DialContext to the client transport. This can be
// used to set the Timeout and KeepAlive settings of the client.
func WithDialer(dialer *net.Dialer) func(*Client) error {
return func(c *Client) error {
if transport, ok := c.client.Transport.(*http.Transport); ok {
transport.DialContext = dialer.DialContext
return nil
}
return errors.Errorf("cannot apply dialer to transport: %T", c.client.Transport)
}
}
// WithVersion overrides the client version with the specified one
func WithVersion(version string) func(*Client) error {
return func(c *Client) error {
c.version = version
return nil
}
}
// WithHost overrides the client host with the specified one.
func WithHost(host string) func(*Client) error {
return func(c *Client) error {
hostURL, err := ParseHostURL(host)
if err != nil {
return err
}
c.host = host
c.proto = hostURL.Scheme
c.addr = hostURL.Host
c.basePath = hostURL.Path
if transport, ok := c.client.Transport.(*http.Transport); ok {
return sockets.ConfigureTransport(transport, c.proto, c.addr)
}
return errors.Errorf("cannot apply host to transport: %T", c.client.Transport)
}
}
// WithHTTPClient overrides the client http client with the specified one
func WithHTTPClient(client *http.Client) func(*Client) error {
return func(c *Client) error {
if client != nil {
c.client = client
}
return nil
}
}
// WithHTTPHeaders overrides the client default http headers
func WithHTTPHeaders(headers map[string]string) func(*Client) error {
return func(c *Client) error {
c.customHTTPHeaders = headers
return nil
}
}
// NewClientWithOpts initializes a new API client with default values. It takes functors
// to modify values when creating it, like `NewClientWithOpts(WithVersion(…))`
// 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.
func NewClientWithOpts(ops ...func(*Client) error) (*Client, error) {
// cli, err := client.NewClientWithOpts(
// client.FromEnv,
// client.WithAPIVersionNegotiation(),
// )
func NewClientWithOpts(ops ...Opt) (*Client, error) {
client, err := defaultHTTPClient(DefaultDockerHost)
if err != nil {
return nil, err
@@ -242,7 +132,6 @@ func NewClientWithOpts(ops ...func(*Client) error) (*Client, error) {
c := &Client{
host: DefaultDockerHost,
version: api.DefaultVersion,
scheme: "http",
client: client,
proto: defaultProto,
addr: defaultAddr,
@@ -254,47 +143,36 @@ func NewClientWithOpts(ops ...func(*Client) error) (*Client, error) {
}
}
if _, ok := c.client.Transport.(http.RoundTripper); !ok {
return nil, fmt.Errorf("unable to verify TLS configuration, invalid transport %v", c.client.Transport)
}
tlsConfig := resolveTLSConfig(c.client.Transport)
if tlsConfig != nil {
// 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"
if c.scheme == "" {
c.scheme = "http"
tlsConfig := resolveTLSConfig(c.client.Transport)
if tlsConfig != nil {
// 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"
}
}
return c, nil
}
func defaultHTTPClient(host string) (*http.Client, error) {
url, err := ParseHostURL(host)
hostURL, err := ParseHostURL(host)
if err != nil {
return nil, err
}
transport := new(http.Transport)
sockets.ConfigureTransport(transport, url.Scheme, url.Host)
transport := &http.Transport{}
_ = sockets.ConfigureTransport(transport, hostURL.Scheme, hostURL.Host)
return &http.Client{
Transport: transport,
CheckRedirect: CheckRedirect,
}, 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 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))
}
// Close the transport used by the client
func (cli *Client) Close() error {
if t, ok := cli.client.Transport.(*http.Transport); ok {
@@ -305,8 +183,11 @@ func (cli *Client) Close() error {
// getAPIPath returns the versioned request path to call the api.
// It appends the query parameters to the path if they are not empty.
func (cli *Client) getAPIPath(p string, query url.Values) string {
func (cli *Client) getAPIPath(ctx context.Context, p string, query url.Values) string {
var apiPath string
if cli.negotiateVersion && !cli.negotiated {
cli.NegotiateAPIVersion(ctx)
}
if cli.version != "" {
v := strings.TrimPrefix(cli.version, "v")
apiPath = path.Join(cli.basePath, "/v"+v, p)
@@ -321,23 +202,53 @@ func (cli *Client) ClientVersion() string {
return cli.version
}
// NegotiateAPIVersion queries the API and updates the version to match the
// API version. Any errors are silently ignored.
// NegotiateAPIVersion queries the API and updates the version to match the API
// version. NegotiateAPIVersion downgrades the client's API version to match the
// APIVersion if the ping version is lower than the default version. If the API
// version reported by the server is higher than the maximum version supported
// by the client, it uses the client's maximum version.
//
// If a manual override is in place, either through the "DOCKER_API_VERSION"
// (EnvOverrideAPIVersion) environment variable, or if the client is initialized
// with a fixed version (WithVersion(xx)), no negotiation is performed.
//
// If the API server's ping response does not contain an API version, or if the
// client did not get a successful ping response, it assumes it is connected with
// an old daemon that does not support API version negotiation, in which case it
// downgrades to the latest version of the API before version negotiation was
// added (1.24).
func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
ping, _ := cli.Ping(ctx)
cli.NegotiateAPIVersionPing(ping)
if !cli.manualOverride {
ping, _ := cli.Ping(ctx)
cli.negotiateAPIVersionPing(ping)
}
}
// NegotiateAPIVersionPing updates the client version to match the Ping.APIVersion
// if the ping version is less than the default version.
func (cli *Client) NegotiateAPIVersionPing(p types.Ping) {
if cli.manualOverride {
return
// NegotiateAPIVersionPing downgrades the client's API version to match the
// APIVersion in the ping response. If the API version in pingResponse is higher
// than the maximum version supported by the client, it uses the client's maximum
// version.
//
// If a manual override is in place, either through the "DOCKER_API_VERSION"
// (EnvOverrideAPIVersion) environment variable, or if the client is initialized
// with a fixed version (WithVersion(xx)), no negotiation is performed.
//
// If the API server's ping response does not contain an API version, we assume
// we are connected with an old daemon without API version negotiation support,
// and downgrade to the latest version of the API before version negotiation was
// added (1.24).
func (cli *Client) NegotiateAPIVersionPing(pingResponse types.Ping) {
if !cli.manualOverride {
cli.negotiateAPIVersionPing(pingResponse)
}
}
// try the latest version before versioning headers existed
if p.APIVersion == "" {
p.APIVersion = "1.24"
// negotiateAPIVersionPing queries the API and updates the version to match the
// API version from the ping response.
func (cli *Client) negotiateAPIVersionPing(pingResponse types.Ping) {
// default to the latest version before versioning headers existed
if pingResponse.APIVersion == "" {
pingResponse.APIVersion = "1.24"
}
// if the client is not initialized with a version, start with the latest supported version
@@ -346,8 +257,14 @@ func (cli *Client) NegotiateAPIVersionPing(p types.Ping) {
}
// if server version is lower than the client version, downgrade
if versions.LessThan(p.APIVersion, cli.version) {
cli.version = p.APIVersion
if versions.LessThan(pingResponse.APIVersion, cli.version) {
cli.version = pingResponse.APIVersion
}
// Store the results, so that automatic API version negotiation (if enabled)
// won't be performed on the next request.
if cli.negotiateVersion {
cli.negotiated = true
}
}
@@ -356,12 +273,18 @@ func (cli *Client) DaemonHost() string {
return cli.host
}
// HTTPClient returns a copy of the HTTP client bound to the server
func (cli *Client) HTTPClient() *http.Client {
c := *cli.client
return &c
}
// ParseHostURL parses a url string, validates the string is a host url, and
// returns the parsed URL
func ParseHostURL(host string) (*url.URL, error) {
protoAddrParts := strings.SplitN(host, "://", 2)
if len(protoAddrParts) == 1 {
return nil, fmt.Errorf("unable to parse docker host `%s`", host)
return nil, errors.Errorf("unable to parse docker host `%s`", host)
}
var basePath string
@@ -381,17 +304,17 @@ func ParseHostURL(host string) (*url.URL, error) {
}, nil
}
// CustomHTTPHeaders returns the custom http headers stored by the client.
func (cli *Client) CustomHTTPHeaders() map[string]string {
m := make(map[string]string)
for k, v := range cli.customHTTPHeaders {
m[k] = v
// Dialer returns a dialer for a raw stream connection, with an 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))
}
return m
}
// 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) {
cli.customHTTPHeaders = headers
}
+23
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)
}
+4 -2
View File
@@ -1,8 +1,10 @@
// +build linux freebsd openbsd darwin
//go:build linux || freebsd || openbsd || netbsd || darwin || solaris || illumos || dragonfly
// +build linux freebsd openbsd netbsd darwin solaris illumos dragonfly
package client // import "github.com/docker/docker/client"
// DefaultDockerHost defines os specific default if DOCKER_HOST is unset
// DefaultDockerHost defines OS-specific default host if the DOCKER_HOST
// (EnvOverrideHost) environment variable is unset or empty.
const DefaultDockerHost = "unix:///var/run/docker.sock"
const defaultProto = "unix"
+2 -1
View File
@@ -1,6 +1,7 @@
package client // import "github.com/docker/docker/client"
// DefaultDockerHost defines os specific default if DOCKER_HOST is unset
// DefaultDockerHost defines OS-specific default host if the DOCKER_HOST
// (EnvOverrideHost) environment variable is unset or empty.
const DefaultDockerHost = "npipe:////./pipe/docker_engine"
const defaultProto = "npipe"
+3 -3
View File
@@ -1,25 +1,25 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context"
)
// ConfigCreate creates a new Config.
// ConfigCreate creates a new config.
func (cli *Client) ConfigCreate(ctx context.Context, config swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
var response types.ConfigCreateResponse
if err := cli.NewVersionError("1.30", "config create"); err != nil {
return response, err
}
resp, err := cli.post(ctx, "/configs/create", nil, config, nil)
defer ensureReaderClosed(resp)
if err != nil {
return response, err
}
err = json.NewDecoder(resp.body).Decode(&response)
ensureReaderClosed(resp)
return response, err
}
+6 -6
View File
@@ -2,11 +2,11 @@ package client // import "github.com/docker/docker/client"
import (
"bytes"
"context"
"encoding/json"
"io/ioutil"
"io"
"github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context"
)
// ConfigInspectWithRaw returns the config information with raw data
@@ -18,12 +18,12 @@ func (cli *Client) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.C
return swarm.Config{}, nil, err
}
resp, err := cli.get(ctx, "/configs/"+id, nil, nil)
if err != nil {
return swarm.Config{}, nil, wrapResponseError(err, resp, "config", id)
}
defer ensureReaderClosed(resp)
if err != nil {
return swarm.Config{}, nil, err
}
body, err := ioutil.ReadAll(resp.body)
body, err := io.ReadAll(resp.body)
if err != nil {
return swarm.Config{}, nil, err
}
+2 -2
View File
@@ -1,13 +1,13 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"net/url"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context"
)
// ConfigList returns the list of configs.
@@ -27,12 +27,12 @@ func (cli *Client) ConfigList(ctx context.Context, options types.ConfigListOptio
}
resp, err := cli.get(ctx, "/configs", query, nil)
defer ensureReaderClosed(resp)
if err != nil {
return nil, err
}
var configs []swarm.Config
err = json.NewDecoder(resp.body).Decode(&configs)
ensureReaderClosed(resp)
return configs, err
}
+4 -4
View File
@@ -1,13 +1,13 @@
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 {
if err := cli.NewVersionError("1.30", "config remove"); err != nil {
return err
}
resp, err := cli.delete(ctx, "/configs/"+id, nil, nil)
ensureReaderClosed(resp)
return wrapResponseError(err, resp, "config", id)
defer ensureReaderClosed(resp)
return err
}
+3 -4
View File
@@ -1,20 +1,19 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"net/url"
"strconv"
"github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context"
)
// ConfigUpdate attempts to update a Config
// ConfigUpdate attempts to update a config
func (cli *Client) ConfigUpdate(ctx context.Context, id string, version swarm.Version, config swarm.ConfigSpec) error {
if err := cli.NewVersionError("1.30", "config update"); err != nil {
return err
}
query := url.Values{}
query.Set("version", strconv.FormatUint(version.Index, 10))
query.Set("version", version.String())
resp, err := cli.post(ctx, "/configs/"+id+"/update", query, config, nil)
ensureReaderClosed(resp)
return err
+5 -3
View File
@@ -1,10 +1,10 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"net/url"
"github.com/docker/docker/api/types"
"golang.org/x/net/context"
)
// ContainerAttach attaches a connection to a container in the server.
@@ -22,7 +22,7 @@ import (
// multiplexed.
// The format of the multiplexed stream is as follows:
//
// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
//
// STREAM_TYPE can be 1 for stdout and 2 for stderr
//
@@ -52,6 +52,8 @@ func (cli *Client) ContainerAttach(ctx context.Context, container string, option
query.Set("logs", "1")
}
headers := map[string][]string{"Content-Type": {"text/plain"}}
headers := map[string][]string{
"Content-Type": {"text/plain"},
}
return cli.postHijacked(ctx, "/containers/"+container+"/attach", query, nil, headers)
}
+3 -3
View File
@@ -1,16 +1,16 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"errors"
"net/url"
"github.com/docker/distribution/reference"
"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 to a container and creates a new tagged image.
func (cli *Client) ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.IDResponse, error) {
var repository, tag string
if options.Reference != "" {
@@ -45,11 +45,11 @@ func (cli *Client) ContainerCommit(ctx context.Context, container string, option
var response types.IDResponse
resp, err := cli.post(ctx, "/commit", query, options.Config, nil)
defer ensureReaderClosed(resp)
if err != nil {
return response, err
}
err = json.NewDecoder(resp.body).Decode(&response)
ensureReaderClosed(resp)
return response, err
}
+8 -17
View File
@@ -1,6 +1,7 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
@@ -10,22 +11,20 @@ import (
"path/filepath"
"strings"
"golang.org/x/net/context"
"github.com/docker/docker/api/types"
)
// ContainerStatPath returns Stat information about a path inside the container filesystem.
// ContainerStatPath returns stat information about a path inside the container filesystem.
func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path string) (types.ContainerPathStat, error) {
query := url.Values{}
query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API.
urlStr := "/containers/" + containerID + "/archive"
response, err := cli.head(ctx, urlStr, query, nil)
if err != nil {
return types.ContainerPathStat{}, wrapResponseError(err, response, "container:path", containerID+":"+path)
}
defer ensureReaderClosed(response)
if err != nil {
return types.ContainerPathStat{}, err
}
return getContainerPathStatFromHeader(response.header)
}
@@ -46,13 +45,9 @@ func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath str
apiPath := "/containers/" + containerID + "/archive"
response, err := cli.putRaw(ctx, apiPath, query, content, nil)
if err != nil {
return wrapResponseError(err, response, "container:path", containerID+":"+dstPath)
}
defer ensureReaderClosed(response)
if response.statusCode != http.StatusOK {
return fmt.Errorf("unexpected status code from daemon: %d", response.statusCode)
if err != nil {
return err
}
return nil
@@ -67,11 +62,7 @@ func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath s
apiPath := "/containers/" + containerID + "/archive"
response, err := cli.get(ctx, apiPath, query, nil)
if err != nil {
return nil, types.ContainerPathStat{}, wrapResponseError(err, response, "container:path", containerID+":"+srcPath)
}
if response.statusCode != http.StatusOK {
return nil, types.ContainerPathStat{}, fmt.Errorf("unexpected status code from daemon: %d", response.statusCode)
return nil, types.ContainerPathStat{}, err
}
// In order to get the copy behavior right, we need to know information
+39 -12
View File
@@ -1,14 +1,15 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"net/url"
"strings"
"path"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/versions"
"golang.org/x/net/context"
specs "github.com/opencontainers/image-spec/specs-go/v1"
)
type configWrapper struct {
@@ -17,21 +18,38 @@ type configWrapper struct {
NetworkingConfig *network.NetworkingConfig
}
// ContainerCreate creates a new container based in the given configuration.
// ContainerCreate creates a new container based on the given configuration.
// It can be associated with a name, but it's not mandatory.
func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (container.ContainerCreateCreatedBody, error) {
var response container.ContainerCreateCreatedBody
func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (container.CreateResponse, error) {
var response container.CreateResponse
if err := cli.NewVersionError("1.25", "stop timeout"); config != nil && config.StopTimeout != nil && err != nil {
return response, err
}
if err := cli.NewVersionError("1.41", "specify container image platform"); platform != nil && err != nil {
return response, err
}
// When using API 1.24 and under, the client is responsible for removing the container
if hostConfig != nil && versions.LessThan(cli.ClientVersion(), "1.25") {
hostConfig.AutoRemove = false
if hostConfig != nil {
if versions.LessThan(cli.ClientVersion(), "1.25") {
// When using API 1.24 and under, the client is responsible for removing the container
hostConfig.AutoRemove = false
}
if versions.GreaterThanOrEqualTo(cli.ClientVersion(), "1.42") || versions.LessThan(cli.ClientVersion(), "1.40") {
// KernelMemory was added in API 1.40, and deprecated in API 1.42
hostConfig.KernelMemory = 0
}
if platform != nil && platform.OS == "linux" && versions.LessThan(cli.ClientVersion(), "1.42") {
// When using API under 1.42, the Linux daemon doesn't respect the ConsoleSize
hostConfig.ConsoleSize = [2]uint{0, 0}
}
}
query := url.Values{}
if p := formatPlatform(platform); p != "" {
query.Set("platform", p)
}
if containerName != "" {
query.Set("name", containerName)
}
@@ -43,14 +61,23 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config
}
serverResp, err := cli.post(ctx, "/containers/create", query, body, nil)
defer ensureReaderClosed(serverResp)
if err != nil {
if serverResp.statusCode == 404 && strings.Contains(err.Error(), "No such image") {
return response, objectNotFoundError{object: "image", id: config.Image}
}
return response, err
}
err = json.NewDecoder(serverResp.body).Decode(&response)
ensureReaderClosed(serverResp)
return response, err
}
// formatPlatform returns a formatted string representing platform (e.g. linux/arm/v7).
//
// Similar to containerd's platforms.Format(), but does allow components to be
// omitted (e.g. pass "architecture" only, without "os":
// https://github.com/containerd/containerd/blob/v1.5.2/platforms/platforms.go#L243-L263
func formatPlatform(platform *specs.Platform) string {
if platform == nil {
return ""
}
return path.Join(platform.OS, platform.Architecture, platform.Variant)
}
+2 -2
View File
@@ -1,11 +1,11 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"net/url"
"github.com/docker/docker/api/types/container"
"golang.org/x/net/context"
)
// ContainerDiff shows differences in a container filesystem since it was started.
@@ -13,11 +13,11 @@ func (cli *Client) ContainerDiff(ctx context.Context, containerID string) ([]con
var changes []container.ContainerChangeResponseItem
serverResp, err := cli.get(ctx, "/containers/"+containerID+"/changes", url.Values{}, nil)
defer ensureReaderClosed(serverResp)
if err != nil {
return changes, err
}
err = json.NewDecoder(serverResp.body).Decode(&changes)
ensureReaderClosed(serverResp)
return changes, err
}
+15 -3
View File
@@ -1,10 +1,11 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"github.com/docker/docker/api/types"
"golang.org/x/net/context"
"github.com/docker/docker/api/types/versions"
)
// ContainerExecCreate creates a new exec configuration to run an exec process.
@@ -14,18 +15,24 @@ func (cli *Client) ContainerExecCreate(ctx context.Context, container string, co
if err := cli.NewVersionError("1.25", "env"); len(config.Env) != 0 && err != nil {
return response, err
}
if versions.LessThan(cli.ClientVersion(), "1.42") {
config.ConsoleSize = nil
}
resp, err := cli.post(ctx, "/containers/"+container+"/exec", nil, config, nil)
defer ensureReaderClosed(resp)
if err != nil {
return response, err
}
err = json.NewDecoder(resp.body).Decode(&response)
ensureReaderClosed(resp)
return response, err
}
// ContainerExecStart starts an exec process already created in the docker host.
func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error {
if versions.LessThan(cli.ClientVersion(), "1.42") {
config.ConsoleSize = nil
}
resp, err := cli.post(ctx, "/exec/"+execID+"/start", nil, config, nil)
ensureReaderClosed(resp)
return err
@@ -36,7 +43,12 @@ func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config
// and the a reader to get output. It's up to the called to close
// the hijacked connection by calling types.HijackedResponse.Close.
func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error) {
headers := map[string][]string{"Content-Type": {"application/json"}}
if versions.LessThan(cli.ClientVersion(), "1.42") {
config.ConsoleSize = nil
}
headers := map[string][]string{
"Content-Type": {"application/json"},
}
return cli.postHijacked(ctx, "/exec/"+execID+"/start", nil, config, headers)
}
+1 -2
View File
@@ -1,10 +1,9 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"io"
"net/url"
"golang.org/x/net/context"
)
// ContainerExport retrieves the raw contents of a container
+8 -8
View File
@@ -2,12 +2,12 @@ package client // import "github.com/docker/docker/client"
import (
"bytes"
"context"
"encoding/json"
"io/ioutil"
"io"
"net/url"
"github.com/docker/docker/api/types"
"golang.org/x/net/context"
)
// ContainerInspect returns the container information.
@@ -16,13 +16,13 @@ func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (ty
return types.ContainerJSON{}, objectNotFoundError{object: "container", id: containerID}
}
serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil)
defer ensureReaderClosed(serverResp)
if err != nil {
return types.ContainerJSON{}, wrapResponseError(err, serverResp, "container", containerID)
return types.ContainerJSON{}, err
}
var response types.ContainerJSON
err = json.NewDecoder(serverResp.body).Decode(&response)
ensureReaderClosed(serverResp)
return response, err
}
@@ -36,12 +36,12 @@ func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID stri
query.Set("size", "1")
}
serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", query, nil)
if err != nil {
return types.ContainerJSON{}, nil, wrapResponseError(err, serverResp, "container", containerID)
}
defer ensureReaderClosed(serverResp)
if err != nil {
return types.ContainerJSON{}, nil, err
}
body, err := ioutil.ReadAll(serverResp.body)
body, err := io.ReadAll(serverResp.body)
if err != nil {
return types.ContainerJSON{}, nil, err
}
+4 -3
View File
@@ -1,15 +1,16 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"net/url"
"golang.org/x/net/context"
)
// ContainerKill terminates the container process but does not remove the container from the docker host.
func (cli *Client) ContainerKill(ctx context.Context, containerID, signal string) error {
query := url.Values{}
query.Set("signal", signal)
if signal != "" {
query.Set("signal", signal)
}
resp, err := cli.post(ctx, "/containers/"+containerID+"/kill", query, nil, nil)
ensureReaderClosed(resp)
+4 -3
View File
@@ -1,13 +1,13 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"net/url"
"strconv"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"golang.org/x/net/context"
)
// ContainerList returns the list of containers in the docker host.
@@ -18,7 +18,7 @@ func (cli *Client) ContainerList(ctx context.Context, options types.ContainerLis
query.Set("all", "1")
}
if options.Limit != -1 {
if options.Limit > 0 {
query.Set("limit", strconv.Itoa(options.Limit))
}
@@ -35,6 +35,7 @@ func (cli *Client) ContainerList(ctx context.Context, options types.ContainerLis
}
if options.Filters.Len() > 0 {
//nolint:staticcheck // ignore SA1019 for old code
filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters)
if err != nil {
@@ -45,12 +46,12 @@ func (cli *Client) ContainerList(ctx context.Context, options types.ContainerLis
}
resp, err := cli.get(ctx, "/containers/json", query, nil)
defer ensureReaderClosed(resp)
if err != nil {
return nil, err
}
var containers []types.Container
err = json.NewDecoder(resp.body).Decode(&containers)
ensureReaderClosed(resp)
return containers, err
}
+6 -6
View File
@@ -1,14 +1,14 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"io"
"net/url"
"time"
"golang.org/x/net/context"
"github.com/docker/docker/api/types"
timetypes "github.com/docker/docker/api/types/time"
"github.com/pkg/errors"
)
// ContainerLogs returns the logs generated by a container in an io.ReadCloser.
@@ -24,7 +24,7 @@ import (
// multiplexed.
// The format of the multiplexed stream is as follows:
//
// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
//
// STREAM_TYPE can be 1 for stdout and 2 for stderr
//
@@ -46,7 +46,7 @@ func (cli *Client) ContainerLogs(ctx context.Context, container string, options
if options.Since != "" {
ts, err := timetypes.GetTimestamp(options.Since, time.Now())
if err != nil {
return nil, err
return nil, errors.Wrap(err, `invalid value for "since"`)
}
query.Set("since", ts)
}
@@ -54,7 +54,7 @@ func (cli *Client) ContainerLogs(ctx context.Context, container string, options
if options.Until != "" {
ts, err := timetypes.GetTimestamp(options.Until, time.Now())
if err != nil {
return nil, err
return nil, errors.Wrap(err, `invalid value for "until"`)
}
query.Set("until", ts)
}
@@ -74,7 +74,7 @@ func (cli *Client) ContainerLogs(ctx context.Context, container string, options
resp, err := cli.get(ctx, "/containers/"+container+"/logs", query, nil)
if err != nil {
return nil, wrapResponseError(err, resp, "container", container)
return nil, err
}
return resp.body, nil
}
+1 -1
View File
@@ -1,6 +1,6 @@
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.
func (cli *Client) ContainerPause(ctx context.Context, containerID string) error {
+2 -2
View File
@@ -1,12 +1,12 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"golang.org/x/net/context"
)
// ContainersPrune requests the daemon to delete unused data
@@ -23,10 +23,10 @@ func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Arg
}
serverResp, err := cli.post(ctx, "/containers/prune", query, nil, nil)
defer ensureReaderClosed(serverResp)
if err != nil {
return report, err
}
defer ensureReaderClosed(serverResp)
if err := json.NewDecoder(serverResp.body).Decode(&report); err != nil {
return report, fmt.Errorf("Error retrieving disk usage: %v", err)
+3 -3
View File
@@ -1,10 +1,10 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"net/url"
"github.com/docker/docker/api/types"
"golang.org/x/net/context"
)
// ContainerRemove kills and removes a container from the docker host.
@@ -22,6 +22,6 @@ func (cli *Client) ContainerRemove(ctx context.Context, containerID string, opti
}
resp, err := cli.delete(ctx, "/containers/"+containerID, query, nil)
ensureReaderClosed(resp)
return wrapResponseError(err, resp, "container", containerID)
defer ensureReaderClosed(resp)
return err
}
+1 -2
View File
@@ -1,9 +1,8 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"net/url"
"golang.org/x/net/context"
)
// ContainerRename changes the name of a given container.
+1 -1
View File
@@ -1,11 +1,11 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"net/url"
"strconv"
"github.com/docker/docker/api/types"
"golang.org/x/net/context"
)
// ContainerResize changes the size of the tty for a container.
+11 -7
View File
@@ -1,20 +1,24 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"net/url"
"time"
"strconv"
timetypes "github.com/docker/docker/api/types/time"
"golang.org/x/net/context"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/versions"
)
// ContainerRestart stops and starts a container again.
// It makes the daemon to wait for the container to be up again for
// It makes the daemon wait for the container to be up again for
// a specific amount of time, given the timeout.
func (cli *Client) ContainerRestart(ctx context.Context, containerID string, timeout *time.Duration) error {
func (cli *Client) ContainerRestart(ctx context.Context, containerID string, options container.StopOptions) error {
query := url.Values{}
if timeout != nil {
query.Set("t", timetypes.DurationToSecondsString(*timeout))
if options.Timeout != nil {
query.Set("t", strconv.Itoa(*options.Timeout))
}
if options.Signal != "" && versions.GreaterThanOrEqualTo(cli.version, "1.42") {
query.Set("signal", options.Signal)
}
resp, err := cli.post(ctx, "/containers/"+containerID+"/restart", query, nil, nil)
ensureReaderClosed(resp)
+1 -2
View File
@@ -1,10 +1,9 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"net/url"
"golang.org/x/net/context"
"github.com/docker/docker/api/types"
)
+17 -1
View File
@@ -1,10 +1,10 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"net/url"
"github.com/docker/docker/api/types"
"golang.org/x/net/context"
)
// ContainerStats returns near realtime stats for a given container.
@@ -24,3 +24,19 @@ func (cli *Client) ContainerStats(ctx context.Context, containerID string, strea
osType := getDockerOS(resp.header.Get("Server"))
return types.ContainerStats{Body: resp.body, OSType: osType}, err
}
// ContainerStatsOneShot gets a single stat entry from a container.
// It differs from `ContainerStats` in that the API should not wait to prime the stats
func (cli *Client) ContainerStatsOneShot(ctx context.Context, containerID string) (types.ContainerStats, error) {
query := url.Values{}
query.Set("stream", "0")
query.Set("one-shot", "1")
resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil)
if err != nil {
return types.ContainerStats{}, err
}
osType := getDockerOS(resp.header.Get("Server"))
return types.ContainerStats{Body: resp.body, OSType: osType}, err
}
+17 -8
View File
@@ -1,19 +1,28 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"net/url"
"time"
"strconv"
timetypes "github.com/docker/docker/api/types/time"
"golang.org/x/net/context"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/versions"
)
// ContainerStop stops a container without terminating the process.
// The process is blocked until the container stops or the timeout expires.
func (cli *Client) ContainerStop(ctx context.Context, containerID string, timeout *time.Duration) error {
// ContainerStop stops a container. In case the container fails to stop
// 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, options container.StopOptions) error {
query := url.Values{}
if timeout != nil {
query.Set("t", timetypes.DurationToSecondsString(*timeout))
if options.Timeout != nil {
query.Set("t", strconv.Itoa(*options.Timeout))
}
if options.Signal != "" && versions.GreaterThanOrEqualTo(cli.version, "1.42") {
query.Set("signal", options.Signal)
}
resp, err := cli.post(ctx, "/containers/"+containerID+"/stop", query, nil, nil)
ensureReaderClosed(resp)
+2 -2
View File
@@ -1,12 +1,12 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"net/url"
"strings"
"github.com/docker/docker/api/types/container"
"golang.org/x/net/context"
)
// ContainerTop shows process information from within a container.
@@ -18,11 +18,11 @@ func (cli *Client) ContainerTop(ctx context.Context, containerID string, argumen
}
resp, err := cli.get(ctx, "/containers/"+containerID+"/top", query, nil)
defer ensureReaderClosed(resp)
if err != nil {
return response, err
}
err = json.NewDecoder(resp.body).Decode(&response)
ensureReaderClosed(resp)
return response, err
}
+1 -1
View File
@@ -1,6 +1,6 @@
package client // import "github.com/docker/docker/client"
import "golang.org/x/net/context"
import "context"
// ContainerUnpause resumes the process execution within a container
func (cli *Client) ContainerUnpause(ctx context.Context, containerID string) error {
+3 -4
View File
@@ -1,22 +1,21 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"github.com/docker/docker/api/types/container"
"golang.org/x/net/context"
)
// ContainerUpdate updates resources of a container
// ContainerUpdate updates the resources of a container.
func (cli *Client) ContainerUpdate(ctx context.Context, containerID string, updateConfig container.UpdateConfig) (container.ContainerUpdateOKBody, error) {
var response container.ContainerUpdateOKBody
serverResp, err := cli.post(ctx, "/containers/"+containerID+"/update", nil, updateConfig, nil)
defer ensureReaderClosed(serverResp)
if err != nil {
return response, err
}
err = json.NewDecoder(serverResp.body).Decode(&response)
ensureReaderClosed(serverResp)
return response, err
}
+31 -11
View File
@@ -1,15 +1,19 @@
package client // import "github.com/docker/docker/client"
import (
"bytes"
"context"
"encoding/json"
"errors"
"io"
"net/url"
"golang.org/x/net/context"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/versions"
)
const containerWaitErrorMsgLimit = 2 * 1024 /* Max: 2KiB */
// ContainerWait waits until the specified container is in a certain state
// indicated by the given condition, either "not-running" (default),
// "next-exit", or "removed".
@@ -25,16 +29,18 @@ import (
// wait request or in getting the response. This allows the caller to
// synchronize ContainerWait with other calls, such as specifying a
// "next-exit" condition before issuing a ContainerStart request.
func (cli *Client) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.ContainerWaitOKBody, <-chan error) {
func (cli *Client) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) {
if versions.LessThan(cli.ClientVersion(), "1.30") {
return cli.legacyContainerWait(ctx, containerID)
}
resultC := make(chan container.ContainerWaitOKBody)
resultC := make(chan container.WaitResponse)
errC := make(chan error, 1)
query := url.Values{}
query.Set("condition", string(condition))
if condition != "" {
query.Set("condition", string(condition))
}
resp, err := cli.post(ctx, "/containers/"+containerID+"/wait", query, nil, nil)
if err != nil {
@@ -45,9 +51,23 @@ func (cli *Client) ContainerWait(ctx context.Context, containerID string, condit
go func() {
defer ensureReaderClosed(resp)
var res container.ContainerWaitOKBody
if err := json.NewDecoder(resp.body).Decode(&res); err != nil {
errC <- err
body := resp.body
responseText := bytes.NewBuffer(nil)
stream := io.TeeReader(body, responseText)
var res container.WaitResponse
if err := json.NewDecoder(stream).Decode(&res); err != nil {
// NOTE(nicks): The /wait API does not work well with HTTP proxies.
// At any time, the proxy could cut off the response stream.
//
// But because the HTTP status has already been written, the proxy's
// only option is to write a plaintext error message.
//
// If there's a JSON parsing error, read the real error message
// off the body and send it to the client.
_, _ = io.ReadAll(io.LimitReader(stream, containerWaitErrorMsgLimit))
errC <- errors.New(responseText.String())
return
}
@@ -59,8 +79,8 @@ func (cli *Client) ContainerWait(ctx context.Context, containerID string, condit
// legacyContainerWait returns immediately and doesn't have an option to wait
// until the container is removed.
func (cli *Client) legacyContainerWait(ctx context.Context, containerID string) (<-chan container.ContainerWaitOKBody, <-chan error) {
resultC := make(chan container.ContainerWaitOKBody)
func (cli *Client) legacyContainerWait(ctx context.Context, containerID string) (<-chan container.WaitResponse, <-chan error) {
resultC := make(chan container.WaitResponse)
errC := make(chan error)
go func() {
@@ -71,7 +91,7 @@ func (cli *Client) legacyContainerWait(ctx context.Context, containerID string)
}
defer ensureReaderClosed(resp)
var res container.ContainerWaitOKBody
var res container.WaitResponse
if err := json.NewDecoder(resp.body).Decode(&res); err != nil {
errC <- err
return
+17 -10
View File
@@ -1,26 +1,33 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"fmt"
"net/url"
"github.com/docker/docker/api/types"
"golang.org/x/net/context"
)
// DiskUsage requests the current data usage from the daemon
func (cli *Client) DiskUsage(ctx context.Context) (types.DiskUsage, error) {
var du types.DiskUsage
serverResp, err := cli.get(ctx, "/system/df", nil, nil)
if err != nil {
return du, err
func (cli *Client) DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error) {
var query url.Values
if len(options.Types) > 0 {
query = url.Values{}
for _, t := range options.Types {
query.Add("type", string(t))
}
}
serverResp, err := cli.get(ctx, "/system/df", query, nil)
defer ensureReaderClosed(serverResp)
if err := json.NewDecoder(serverResp.body).Decode(&du); err != nil {
return du, fmt.Errorf("Error retrieving disk usage: %v", err)
if err != nil {
return types.DiskUsage{}, err
}
var du types.DiskUsage
if err := json.NewDecoder(serverResp.body).Decode(&du); err != nil {
return types.DiskUsage{}, fmt.Errorf("Error retrieving disk usage: %v", err)
}
return du, nil
}
+3 -3
View File
@@ -1,14 +1,14 @@
package client // import "github.com/docker/docker/client"
import (
"context"
"encoding/json"
"net/url"
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 the full manifest.
func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegistryAuth string) (registrytypes.DistributionInspect, error) {
// Contact the registry to retrieve digest and platform information
var distributionInspect registrytypes.DistributionInspect
@@ -28,11 +28,11 @@ func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegist
}
resp, err := cli.get(ctx, "/distribution/"+image+"/json", url.Values{}, headers)
defer ensureReaderClosed(resp)
if err != nil {
return distributionInspect, err
}
err = json.NewDecoder(resp.body).Decode(&distributionInspect)
ensureReaderClosed(resp)
return distributionInspect, err
}
+90
View File
@@ -0,0 +1,90 @@
package client // import "github.com/docker/docker/client"
const (
// EnvOverrideHost is the name of the environment variable that can be used
// to override the default host to connect to (DefaultDockerHost).
//
// This env-var is read by FromEnv and WithHostFromEnv and when set to a
// non-empty value, takes precedence over the default host (which is platform
// specific), or any host already set.
EnvOverrideHost = "DOCKER_HOST"
// EnvOverrideAPIVersion is the name of the environment variable that can
// be used to override the API version to use. Value should be
// formatted as MAJOR.MINOR, for example, "1.19".
//
// This env-var is read by FromEnv and WithVersionFromEnv and when set to a
// non-empty value, takes precedence over API version negotiation.
//
// This environment variable should be used for debugging purposes only, as
// it can set the client to use an incompatible (or invalid) API version.
EnvOverrideAPIVersion = "DOCKER_API_VERSION"
// EnvOverrideCertPath is the name of the environment variable that can be
// used to specify the directory from which to load the TLS certificates
// (ca.pem, cert.pem, key.pem) from. These certificates are used to configure
// the Client for a TCP connection protected by TLS client authentication.
//
// TLS certificate verification is enabled by default if the Client is configured
// to use a TLS connection. Refer to EnvTLSVerify below to learn how to
// disable verification for testing purposes.
//
// WARNING: Access to the remote API is equivalent to root access to the
// host where the daemon runs. Do not expose the API without protection,
// and only if needed. Make sure you are familiar with the "daemon attack
// surface" (https://docs.docker.com/go/attack-surface/).
//
// For local access to the API, it is recommended to connect with the daemon
// using the default local socket connection (on Linux), or the named pipe
// (on Windows).
//
// If you need to access the API of a remote daemon, consider using an SSH
// (ssh://) connection, which is easier to set up, and requires no additional
// configuration if the host is accessible using ssh.
//
// If you cannot use the alternatives above, and you must expose the API over
// a TCP connection, refer to https://docs.docker.com/engine/security/protect-access/
// to learn how to configure the daemon and client to use a TCP connection
// with TLS client authentication. Make sure you know the differences between
// a regular TLS connection and a TLS connection protected by TLS client
// authentication, and verify that the API cannot be accessed by other clients.
EnvOverrideCertPath = "DOCKER_CERT_PATH"
// EnvTLSVerify is the name of the environment variable that can be used to
// enable or disable TLS certificate verification. When set to a non-empty
// value, TLS certificate verification is enabled, and the client is configured
// to use a TLS connection, using certificates from the default directories
// (within `~/.docker`); refer to EnvOverrideCertPath above for additional
// details.
//
// WARNING: Access to the remote API is equivalent to root access to the
// host where the daemon runs. Do not expose the API without protection,
// and only if needed. Make sure you are familiar with the "daemon attack
// surface" (https://docs.docker.com/go/attack-surface/).
//
// Before setting up your client and daemon to use a TCP connection with TLS
// client authentication, consider using one of the alternatives mentioned
// in EnvOverrideCertPath above.
//
// Disabling TLS certificate verification (for testing purposes)
//
// TLS certificate verification is enabled by default if the Client is configured
// to use a TLS connection, and it is highly recommended to keep verification
// enabled to prevent machine-in-the-middle attacks. Refer to the documentation
// at https://docs.docker.com/engine/security/protect-access/ and pages linked
// from that page to learn how to configure the daemon and client to use a
// TCP connection with TLS client authentication enabled.
//
// Set the "DOCKER_TLS_VERIFY" environment to an empty string ("") to
// disable TLS certificate verification. Disabling verification is insecure,
// so should only be done for testing purposes. From the Go documentation
// (https://pkg.go.dev/crypto/tls#Config):
//
// InsecureSkipVerify controls whether a client verifies the server's
// certificate chain and host name. If InsecureSkipVerify is true, crypto/tls
// accepts any certificate presented by the server and any host name in that
// certificate. In this mode, TLS is susceptible to machine-in-the-middle
// attacks unless custom verification is used. This should be used only for
// testing or in combination with VerifyConnection or VerifyPeerCertificate.
EnvTLSVerify = "DOCKER_TLS_VERIFY"
)
+16 -56
View File
@@ -3,9 +3,8 @@ package client // import "github.com/docker/docker/client"
import (
"fmt"
"net/http"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
"github.com/pkg/errors"
)
@@ -24,8 +23,7 @@ func (err errConnectionFailed) Error() string {
// IsErrConnectionFailed returns true if the error is caused by connection failed.
func IsErrConnectionFailed(err error) bool {
_, ok := errors.Cause(err).(errConnectionFailed)
return ok
return errors.As(err, &errConnectionFailed{})
}
// ErrorConnectionFailed returns an error with host in the error message when connection to docker daemon failed.
@@ -33,16 +31,20 @@ func ErrorConnectionFailed(host string) error {
return errConnectionFailed{host: host}
}
// Deprecated: use the errdefs.NotFound() interface instead. Kept for backward compatibility
type notFound interface {
error
NotFound() bool // Is the error a NotFound error
NotFound() bool
}
// IsErrNotFound returns true if the error is a NotFound error, which is returned
// by the API when some object is not found.
func IsErrNotFound(err error) bool {
te, ok := err.(notFound)
return ok && te.NotFound()
if errdefs.IsNotFound(err) {
return true
}
var e notFound
return errors.As(err, &e)
}
type objectNotFoundError struct {
@@ -50,42 +52,18 @@ type objectNotFoundError struct {
id string
}
func (e objectNotFoundError) NotFound() bool {
return true
}
func (e objectNotFoundError) NotFound() {}
func (e objectNotFoundError) Error() string {
return fmt.Sprintf("Error: No such %s: %s", e.object, e.id)
}
func wrapResponseError(err error, resp serverResponse, object, id string) error {
switch {
case err == nil:
return nil
case resp.statusCode == http.StatusNotFound:
return objectNotFoundError{object: object, id: id}
case resp.statusCode == http.StatusNotImplemented:
return notImplementedError{message: err.Error()}
default:
return err
}
}
// unauthorizedError represents an authorization error in a remote registry.
type unauthorizedError struct {
cause error
}
// Error returns a string representation of an unauthorizedError
func (u unauthorizedError) Error() string {
return u.cause.Error()
}
// IsErrUnauthorized returns true if the error is caused
// when a remote registry authentication fails
//
// Deprecated: use errdefs.IsUnauthorized
func IsErrUnauthorized(err error) bool {
_, ok := err.(unauthorizedError)
return ok
return errdefs.IsUnauthorized(err)
}
type pluginPermissionDenied struct {
@@ -96,31 +74,13 @@ func (e pluginPermissionDenied) Error() string {
return "Permission denied while installing plugin " + e.name
}
// IsErrPluginPermissionDenied returns true if the error is caused
// when a user denies a plugin's permissions
func IsErrPluginPermissionDenied(err error) bool {
_, ok := err.(pluginPermissionDenied)
return ok
}
type notImplementedError struct {
message string
}
func (e notImplementedError) Error() string {
return e.message
}
func (e notImplementedError) NotImplemented() bool {
return true
}
// IsErrNotImplemented returns true if the error is a NotImplemented error.
// This is returned by the API when a requested feature has not been
// implemented.
//
// Deprecated: use errdefs.IsNotImplemented
func IsErrNotImplemented(err error) bool {
te, ok := err.(notImplementedError)
return ok && te.NotImplemented()
return errdefs.IsNotImplemented(err)
}
// NewVersionError returns an error if the APIVersion required
Loaded 100 of 1570 files, more files were not shown because too many files have changed in this diff. Show more