mirror of https://github.com/docker/cli.git
Merge pull request #3605 from thaJeztah/update_engine
vendor: github.com/docker/docker f1dd6bf84e28930e1ccd903361f9284fb22d3b8a
This commit is contained in:
commit
d0df532a25
|
@ -76,7 +76,7 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
replace (
|
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
|
github.com/gogo/googleapis => github.com/gogo/googleapis v1.3.2
|
||||||
|
|
||||||
// Resolve dependency hell with github.com/cloudflare/cfssl (transitive via
|
// 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.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 h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
|
||||||
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
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.20220513094153-f1dd6bf84e28+incompatible h1:N6klPo5I0m29g5jQgwNNmdL8KTyHXOYdtB0lep7H5Y0=
|
||||||
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/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 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o=
|
||||||
github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c=
|
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=
|
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
||||||
|
|
|
@ -1996,6 +1996,8 @@ definitions:
|
||||||
x-nullable: false
|
x-nullable: false
|
||||||
enum: ["local", "global"]
|
enum: ["local", "global"]
|
||||||
example: "local"
|
example: "local"
|
||||||
|
ClusterVolume:
|
||||||
|
$ref: "#/definitions/ClusterVolume"
|
||||||
Options:
|
Options:
|
||||||
type: "object"
|
type: "object"
|
||||||
description: |
|
description: |
|
||||||
|
@ -2069,6 +2071,8 @@ definitions:
|
||||||
example:
|
example:
|
||||||
com.example.some-label: "some-value"
|
com.example.some-label: "some-value"
|
||||||
com.example.some-other-label: "some-other-value"
|
com.example.some-other-label: "some-other-value"
|
||||||
|
ClusterVolumeSpec:
|
||||||
|
$ref: "#/definitions/ClusterVolumeSpec"
|
||||||
|
|
||||||
VolumeListResponse:
|
VolumeListResponse:
|
||||||
type: "object"
|
type: "object"
|
||||||
|
@ -5740,6 +5744,242 @@ definitions:
|
||||||
items:
|
items:
|
||||||
$ref: "#/definitions/OCIPlatform"
|
$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:
|
paths:
|
||||||
/containers/json:
|
/containers/json:
|
||||||
get:
|
get:
|
||||||
|
@ -6478,6 +6718,9 @@ paths:
|
||||||
|
|
||||||
Note: This endpoint works only for containers with the `json-file` or
|
Note: This endpoint works only for containers with the `json-file` or
|
||||||
`journald` logging driver.
|
`journald` logging driver.
|
||||||
|
produces:
|
||||||
|
- "application/vnd.docker.raw-stream"
|
||||||
|
- "application/vnd.docker.multiplexed-stream"
|
||||||
operationId: "ContainerLogs"
|
operationId: "ContainerLogs"
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
|
@ -7189,7 +7432,8 @@ paths:
|
||||||
### Stream format
|
### Stream format
|
||||||
|
|
||||||
When the TTY setting is disabled in [`POST /containers/create`](#operation/ContainerCreate),
|
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
|
`stdout` and `stderr`. The stream consists of a series of frames, each
|
||||||
containing a header and a payload.
|
containing a header and a payload.
|
||||||
|
|
||||||
|
@ -7233,6 +7477,7 @@ paths:
|
||||||
operationId: "ContainerAttach"
|
operationId: "ContainerAttach"
|
||||||
produces:
|
produces:
|
||||||
- "application/vnd.docker.raw-stream"
|
- "application/vnd.docker.raw-stream"
|
||||||
|
- "application/vnd.docker.multiplexed-stream"
|
||||||
responses:
|
responses:
|
||||||
101:
|
101:
|
||||||
description: "no error, hints proxy about hijacking"
|
description: "no error, hints proxy about hijacking"
|
||||||
|
@ -9015,6 +9260,7 @@ paths:
|
||||||
- "application/json"
|
- "application/json"
|
||||||
produces:
|
produces:
|
||||||
- "application/vnd.docker.raw-stream"
|
- "application/vnd.docker.raw-stream"
|
||||||
|
- "application/vnd.docker.multiplexed-stream"
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: "No error"
|
description: "No error"
|
||||||
|
@ -9241,6 +9487,64 @@ paths:
|
||||||
type: "string"
|
type: "string"
|
||||||
tags: ["Volume"]
|
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:
|
delete:
|
||||||
summary: "Remove a volume"
|
summary: "Remove a volume"
|
||||||
description: "Instruct the driver to remove the volume."
|
description: "Instruct the driver to remove the volume."
|
||||||
|
@ -9272,6 +9576,7 @@ paths:
|
||||||
type: "boolean"
|
type: "boolean"
|
||||||
default: false
|
default: false
|
||||||
tags: ["Volume"]
|
tags: ["Volume"]
|
||||||
|
|
||||||
/volumes/prune:
|
/volumes/prune:
|
||||||
post:
|
post:
|
||||||
summary: "Delete unused volumes"
|
summary: "Delete unused volumes"
|
||||||
|
@ -10913,6 +11218,9 @@ paths:
|
||||||
|
|
||||||
**Note**: This endpoint works only for services with the `local`,
|
**Note**: This endpoint works only for services with the `local`,
|
||||||
`json-file` or `journald` logging drivers.
|
`json-file` or `journald` logging drivers.
|
||||||
|
produces:
|
||||||
|
- "application/vnd.docker.raw-stream"
|
||||||
|
- "application/vnd.docker.multiplexed-stream"
|
||||||
operationId: "ServiceLogs"
|
operationId: "ServiceLogs"
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
|
@ -11168,6 +11476,9 @@ paths:
|
||||||
**Note**: This endpoint works only for services with the `local`,
|
**Note**: This endpoint works only for services with the `local`,
|
||||||
`json-file` or `journald` logging drivers.
|
`json-file` or `journald` logging drivers.
|
||||||
operationId: "TaskLogs"
|
operationId: "TaskLogs"
|
||||||
|
produces:
|
||||||
|
- "application/vnd.docker.raw-stream"
|
||||||
|
- "application/vnd.docker.multiplexed-stream"
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: "logs returned as a stream in response body"
|
description: "logs returned as a stream in response body"
|
||||||
|
|
|
@ -112,10 +112,16 @@ type NetworkListOptions struct {
|
||||||
Filters filters.Args
|
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.
|
// HijackedResponse holds connection information for a hijacked request.
|
||||||
type HijackedResponse struct {
|
type HijackedResponse struct {
|
||||||
Conn net.Conn
|
mediaType string
|
||||||
Reader *bufio.Reader
|
Conn net.Conn
|
||||||
|
Reader *bufio.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the hijacked connection and reader.
|
// Close closes the hijacked connection and reader.
|
||||||
|
@ -123,6 +129,15 @@ func (h *HijackedResponse) Close() {
|
||||||
h.Conn.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
|
// CloseWriter is an interface that implements structs
|
||||||
// that close input streams to prevent from writing.
|
// that close input streams to prevent from writing.
|
||||||
type CloseWriter interface {
|
type CloseWriter interface {
|
||||||
|
|
|
@ -17,6 +17,8 @@ const (
|
||||||
TypeTmpfs Type = "tmpfs"
|
TypeTmpfs Type = "tmpfs"
|
||||||
// TypeNamedPipe is the type for mounting Windows named pipes
|
// TypeNamedPipe is the type for mounting Windows named pipes
|
||||||
TypeNamedPipe Type = "npipe"
|
TypeNamedPipe Type = "npipe"
|
||||||
|
// TypeCluster is the type for Swarm Cluster Volumes.
|
||||||
|
TypeCluster = "csi"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Mount represents a mount (volume).
|
// Mount represents a mount (volume).
|
||||||
|
@ -30,9 +32,10 @@ type Mount struct {
|
||||||
ReadOnly bool `json:",omitempty"`
|
ReadOnly bool `json:",omitempty"`
|
||||||
Consistency Consistency `json:",omitempty"`
|
Consistency Consistency `json:",omitempty"`
|
||||||
|
|
||||||
BindOptions *BindOptions `json:",omitempty"`
|
BindOptions *BindOptions `json:",omitempty"`
|
||||||
VolumeOptions *VolumeOptions `json:",omitempty"`
|
VolumeOptions *VolumeOptions `json:",omitempty"`
|
||||||
TmpfsOptions *TmpfsOptions `json:",omitempty"`
|
TmpfsOptions *TmpfsOptions `json:",omitempty"`
|
||||||
|
ClusterOptions *ClusterOptions `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Propagation represents the propagation of a mount.
|
// 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
|
// Some of these may be straightforward to add, but others, such as
|
||||||
// uid/gid have implications in a clustered system.
|
// 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"`
|
Resources Resources `json:",omitempty"`
|
||||||
Engine EngineDescription `json:",omitempty"`
|
Engine EngineDescription `json:",omitempty"`
|
||||||
TLSInfo TLSInfo `json:",omitempty"`
|
TLSInfo TLSInfo `json:",omitempty"`
|
||||||
|
CSIInfo []NodeCSIInfo `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Platform represents the platform (Arch/OS).
|
// Platform represents the platform (Arch/OS).
|
||||||
|
@ -68,6 +69,21 @@ type EngineDescription struct {
|
||||||
Plugins []PluginDescription `json:",omitempty"`
|
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.
|
// PluginDescription represents the description of an engine plugin.
|
||||||
type PluginDescription struct {
|
type PluginDescription struct {
|
||||||
Type string `json:",omitempty"`
|
Type string `json:",omitempty"`
|
||||||
|
@ -113,3 +129,11 @@ const (
|
||||||
// NodeStateDisconnected DISCONNECTED
|
// NodeStateDisconnected DISCONNECTED
|
||||||
NodeStateDisconnected NodeState = "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
|
// used to determine which Tasks belong to which run of the job. This field
|
||||||
// is absent if the Service mode is Replicated or Global.
|
// is absent if the Service mode is Replicated or Global.
|
||||||
JobIteration *Version `json:",omitempty"`
|
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.
|
// TaskSpec represents the spec of a task.
|
||||||
|
@ -204,3 +209,17 @@ type ContainerStatus struct {
|
||||||
type PortStatus struct {
|
type PortStatus struct {
|
||||||
Ports []PortConfig `json:",omitempty"`
|
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"
|
"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.
|
// RootFS returns Image's RootFS description including the layer IDs.
|
||||||
type RootFS struct {
|
type RootFS struct {
|
||||||
Type string `json:",omitempty"`
|
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
|
// swagger:model CreateOptions
|
||||||
type CreateOptions struct {
|
type CreateOptions struct {
|
||||||
|
|
||||||
|
// cluster volume spec
|
||||||
|
ClusterVolumeSpec *ClusterVolumeSpec `json:"ClusterVolumeSpec,omitempty"`
|
||||||
|
|
||||||
// Name of the volume driver to use.
|
// Name of the volume driver to use.
|
||||||
Driver string `json:"Driver,omitempty"`
|
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
|
// swagger:model Volume
|
||||||
type Volume struct {
|
type Volume struct {
|
||||||
|
|
||||||
|
// cluster volume
|
||||||
|
ClusterVolume *ClusterVolume `json:"ClusterVolume,omitempty"`
|
||||||
|
|
||||||
// Date/Time the volume was created.
|
// Date/Time the volume was created.
|
||||||
CreatedAt string `json:"CreatedAt,omitempty"`
|
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")
|
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)
|
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
|
// and the a reader to get output. It's up to the called to close
|
||||||
// the hijacked connection by calling types.HijackedResponse.Close.
|
// the hijacked connection by calling types.HijackedResponse.Close.
|
||||||
func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error) {
|
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)
|
return cli.postHijacked(ctx, "/exec/"+execID+"/start", nil, config, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/docker/api/types/versions"
|
||||||
"github.com/docker/go-connections/sockets"
|
"github.com/docker/go-connections/sockets"
|
||||||
"github.com/pkg/errors"
|
"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)
|
req = cli.addHeaders(req, headers)
|
||||||
|
|
||||||
conn, err := cli.setupHijackConn(ctx, req, "tcp")
|
conn, mediaType, err := cli.setupHijackConn(ctx, req, "tcp")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.HijackedResponse{}, err
|
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.
|
// 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)
|
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.
|
// 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)
|
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.Host = cli.addr
|
||||||
req.Header.Set("Connection", "Upgrade")
|
req.Header.Set("Connection", "Upgrade")
|
||||||
req.Header.Set("Upgrade", proto)
|
req.Header.Set("Upgrade", proto)
|
||||||
|
@ -69,7 +71,7 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto
|
||||||
dialer := cli.Dialer()
|
dialer := cli.Dialer()
|
||||||
conn, err := dialer(ctx)
|
conn, err := dialer(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "cannot connect to the Docker daemon. Is 'docker daemon' running on this host?")
|
return nil, "", errors.Wrap(err, "cannot connect to the Docker daemon. Is 'docker daemon' running on this host?")
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we set up a TCP connection for hijack, there could be long periods
|
// 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
|
//nolint:staticcheck // ignore SA1019 for connecting to old (pre go1.8) daemons
|
||||||
if err != httputil.ErrPersistEOF {
|
if err != httputil.ErrPersistEOF {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusSwitchingProtocols {
|
if resp.StatusCode != http.StatusSwitchingProtocols {
|
||||||
resp.Body.Close()
|
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()
|
c, br := clientconn.Hijack()
|
||||||
if br.Buffered() > 0 {
|
if br.Buffered() > 0 {
|
||||||
// If there is buffered content, wrap the connection. We return an
|
// 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.
|
// implements it.
|
||||||
if _, ok := c.(types.CloseWriter); ok {
|
if _, ok := c.(types.CloseWriter); ok {
|
||||||
c = &hijackedConnCloseWriter{&hijackedConn{c, br}}
|
c = &hijackedConnCloseWriter{&hijackedConn{c, br}}
|
||||||
|
@ -113,7 +115,13 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto
|
||||||
br.Reset(nil)
|
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
|
// 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)
|
VolumeList(ctx context.Context, filter filters.Args) (volume.ListResponse, error)
|
||||||
VolumeRemove(ctx context.Context, volumeID string, force bool) error
|
VolumeRemove(ctx context.Context, volumeID string, force bool) error
|
||||||
VolumesPrune(ctx context.Context, pruneFilter filters.Args) (types.VolumesPruneReport, 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
|
// 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)
|
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.
|
// putRaw sends an http request to the docker API using the method PUT.
|
||||||
func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) {
|
func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) {
|
||||||
return cli.sendRequest(ctx, http.MethodPut, path, query, body, headers)
|
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
|
||||||
github.com/docker/distribution/registry/storage/cache/memory
|
github.com/docker/distribution/registry/storage/cache/memory
|
||||||
github.com/docker/distribution/uuid
|
github.com/docker/distribution/uuid
|
||||||
# github.com/docker/docker 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
|
## explicit
|
||||||
github.com/docker/docker/api
|
github.com/docker/docker/api
|
||||||
github.com/docker/docker/api/types
|
github.com/docker/docker/api/types
|
||||||
|
@ -390,6 +390,6 @@ gotest.tools/v3/internal/format
|
||||||
gotest.tools/v3/internal/source
|
gotest.tools/v3/internal/source
|
||||||
gotest.tools/v3/poll
|
gotest.tools/v3/poll
|
||||||
gotest.tools/v3/skip
|
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/gogo/googleapis => github.com/gogo/googleapis v1.3.2
|
||||||
# github.com/google/certificate-transparency-go => github.com/google/certificate-transparency-go v1.0.20
|
# github.com/google/certificate-transparency-go => github.com/google/certificate-transparency-go v1.0.20
|
||||||
|
|
Loading…
Reference in New Issue