mirror of https://github.com/docker/cli.git
vendor: github.com/docker/docker f1dd6bf84e28930e1ccd903361f9284fb22d3b8a
full diff: 7c69b6dc08...f1dd6bf84e
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
ec37bfb245
commit
9bf28fc003
|
@ -76,7 +76,7 @@ require (
|
|||
)
|
||||
|
||||
replace (
|
||||
github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220512073244-7c69b6dc08c7+incompatible // master (v22.06-dev)
|
||||
github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220513094153-f1dd6bf84e28+incompatible // master (v22.06-dev)
|
||||
github.com/gogo/googleapis => github.com/gogo/googleapis v1.3.2
|
||||
|
||||
// Resolve dependency hell with github.com/cloudflare/cfssl (transitive via
|
||||
|
|
|
@ -105,8 +105,8 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xb
|
|||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
|
||||
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v20.10.3-0.20220512073244-7c69b6dc08c7+incompatible h1:QNoUa4JDYdN4PQOdB89GO9urFixZfrKTH2qcxCthbYk=
|
||||
github.com/docker/docker v20.10.3-0.20220512073244-7c69b6dc08c7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.3-0.20220513094153-f1dd6bf84e28+incompatible h1:N6klPo5I0m29g5jQgwNNmdL8KTyHXOYdtB0lep7H5Y0=
|
||||
github.com/docker/docker v20.10.3-0.20220513094153-f1dd6bf84e28+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o=
|
||||
github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c=
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
||||
|
|
|
@ -1996,6 +1996,8 @@ definitions:
|
|||
x-nullable: false
|
||||
enum: ["local", "global"]
|
||||
example: "local"
|
||||
ClusterVolume:
|
||||
$ref: "#/definitions/ClusterVolume"
|
||||
Options:
|
||||
type: "object"
|
||||
description: |
|
||||
|
@ -2069,6 +2071,8 @@ definitions:
|
|||
example:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
ClusterVolumeSpec:
|
||||
$ref: "#/definitions/ClusterVolumeSpec"
|
||||
|
||||
VolumeListResponse:
|
||||
type: "object"
|
||||
|
@ -5740,6 +5744,242 @@ definitions:
|
|||
items:
|
||||
$ref: "#/definitions/OCIPlatform"
|
||||
|
||||
ClusterVolume:
|
||||
type: "object"
|
||||
description: |
|
||||
Options and information specific to, and only present on, Swarm CSI
|
||||
cluster volumes.
|
||||
properties:
|
||||
ID:
|
||||
type: "string"
|
||||
description: |
|
||||
The Swarm ID of this volume. Because cluster volumes are Swarm
|
||||
objects, they have an ID, unlike non-cluster volumes. This ID can
|
||||
be used to refer to the Volume instead of the name.
|
||||
Version:
|
||||
$ref: "#/definitions/ObjectVersion"
|
||||
CreatedAt:
|
||||
type: "string"
|
||||
format: "dateTime"
|
||||
UpdatedAt:
|
||||
type: "string"
|
||||
format: "dateTime"
|
||||
Spec:
|
||||
$ref: "#/definitions/ClusterVolumeSpec"
|
||||
Info:
|
||||
type: "object"
|
||||
description: |
|
||||
Information about the global status of the volume.
|
||||
properties:
|
||||
CapacityBytes:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
description: |
|
||||
The capacity of the volume in bytes. A value of 0 indicates that
|
||||
the capacity is unknown.
|
||||
VolumeContext:
|
||||
type: "object"
|
||||
description: |
|
||||
A map of strings to strings returned from the storage plugin when
|
||||
the volume is created.
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
VolumeID:
|
||||
type: "string"
|
||||
description: |
|
||||
The ID of the volume as returned by the CSI storage plugin. This
|
||||
is distinct from the volume's ID as provided by Docker. This ID
|
||||
is never used by the user when communicating with Docker to refer
|
||||
to this volume. If the ID is blank, then the Volume has not been
|
||||
successfully created in the plugin yet.
|
||||
AccessibleTopology:
|
||||
type: "array"
|
||||
description: |
|
||||
The topology this volume is actually accessible from.
|
||||
items:
|
||||
$ref: "#/definitions/Topology"
|
||||
PublishStatus:
|
||||
type: "array"
|
||||
description: |
|
||||
The status of the volume as it pertains to its publishing and use on
|
||||
specific nodes
|
||||
items:
|
||||
type: "object"
|
||||
properties:
|
||||
NodeID:
|
||||
type: "string"
|
||||
description: |
|
||||
The ID of the Swarm node the volume is published on.
|
||||
State:
|
||||
type: "string"
|
||||
description: |
|
||||
The published state of the volume.
|
||||
* `pending-publish` The volume should be published to this node, but the call to the controller plugin to do so has not yet been successfully completed.
|
||||
* `published` The volume is published successfully to the node.
|
||||
* `pending-node-unpublish` The volume should be unpublished from the node, and the manager is awaiting confirmation from the worker that it has done so.
|
||||
* `pending-controller-unpublish` The volume is successfully unpublished from the node, but has not yet been successfully unpublished on the controller.
|
||||
enum:
|
||||
- "pending-publish"
|
||||
- "published"
|
||||
- "pending-node-unpublish"
|
||||
- "pending-controller-unpublish"
|
||||
PublishContext:
|
||||
type: "object"
|
||||
description: |
|
||||
A map of strings to strings returned by the CSI controller
|
||||
plugin when a volume is published.
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
|
||||
ClusterVolumeSpec:
|
||||
type: "object"
|
||||
description: |
|
||||
Cluster-specific options used to create the volume.
|
||||
properties:
|
||||
Group:
|
||||
type: "string"
|
||||
description: |
|
||||
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.
|
||||
AccessMode:
|
||||
type: "object"
|
||||
description: |
|
||||
Defines how the volume is used by tasks.
|
||||
properties:
|
||||
Scope:
|
||||
type: "string"
|
||||
description: |
|
||||
The set of nodes this volume can be used on at one time.
|
||||
- `single` The volume may only be scheduled to one node at a time.
|
||||
- `multi` the volume may be scheduled to any supported number of nodes at a time.
|
||||
default: "single"
|
||||
enum: ["single", "multi"]
|
||||
x-nullable: false
|
||||
Sharing:
|
||||
type: "string"
|
||||
description: |
|
||||
The number and way that different tasks can use this volume
|
||||
at one time.
|
||||
- `none` The volume may only be used by one task at a time.
|
||||
- `readonly` The volume may be used by any number of tasks, but they all must mount the volume as readonly
|
||||
- `onewriter` The volume may be used by any number of tasks, but only one may mount it as read/write.
|
||||
- `all` The volume may have any number of readers and writers.
|
||||
default: "none"
|
||||
enum: ["none", "readonly", "onewriter", "all"]
|
||||
x-nullable: false
|
||||
MountVolume:
|
||||
type: "object"
|
||||
description: |
|
||||
Options for using this volume as a Mount-type volume.
|
||||
|
||||
Either MountVolume or BlockVolume, but not both, must be
|
||||
present.
|
||||
properties:
|
||||
FsType:
|
||||
type: "string"
|
||||
description: |
|
||||
Specifies the filesystem type for the mount volume.
|
||||
Optional.
|
||||
MountFlags:
|
||||
type: "array"
|
||||
description: |
|
||||
Flags to pass when mounting the volume. Optional.
|
||||
items:
|
||||
type: "string"
|
||||
BlockVolume:
|
||||
type: "object"
|
||||
description: |
|
||||
Options for using this volume as a Block-type volume.
|
||||
Intentionally empty.
|
||||
Secrets:
|
||||
type: "array"
|
||||
description: |
|
||||
Swarm Secrets that are passed to the CSI storage plugin when
|
||||
operating on this volume.
|
||||
items:
|
||||
type: "object"
|
||||
description: |
|
||||
One cluster volume secret entry. Defines a key-value pair that
|
||||
is passed to the plugin.
|
||||
properties:
|
||||
Key:
|
||||
type: "string"
|
||||
description: |
|
||||
Key is the name of the key of the key-value pair passed to
|
||||
the plugin.
|
||||
Secret:
|
||||
type: "string"
|
||||
description: |
|
||||
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.
|
||||
AccessibilityRequirements:
|
||||
type: "object"
|
||||
description: |
|
||||
Requirements for the accessible topology of the volume. These
|
||||
fields are optional. For an in-depth description of what these
|
||||
fields mean, see the CSI specification.
|
||||
properties:
|
||||
Requisite:
|
||||
type: "array"
|
||||
description: |
|
||||
A list of required topologies, at least one of which the
|
||||
volume must be accessible from.
|
||||
items:
|
||||
$ref: "#/definitions/Topology"
|
||||
Preferred:
|
||||
type: "array"
|
||||
description: |
|
||||
A list of topologies that the volume should attempt to be
|
||||
provisioned in.
|
||||
items:
|
||||
$ref: "#/definitions/Topology"
|
||||
CapacityRange:
|
||||
type: "object"
|
||||
description: |
|
||||
The desired capacity that the volume should be created with. If
|
||||
empty, the plugin will decide the capacity.
|
||||
properties:
|
||||
RequiredBytes:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
description: |
|
||||
The volume must be at least this big. The value of 0
|
||||
indicates an unspecified minimum
|
||||
LimitBytes:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
description: |
|
||||
The volume must not be bigger than this. The value of 0
|
||||
indicates an unspecified maximum.
|
||||
Availability:
|
||||
type: "string"
|
||||
description: |
|
||||
The availability of the volume for use in tasks.
|
||||
- `active` The volume is fully available for scheduling on the cluster
|
||||
- `pause` No new workloads should use the volume, but existing workloads are not stopped.
|
||||
- `drain` All workloads using this volume should be stopped and rescheduled, and no new ones should be started.
|
||||
default: "active"
|
||||
x-nullable: false
|
||||
enum:
|
||||
- "active"
|
||||
- "pause"
|
||||
- "drain"
|
||||
|
||||
Topology:
|
||||
description: |
|
||||
A map of topological domains to topological segments. For in depth
|
||||
details, see documentation for the Topology object in the CSI
|
||||
specification.
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
|
||||
paths:
|
||||
/containers/json:
|
||||
get:
|
||||
|
@ -6478,6 +6718,9 @@ paths:
|
|||
|
||||
Note: This endpoint works only for containers with the `json-file` or
|
||||
`journald` logging driver.
|
||||
produces:
|
||||
- "application/vnd.docker.raw-stream"
|
||||
- "application/vnd.docker.multiplexed-stream"
|
||||
operationId: "ContainerLogs"
|
||||
responses:
|
||||
200:
|
||||
|
@ -7189,7 +7432,8 @@ paths:
|
|||
### Stream format
|
||||
|
||||
When the TTY setting is disabled in [`POST /containers/create`](#operation/ContainerCreate),
|
||||
the stream over the hijacked connected is multiplexed to separate out
|
||||
the HTTP Content-Type header is set to application/vnd.docker.multiplexed-stream
|
||||
and the stream over the hijacked connected is multiplexed to separate out
|
||||
`stdout` and `stderr`. The stream consists of a series of frames, each
|
||||
containing a header and a payload.
|
||||
|
||||
|
@ -7233,6 +7477,7 @@ paths:
|
|||
operationId: "ContainerAttach"
|
||||
produces:
|
||||
- "application/vnd.docker.raw-stream"
|
||||
- "application/vnd.docker.multiplexed-stream"
|
||||
responses:
|
||||
101:
|
||||
description: "no error, hints proxy about hijacking"
|
||||
|
@ -9015,6 +9260,7 @@ paths:
|
|||
- "application/json"
|
||||
produces:
|
||||
- "application/vnd.docker.raw-stream"
|
||||
- "application/vnd.docker.multiplexed-stream"
|
||||
responses:
|
||||
200:
|
||||
description: "No error"
|
||||
|
@ -9241,6 +9487,64 @@ paths:
|
|||
type: "string"
|
||||
tags: ["Volume"]
|
||||
|
||||
put:
|
||||
summary: |
|
||||
"Update a volume. Valid only for Swarm cluster volumes"
|
||||
operationId: "VolumeUpdate"
|
||||
consumes: ["application/json"]
|
||||
produces: ["application/json"]
|
||||
responses:
|
||||
200:
|
||||
description: "no error"
|
||||
400:
|
||||
description: "bad parameter"
|
||||
schema:
|
||||
$ref: "#/definitions/ErrorResponse"
|
||||
404:
|
||||
description: "no such volume"
|
||||
schema:
|
||||
$ref: "#/definitions/ErrorResponse"
|
||||
500:
|
||||
description: "server error"
|
||||
schema:
|
||||
$ref: "#/definitions/ErrorResponse"
|
||||
503:
|
||||
description: "node is not part of a swarm"
|
||||
schema:
|
||||
$ref: "#/definitions/ErrorResponse"
|
||||
parameters:
|
||||
- name: "name"
|
||||
in: "path"
|
||||
description: "The name or ID of the volume"
|
||||
type: "string"
|
||||
required: true
|
||||
- name: "body"
|
||||
in: "body"
|
||||
schema:
|
||||
# though the schema for is an object that contains only a
|
||||
# ClusterVolumeSpec, wrapping the ClusterVolumeSpec in this object
|
||||
# means that if, later on, we support things like changing the
|
||||
# labels, we can do so without duplicating that information to the
|
||||
# ClusterVolumeSpec.
|
||||
type: "object"
|
||||
description: "Volume configuration"
|
||||
properties:
|
||||
Spec:
|
||||
$ref: "#/definitions/ClusterVolumeSpec"
|
||||
description: |
|
||||
The spec of the volume to update. Currently, only Availability may
|
||||
change. All other fields must remain unchanged.
|
||||
- name: "version"
|
||||
in: "query"
|
||||
description: |
|
||||
The version number of the volume being updated. This is required to
|
||||
avoid conflicting writes. Found in the volume's `ClusterVolume`
|
||||
field.
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
required: true
|
||||
tags: ["Volume"]
|
||||
|
||||
delete:
|
||||
summary: "Remove a volume"
|
||||
description: "Instruct the driver to remove the volume."
|
||||
|
@ -9272,6 +9576,7 @@ paths:
|
|||
type: "boolean"
|
||||
default: false
|
||||
tags: ["Volume"]
|
||||
|
||||
/volumes/prune:
|
||||
post:
|
||||
summary: "Delete unused volumes"
|
||||
|
@ -10913,6 +11218,9 @@ paths:
|
|||
|
||||
**Note**: This endpoint works only for services with the `local`,
|
||||
`json-file` or `journald` logging drivers.
|
||||
produces:
|
||||
- "application/vnd.docker.raw-stream"
|
||||
- "application/vnd.docker.multiplexed-stream"
|
||||
operationId: "ServiceLogs"
|
||||
responses:
|
||||
200:
|
||||
|
@ -11168,6 +11476,9 @@ paths:
|
|||
**Note**: This endpoint works only for services with the `local`,
|
||||
`json-file` or `journald` logging drivers.
|
||||
operationId: "TaskLogs"
|
||||
produces:
|
||||
- "application/vnd.docker.raw-stream"
|
||||
- "application/vnd.docker.multiplexed-stream"
|
||||
responses:
|
||||
200:
|
||||
description: "logs returned as a stream in response body"
|
||||
|
|
|
@ -112,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.
|
||||
|
@ -123,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 {
|
||||
|
|
|
@ -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 = "csi"
|
||||
)
|
||||
|
||||
// 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.
|
||||
|
@ -129,3 +132,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
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
|
|
@ -62,6 +62,11 @@ type Task struct {
|
|||
// 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.
|
||||
|
@ -204,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"`
|
||||
}
|
||||
|
|
|
@ -18,6 +18,14 @@ import (
|
|||
"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 `json:",omitempty"`
|
||||
|
|
420
vendor/github.com/docker/docker/api/types/volume/cluster_volume.go
generated
vendored
Normal file
420
vendor/github.com/docker/docker/api/types/volume/cluster_volume.go
generated
vendored
Normal 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 CSI 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 CSI 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"`
|
||||
}
|
|
@ -9,6 +9,9 @@ package volume
|
|||
// 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"`
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -7,6 +7,9 @@ package volume
|
|||
// swagger:model Volume
|
||||
type Volume struct {
|
||||
|
||||
// cluster volume
|
||||
ClusterVolume *ClusterVolume `json:"ClusterVolume,omitempty"`
|
||||
|
||||
// Date/Time the volume was created.
|
||||
CreatedAt string `json:"CreatedAt,omitempty"`
|
||||
|
||||
|
|
|
@ -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"`
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -36,7 +36,9 @@ 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"}}
|
||||
headers := map[string][]string{
|
||||
"Content-Type": {"application/json"},
|
||||
}
|
||||
return cli.postHijacked(ctx, "/exec/"+execID+"/start", nil, config, headers)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/go-connections/sockets"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -30,12 +31,12 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu
|
|||
}
|
||||
req = cli.addHeaders(req, headers)
|
||||
|
||||
conn, err := cli.setupHijackConn(ctx, req, "tcp")
|
||||
conn, mediaType, err := cli.setupHijackConn(ctx, req, "tcp")
|
||||
if err != nil {
|
||||
return types.HijackedResponse{}, err
|
||||
}
|
||||
|
||||
return types.HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn)}, err
|
||||
return types.NewHijackedResponse(conn, mediaType), err
|
||||
}
|
||||
|
||||
// DialHijack returns a hijacked connection with negotiated protocol proto.
|
||||
|
@ -46,7 +47,8 @@ func (cli *Client) DialHijack(ctx context.Context, url, proto string, meta map[s
|
|||
}
|
||||
req = cli.addHeaders(req, meta)
|
||||
|
||||
return cli.setupHijackConn(ctx, req, proto)
|
||||
conn, _, err := cli.setupHijackConn(ctx, req, proto)
|
||||
return conn, err
|
||||
}
|
||||
|
||||
// fallbackDial is used when WithDialer() was not called.
|
||||
|
@ -61,7 +63,7 @@ func fallbackDial(proto, addr string, tlsConfig *tls.Config) (net.Conn, error) {
|
|||
return net.Dial(proto, addr)
|
||||
}
|
||||
|
||||
func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto string) (net.Conn, error) {
|
||||
func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto string) (net.Conn, string, error) {
|
||||
req.Host = cli.addr
|
||||
req.Header.Set("Connection", "Upgrade")
|
||||
req.Header.Set("Upgrade", proto)
|
||||
|
@ -69,7 +71,7 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto
|
|||
dialer := cli.Dialer()
|
||||
conn, err := dialer(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot connect to the Docker daemon. Is 'docker daemon' running on this host?")
|
||||
return nil, "", errors.Wrap(err, "cannot connect to the Docker daemon. Is 'docker daemon' running on this host?")
|
||||
}
|
||||
|
||||
// When we set up a TCP connection for hijack, there could be long periods
|
||||
|
@ -91,18 +93,18 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto
|
|||
//nolint:staticcheck // ignore SA1019 for connecting to old (pre go1.8) daemons
|
||||
if err != httputil.ErrPersistEOF {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, "", err
|
||||
}
|
||||
if resp.StatusCode != http.StatusSwitchingProtocols {
|
||||
resp.Body.Close()
|
||||
return nil, fmt.Errorf("unable to upgrade to %s, received %d", proto, resp.StatusCode)
|
||||
return nil, "", fmt.Errorf("unable to upgrade to %s, received %d", proto, resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
c, br := clientconn.Hijack()
|
||||
if br.Buffered() > 0 {
|
||||
// If there is buffered content, wrap the connection. We return an
|
||||
// object that implements CloseWrite iff the underlying connection
|
||||
// object that implements CloseWrite if the underlying connection
|
||||
// implements it.
|
||||
if _, ok := c.(types.CloseWriter); ok {
|
||||
c = &hijackedConnCloseWriter{&hijackedConn{c, br}}
|
||||
|
@ -113,7 +115,13 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto
|
|||
br.Reset(nil)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
var mediaType string
|
||||
if versions.GreaterThanOrEqualTo(cli.ClientVersion(), "1.42") {
|
||||
// Prior to 1.42, Content-Type is always set to raw-stream and not relevant
|
||||
mediaType = resp.Header.Get("Content-Type")
|
||||
}
|
||||
|
||||
return c, mediaType, nil
|
||||
}
|
||||
|
||||
// hijackedConn wraps a net.Conn and is returned by setupHijackConn in the case
|
||||
|
|
|
@ -179,6 +179,7 @@ type VolumeAPIClient interface {
|
|||
VolumeList(ctx context.Context, filter filters.Args) (volume.ListResponse, error)
|
||||
VolumeRemove(ctx context.Context, volumeID string, force bool) error
|
||||
VolumesPrune(ctx context.Context, pruneFilter filters.Args) (types.VolumesPruneReport, error)
|
||||
VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error
|
||||
}
|
||||
|
||||
// SecretAPIClient defines API client methods for secrets
|
||||
|
|
|
@ -49,6 +49,14 @@ func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, b
|
|||
return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers)
|
||||
}
|
||||
|
||||
func (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) {
|
||||
body, headers, err := encodeBody(obj, headers)
|
||||
if err != nil {
|
||||
return serverResponse{}, err
|
||||
}
|
||||
return cli.sendRequest(ctx, http.MethodPut, path, query, body, headers)
|
||||
}
|
||||
|
||||
// putRaw sends an http request to the docker API using the method PUT.
|
||||
func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) {
|
||||
return cli.sendRequest(ctx, http.MethodPut, path, query, body, headers)
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package client // import "github.com/docker/docker/client"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
)
|
||||
|
||||
// VolumeUpdate updates a volume. This only works for Cluster Volumes, and
|
||||
// only some fields can be updated.
|
||||
func (cli *Client) VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error {
|
||||
if err := cli.NewVersionError("1.42", "volume update"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
query := url.Values{}
|
||||
query.Set("version", strconv.FormatUint(version.Index, 10))
|
||||
|
||||
resp, err := cli.put(ctx, "/volumes/"+volumeID, query, options, nil)
|
||||
ensureReaderClosed(resp)
|
||||
return err
|
||||
}
|
|
@ -39,7 +39,7 @@ github.com/docker/distribution/registry/client/transport
|
|||
github.com/docker/distribution/registry/storage/cache
|
||||
github.com/docker/distribution/registry/storage/cache/memory
|
||||
github.com/docker/distribution/uuid
|
||||
# github.com/docker/docker v20.10.14+incompatible => github.com/docker/docker v20.10.3-0.20220512073244-7c69b6dc08c7+incompatible
|
||||
# github.com/docker/docker v20.10.14+incompatible => github.com/docker/docker v20.10.3-0.20220513094153-f1dd6bf84e28+incompatible
|
||||
## explicit
|
||||
github.com/docker/docker/api
|
||||
github.com/docker/docker/api/types
|
||||
|
@ -390,6 +390,6 @@ gotest.tools/v3/internal/format
|
|||
gotest.tools/v3/internal/source
|
||||
gotest.tools/v3/poll
|
||||
gotest.tools/v3/skip
|
||||
# github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220512073244-7c69b6dc08c7+incompatible
|
||||
# github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220513094153-f1dd6bf84e28+incompatible
|
||||
# github.com/gogo/googleapis => github.com/gogo/googleapis v1.3.2
|
||||
# github.com/google/certificate-transparency-go => github.com/google/certificate-transparency-go v1.0.20
|
||||
|
|
Loading…
Reference in New Issue