mirror of https://github.com/docker/cli.git
vendor: github.com/docker/docker 25.0.4-51e876cd96
full diff: https://github.com/docker/docker/compare/v25.0.3...51e876cd964c4bb1f0a7c1bc24ecab9321b3ff1c Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
parent
a5937c6043
commit
0735e78cc9
|
@ -5,7 +5,6 @@
|
||||||
"RepoDigests": null,
|
"RepoDigests": null,
|
||||||
"Parent": "",
|
"Parent": "",
|
||||||
"Comment": "",
|
"Comment": "",
|
||||||
"Created": "",
|
|
||||||
"Container": "",
|
"Container": "",
|
||||||
"ContainerConfig": null,
|
"ContainerConfig": null,
|
||||||
"DockerVersion": "",
|
"DockerVersion": "",
|
||||||
|
@ -29,7 +28,6 @@
|
||||||
"RepoDigests": null,
|
"RepoDigests": null,
|
||||||
"Parent": "",
|
"Parent": "",
|
||||||
"Comment": "",
|
"Comment": "",
|
||||||
"Created": "",
|
|
||||||
"Container": "",
|
"Container": "",
|
||||||
"ContainerConfig": null,
|
"ContainerConfig": null,
|
||||||
"DockerVersion": "",
|
"DockerVersion": "",
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
"RepoDigests": null,
|
"RepoDigests": null,
|
||||||
"Parent": "",
|
"Parent": "",
|
||||||
"Comment": "",
|
"Comment": "",
|
||||||
"Created": "",
|
|
||||||
"Container": "",
|
"Container": "",
|
||||||
"ContainerConfig": null,
|
"ContainerConfig": null,
|
||||||
"DockerVersion": "",
|
"DockerVersion": "",
|
||||||
|
|
|
@ -12,7 +12,7 @@ require (
|
||||||
github.com/creack/pty v1.1.21
|
github.com/creack/pty v1.1.21
|
||||||
github.com/distribution/reference v0.5.0
|
github.com/distribution/reference v0.5.0
|
||||||
github.com/docker/distribution v2.8.3+incompatible
|
github.com/docker/distribution v2.8.3+incompatible
|
||||||
github.com/docker/docker v25.0.3+incompatible
|
github.com/docker/docker v25.0.4-0.20240301160236-51e876cd964c+incompatible // 25.0 branch (v25.0.4-dev)
|
||||||
github.com/docker/docker-credential-helpers v0.8.1
|
github.com/docker/docker-credential-helpers v0.8.1
|
||||||
github.com/docker/go-connections v0.5.0
|
github.com/docker/go-connections v0.5.0
|
||||||
github.com/docker/go-units v0.5.0
|
github.com/docker/go-units v0.5.0
|
||||||
|
|
|
@ -54,8 +54,8 @@ github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5
|
||||||
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.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v25.0.3+incompatible h1:D5fy/lYmY7bvZa0XTZ5/UJPljor41F+vdyJG5luQLfQ=
|
github.com/docker/docker v25.0.4-0.20240301160236-51e876cd964c+incompatible h1:sCE9u4l5Kr3Z0pvUEAC6XKe/wnH6Q4O19I/0Mcqlxz8=
|
||||||
github.com/docker/docker v25.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v25.0.4-0.20240301160236-51e876cd964c+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo=
|
github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo=
|
||||||
github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
||||||
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=
|
||||||
|
|
|
@ -391,7 +391,11 @@ definitions:
|
||||||
ReadOnlyNonRecursive:
|
ReadOnlyNonRecursive:
|
||||||
description: |
|
description: |
|
||||||
Make the mount non-recursively read-only, but still leave the mount recursive
|
Make the mount non-recursively read-only, but still leave the mount recursive
|
||||||
(unless NonRecursive is set to true in conjunction).
|
(unless NonRecursive is set to `true` in conjunction).
|
||||||
|
|
||||||
|
Addded in v1.44, before that version all read-only mounts were
|
||||||
|
non-recursive by default. To match the previous behaviour this
|
||||||
|
will default to `true` for clients on versions prior to v1.44.
|
||||||
type: "boolean"
|
type: "boolean"
|
||||||
default: false
|
default: false
|
||||||
ReadOnlyForceRecursive:
|
ReadOnlyForceRecursive:
|
||||||
|
@ -1743,8 +1747,12 @@ definitions:
|
||||||
description: |
|
description: |
|
||||||
Date and time at which the image was created, formatted in
|
Date and time at which the image was created, formatted in
|
||||||
[RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.
|
[RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.
|
||||||
|
|
||||||
|
This information is only available if present in the image,
|
||||||
|
and omitted otherwise.
|
||||||
type: "string"
|
type: "string"
|
||||||
x-nullable: false
|
format: "dateTime"
|
||||||
|
x-nullable: true
|
||||||
example: "2022-02-04T21:20:12.497794809Z"
|
example: "2022-02-04T21:20:12.497794809Z"
|
||||||
Container:
|
Container:
|
||||||
description: |
|
description: |
|
||||||
|
|
|
@ -72,7 +72,10 @@ type ImageInspect struct {
|
||||||
|
|
||||||
// Created is the date and time at which the image was created, formatted in
|
// Created is the date and time at which the image was created, formatted in
|
||||||
// RFC 3339 nano-seconds (time.RFC3339Nano).
|
// RFC 3339 nano-seconds (time.RFC3339Nano).
|
||||||
Created string
|
//
|
||||||
|
// This information is only available if present in the image,
|
||||||
|
// and omitted otherwise.
|
||||||
|
Created string `json:",omitempty"`
|
||||||
|
|
||||||
// Container is the ID of the container that was used to create the image.
|
// Container is the ID of the container that was used to create the image.
|
||||||
//
|
//
|
||||||
|
|
|
@ -265,17 +265,22 @@ func (cli *Client) Close() error {
|
||||||
// This allows for version-dependent code to use the same version as will
|
// This allows for version-dependent code to use the same version as will
|
||||||
// be negotiated when making the actual requests, and for which cases
|
// be negotiated when making the actual requests, and for which cases
|
||||||
// we cannot do the negotiation lazily.
|
// we cannot do the negotiation lazily.
|
||||||
func (cli *Client) checkVersion(ctx context.Context) {
|
func (cli *Client) checkVersion(ctx context.Context) error {
|
||||||
if cli.negotiateVersion && !cli.negotiated {
|
if !cli.manualOverride && cli.negotiateVersion && !cli.negotiated {
|
||||||
cli.NegotiateAPIVersion(ctx)
|
ping, err := cli.Ping(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cli.negotiateAPIVersionPing(ping)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getAPIPath returns the versioned request path to call the API.
|
// getAPIPath returns the versioned request path to call the API.
|
||||||
// It appends the query parameters to the path if they are not empty.
|
// It appends the query parameters to the path if they are not empty.
|
||||||
func (cli *Client) getAPIPath(ctx context.Context, p string, query url.Values) string {
|
func (cli *Client) getAPIPath(ctx context.Context, p string, query url.Values) string {
|
||||||
var apiPath string
|
var apiPath string
|
||||||
cli.checkVersion(ctx)
|
_ = cli.checkVersion(ctx)
|
||||||
if cli.version != "" {
|
if cli.version != "" {
|
||||||
v := strings.TrimPrefix(cli.version, "v")
|
v := strings.TrimPrefix(cli.version, "v")
|
||||||
apiPath = path.Join(cli.basePath, "/v"+v, p)
|
apiPath = path.Join(cli.basePath, "/v"+v, p)
|
||||||
|
@ -307,7 +312,11 @@ func (cli *Client) ClientVersion() string {
|
||||||
// added (1.24).
|
// added (1.24).
|
||||||
func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
|
func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
|
||||||
if !cli.manualOverride {
|
if !cli.manualOverride {
|
||||||
ping, _ := cli.Ping(ctx)
|
ping, err := cli.Ping(ctx)
|
||||||
|
if err != nil {
|
||||||
|
// FIXME(thaJeztah): Ping returns an error when failing to connect to the API; we should not swallow the error here, and instead returning it.
|
||||||
|
return
|
||||||
|
}
|
||||||
cli.negotiateAPIVersionPing(ping)
|
cli.negotiateAPIVersionPing(ping)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,9 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config
|
||||||
//
|
//
|
||||||
// Normally, version-negotiation (if enabled) would not happen until
|
// Normally, version-negotiation (if enabled) would not happen until
|
||||||
// the API request is made.
|
// the API request is made.
|
||||||
cli.checkVersion(ctx)
|
if err := cli.checkVersion(ctx); err != nil {
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
if err := cli.NewVersionError(ctx, "1.25", "stop timeout"); config != nil && config.StopTimeout != nil && err != nil {
|
if err := cli.NewVersionError(ctx, "1.25", "stop timeout"); config != nil && config.StopTimeout != nil && err != nil {
|
||||||
return response, err
|
return response, err
|
||||||
|
|
|
@ -18,7 +18,9 @@ func (cli *Client) ContainerExecCreate(ctx context.Context, container string, co
|
||||||
//
|
//
|
||||||
// Normally, version-negotiation (if enabled) would not happen until
|
// Normally, version-negotiation (if enabled) would not happen until
|
||||||
// the API request is made.
|
// the API request is made.
|
||||||
cli.checkVersion(ctx)
|
if err := cli.checkVersion(ctx); err != nil {
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
if err := cli.NewVersionError(ctx, "1.25", "env"); len(config.Env) != 0 && err != nil {
|
if err := cli.NewVersionError(ctx, "1.25", "env"); len(config.Env) != 0 && err != nil {
|
||||||
return response, err
|
return response, err
|
||||||
|
|
|
@ -23,7 +23,9 @@ func (cli *Client) ContainerRestart(ctx context.Context, containerID string, opt
|
||||||
//
|
//
|
||||||
// Normally, version-negotiation (if enabled) would not happen until
|
// Normally, version-negotiation (if enabled) would not happen until
|
||||||
// the API request is made.
|
// the API request is made.
|
||||||
cli.checkVersion(ctx)
|
if err := cli.checkVersion(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if versions.GreaterThanOrEqualTo(cli.version, "1.42") {
|
if versions.GreaterThanOrEqualTo(cli.version, "1.42") {
|
||||||
query.Set("signal", options.Signal)
|
query.Set("signal", options.Signal)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,9 @@ func (cli *Client) ContainerStop(ctx context.Context, containerID string, option
|
||||||
//
|
//
|
||||||
// Normally, version-negotiation (if enabled) would not happen until
|
// Normally, version-negotiation (if enabled) would not happen until
|
||||||
// the API request is made.
|
// the API request is made.
|
||||||
cli.checkVersion(ctx)
|
if err := cli.checkVersion(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if versions.GreaterThanOrEqualTo(cli.version, "1.42") {
|
if versions.GreaterThanOrEqualTo(cli.version, "1.42") {
|
||||||
query.Set("signal", options.Signal)
|
query.Set("signal", options.Signal)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,19 +30,22 @@ const containerWaitErrorMsgLimit = 2 * 1024 /* Max: 2KiB */
|
||||||
// synchronize ContainerWait with other calls, such as specifying a
|
// synchronize ContainerWait with other calls, such as specifying a
|
||||||
// "next-exit" condition before issuing a ContainerStart request.
|
// "next-exit" condition before issuing a ContainerStart request.
|
||||||
func (cli *Client) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) {
|
func (cli *Client) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) {
|
||||||
|
resultC := make(chan container.WaitResponse)
|
||||||
|
errC := make(chan error, 1)
|
||||||
|
|
||||||
// Make sure we negotiated (if the client is configured to do so),
|
// Make sure we negotiated (if the client is configured to do so),
|
||||||
// as code below contains API-version specific handling of options.
|
// as code below contains API-version specific handling of options.
|
||||||
//
|
//
|
||||||
// Normally, version-negotiation (if enabled) would not happen until
|
// Normally, version-negotiation (if enabled) would not happen until
|
||||||
// the API request is made.
|
// the API request is made.
|
||||||
cli.checkVersion(ctx)
|
if err := cli.checkVersion(ctx); err != nil {
|
||||||
|
errC <- err
|
||||||
|
return resultC, errC
|
||||||
|
}
|
||||||
if versions.LessThan(cli.ClientVersion(), "1.30") {
|
if versions.LessThan(cli.ClientVersion(), "1.30") {
|
||||||
return cli.legacyContainerWait(ctx, containerID)
|
return cli.legacyContainerWait(ctx, containerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
resultC := make(chan container.WaitResponse)
|
|
||||||
errC := make(chan error, 1)
|
|
||||||
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
if condition != "" {
|
if condition != "" {
|
||||||
query.Set("condition", string(condition))
|
query.Set("condition", string(condition))
|
||||||
|
|
|
@ -11,15 +11,16 @@ import (
|
||||||
|
|
||||||
// errConnectionFailed implements an error returned when connection failed.
|
// errConnectionFailed implements an error returned when connection failed.
|
||||||
type errConnectionFailed struct {
|
type errConnectionFailed struct {
|
||||||
host string
|
error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error returns a string representation of an errConnectionFailed
|
// Error returns a string representation of an errConnectionFailed
|
||||||
func (err errConnectionFailed) Error() string {
|
func (e errConnectionFailed) Error() string {
|
||||||
if err.host == "" {
|
return e.error.Error()
|
||||||
return "Cannot connect to the Docker daemon. Is the docker daemon running on this host?"
|
}
|
||||||
}
|
|
||||||
return fmt.Sprintf("Cannot connect to the Docker daemon at %s. Is the docker daemon running?", err.host)
|
func (e errConnectionFailed) Unwrap() error {
|
||||||
|
return e.error
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsErrConnectionFailed returns true if the error is caused by connection failed.
|
// IsErrConnectionFailed returns true if the error is caused by connection failed.
|
||||||
|
@ -29,7 +30,13 @@ func IsErrConnectionFailed(err error) bool {
|
||||||
|
|
||||||
// ErrorConnectionFailed returns an error with host in the error message when connection to docker daemon failed.
|
// ErrorConnectionFailed returns an error with host in the error message when connection to docker daemon failed.
|
||||||
func ErrorConnectionFailed(host string) error {
|
func ErrorConnectionFailed(host string) error {
|
||||||
return errConnectionFailed{host: host}
|
var err error
|
||||||
|
if host == "" {
|
||||||
|
err = fmt.Errorf("Cannot connect to the Docker daemon. Is the docker daemon running on this host?")
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("Cannot connect to the Docker daemon at %s. Is the docker daemon running?", host)
|
||||||
|
}
|
||||||
|
return errConnectionFailed{error: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsErrNotFound returns true if the error is a NotFound error, which is returned
|
// IsErrNotFound returns true if the error is a NotFound error, which is returned
|
||||||
|
@ -60,7 +67,9 @@ func (cli *Client) NewVersionError(ctx context.Context, APIrequired, feature str
|
||||||
//
|
//
|
||||||
// Normally, version-negotiation (if enabled) would not happen until
|
// Normally, version-negotiation (if enabled) would not happen until
|
||||||
// the API request is made.
|
// the API request is made.
|
||||||
cli.checkVersion(ctx)
|
if err := cli.checkVersion(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if cli.version != "" && versions.LessThan(cli.version, APIrequired) {
|
if cli.version != "" && versions.LessThan(cli.version, APIrequired) {
|
||||||
return fmt.Errorf("%q requires API version %s, but the Docker daemon API version is %s", feature, APIrequired, cli.version)
|
return fmt.Errorf("%q requires API version %s, but the Docker daemon API version is %s", feature, APIrequired, cli.version)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,17 @@ import (
|
||||||
|
|
||||||
// ImageList returns a list of images in the docker host.
|
// ImageList returns a list of images in the docker host.
|
||||||
func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions) ([]image.Summary, error) {
|
func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions) ([]image.Summary, error) {
|
||||||
|
var images []image.Summary
|
||||||
|
|
||||||
// Make sure we negotiated (if the client is configured to do so),
|
// Make sure we negotiated (if the client is configured to do so),
|
||||||
// as code below contains API-version specific handling of options.
|
// as code below contains API-version specific handling of options.
|
||||||
//
|
//
|
||||||
// Normally, version-negotiation (if enabled) would not happen until
|
// Normally, version-negotiation (if enabled) would not happen until
|
||||||
// the API request is made.
|
// the API request is made.
|
||||||
cli.checkVersion(ctx)
|
if err := cli.checkVersion(ctx); err != nil {
|
||||||
|
return images, err
|
||||||
|
}
|
||||||
|
|
||||||
var images []image.Summary
|
|
||||||
query := url.Values{}
|
query := url.Values{}
|
||||||
|
|
||||||
optionFilters := options.Filters
|
optionFilters := options.Filters
|
||||||
|
|
|
@ -10,12 +10,16 @@ import (
|
||||||
|
|
||||||
// NetworkCreate creates a new network in the docker host.
|
// NetworkCreate creates a new network in the docker host.
|
||||||
func (cli *Client) NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) {
|
func (cli *Client) NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) {
|
||||||
|
var response types.NetworkCreateResponse
|
||||||
|
|
||||||
// Make sure we negotiated (if the client is configured to do so),
|
// Make sure we negotiated (if the client is configured to do so),
|
||||||
// as code below contains API-version specific handling of options.
|
// as code below contains API-version specific handling of options.
|
||||||
//
|
//
|
||||||
// Normally, version-negotiation (if enabled) would not happen until
|
// Normally, version-negotiation (if enabled) would not happen until
|
||||||
// the API request is made.
|
// the API request is made.
|
||||||
cli.checkVersion(ctx)
|
if err := cli.checkVersion(ctx); err != nil {
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
networkCreateRequest := types.NetworkCreateRequest{
|
networkCreateRequest := types.NetworkCreateRequest{
|
||||||
NetworkCreate: options,
|
NetworkCreate: options,
|
||||||
|
@ -25,7 +29,6 @@ func (cli *Client) NetworkCreate(ctx context.Context, name string, options types
|
||||||
networkCreateRequest.CheckDuplicate = true //nolint:staticcheck // ignore SA1019: CheckDuplicate is deprecated since API v1.44.
|
networkCreateRequest.CheckDuplicate = true //nolint:staticcheck // ignore SA1019: CheckDuplicate is deprecated since API v1.44.
|
||||||
}
|
}
|
||||||
|
|
||||||
var response types.NetworkCreateResponse
|
|
||||||
serverResp, err := cli.post(ctx, "/networks/create", nil, networkCreateRequest, nil)
|
serverResp, err := cli.post(ctx, "/networks/create", nil, networkCreateRequest, nil)
|
||||||
defer ensureReaderClosed(serverResp)
|
defer ensureReaderClosed(serverResp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -14,7 +14,10 @@ import (
|
||||||
// Ping pings the server and returns the value of the "Docker-Experimental",
|
// Ping pings the server and returns the value of the "Docker-Experimental",
|
||||||
// "Builder-Version", "OS-Type" & "API-Version" headers. It attempts to use
|
// "Builder-Version", "OS-Type" & "API-Version" headers. It attempts to use
|
||||||
// a HEAD request on the endpoint, but falls back to GET if HEAD is not supported
|
// a HEAD request on the endpoint, but falls back to GET if HEAD is not supported
|
||||||
// by the daemon.
|
// by the daemon. It ignores internal server errors returned by the API, which
|
||||||
|
// may be returned if the daemon is in an unhealthy state, but returns errors
|
||||||
|
// for other non-success status codes, failing to connect to the API, or failing
|
||||||
|
// to parse the API response.
|
||||||
func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
||||||
var ping types.Ping
|
var ping types.Ping
|
||||||
|
|
||||||
|
|
|
@ -134,17 +134,18 @@ func (cli *Client) sendRequest(ctx context.Context, method, path string, query u
|
||||||
return resp, errdefs.FromStatusCode(err, resp.statusCode)
|
return resp, errdefs.FromStatusCode(err, resp.statusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(thaJeztah): Should this actually return a serverResp when a connection error occurred?
|
||||||
func (cli *Client) doRequest(req *http.Request) (serverResponse, error) {
|
func (cli *Client) doRequest(req *http.Request) (serverResponse, error) {
|
||||||
serverResp := serverResponse{statusCode: -1, reqURL: req.URL}
|
serverResp := serverResponse{statusCode: -1, reqURL: req.URL}
|
||||||
|
|
||||||
resp, err := cli.client.Do(req)
|
resp, err := cli.client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if cli.scheme != "https" && strings.Contains(err.Error(), "malformed HTTP response") {
|
if cli.scheme != "https" && strings.Contains(err.Error(), "malformed HTTP response") {
|
||||||
return serverResp, fmt.Errorf("%v.\n* Are you trying to connect to a TLS-enabled daemon without TLS?", err)
|
return serverResp, errConnectionFailed{fmt.Errorf("%v.\n* Are you trying to connect to a TLS-enabled daemon without TLS?", err)}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cli.scheme == "https" && strings.Contains(err.Error(), "bad certificate") {
|
if cli.scheme == "https" && strings.Contains(err.Error(), "bad certificate") {
|
||||||
return serverResp, errors.Wrap(err, "the server probably has client authentication (--tlsverify) enabled; check your TLS client certification settings")
|
return serverResp, errConnectionFailed{errors.Wrap(err, "the server probably has client authentication (--tlsverify) enabled; check your TLS client certification settings")}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't decorate context sentinel errors; users may be comparing to
|
// Don't decorate context sentinel errors; users may be comparing to
|
||||||
|
@ -156,12 +157,13 @@ func (cli *Client) doRequest(req *http.Request) (serverResponse, error) {
|
||||||
if uErr, ok := err.(*url.Error); ok {
|
if uErr, ok := err.(*url.Error); ok {
|
||||||
if nErr, ok := uErr.Err.(*net.OpError); ok {
|
if nErr, ok := uErr.Err.(*net.OpError); ok {
|
||||||
if os.IsPermission(nErr.Err) {
|
if os.IsPermission(nErr.Err) {
|
||||||
return serverResp, errors.Wrapf(err, "permission denied while trying to connect to the Docker daemon socket at %v", cli.host)
|
return serverResp, errConnectionFailed{errors.Wrapf(err, "permission denied while trying to connect to the Docker daemon socket at %v", cli.host)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if nErr, ok := err.(net.Error); ok {
|
if nErr, ok := err.(net.Error); ok {
|
||||||
|
// FIXME(thaJeztah): any net.Error should be considered a connection error (but we should include the original error)?
|
||||||
if nErr.Timeout() {
|
if nErr.Timeout() {
|
||||||
return serverResp, ErrorConnectionFailed(cli.host)
|
return serverResp, ErrorConnectionFailed(cli.host)
|
||||||
}
|
}
|
||||||
|
@ -190,7 +192,7 @@ func (cli *Client) doRequest(req *http.Request) (serverResponse, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return serverResp, errors.Wrap(err, "error during connect")
|
return serverResp, errConnectionFailed{errors.Wrap(err, "error during connect")}
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp != nil {
|
if resp != nil {
|
||||||
|
|
|
@ -25,7 +25,9 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec,
|
||||||
//
|
//
|
||||||
// Normally, version-negotiation (if enabled) would not happen until
|
// Normally, version-negotiation (if enabled) would not happen until
|
||||||
// the API request is made.
|
// the API request is made.
|
||||||
cli.checkVersion(ctx)
|
if err := cli.checkVersion(ctx); err != nil {
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure containerSpec is not nil when no runtime is set or the runtime is set to container
|
// Make sure containerSpec is not nil when no runtime is set or the runtime is set to container
|
||||||
if service.TaskTemplate.ContainerSpec == nil && (service.TaskTemplate.Runtime == "" || service.TaskTemplate.Runtime == swarm.RuntimeContainer) {
|
if service.TaskTemplate.ContainerSpec == nil && (service.TaskTemplate.Runtime == "" || service.TaskTemplate.Runtime == swarm.RuntimeContainer) {
|
||||||
|
|
|
@ -16,18 +16,18 @@ import (
|
||||||
// It should be the value as set *before* the update. You can find this value in the Meta field
|
// It should be the value as set *before* the update. You can find this value in the Meta field
|
||||||
// of swarm.Service, which can be found using ServiceInspectWithRaw.
|
// of swarm.Service, which can be found using ServiceInspectWithRaw.
|
||||||
func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
||||||
|
response := swarm.ServiceUpdateResponse{}
|
||||||
|
|
||||||
// Make sure we negotiated (if the client is configured to do so),
|
// Make sure we negotiated (if the client is configured to do so),
|
||||||
// as code below contains API-version specific handling of options.
|
// as code below contains API-version specific handling of options.
|
||||||
//
|
//
|
||||||
// Normally, version-negotiation (if enabled) would not happen until
|
// Normally, version-negotiation (if enabled) would not happen until
|
||||||
// the API request is made.
|
// the API request is made.
|
||||||
cli.checkVersion(ctx)
|
if err := cli.checkVersion(ctx); err != nil {
|
||||||
|
return response, err
|
||||||
var (
|
}
|
||||||
query = url.Values{}
|
|
||||||
response = swarm.ServiceUpdateResponse{}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
query := url.Values{}
|
||||||
if options.RegistryAuthFrom != "" {
|
if options.RegistryAuthFrom != "" {
|
||||||
query.Set("registryAuthFrom", options.RegistryAuthFrom)
|
query.Set("registryAuthFrom", options.RegistryAuthFrom)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,9 @@ func (cli *Client) VolumeRemove(ctx context.Context, volumeID string, force bool
|
||||||
//
|
//
|
||||||
// Normally, version-negotiation (if enabled) would not happen until
|
// Normally, version-negotiation (if enabled) would not happen until
|
||||||
// the API request is made.
|
// the API request is made.
|
||||||
cli.checkVersion(ctx)
|
if err := cli.checkVersion(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if versions.GreaterThanOrEqualTo(cli.version, "1.25") {
|
if versions.GreaterThanOrEqualTo(cli.version, "1.25") {
|
||||||
query.Set("force", "1")
|
query.Set("force", "1")
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/jsonmessage"
|
"github.com/docker/docker/pkg/jsonmessage"
|
||||||
"github.com/docker/docker/pkg/progress"
|
"github.com/docker/docker/pkg/progress"
|
||||||
|
@ -109,6 +110,7 @@ type progressOutput struct {
|
||||||
sf formatProgress
|
sf formatProgress
|
||||||
out io.Writer
|
out io.Writer
|
||||||
newLines bool
|
newLines bool
|
||||||
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteProgress formats progress information from a ProgressReader.
|
// WriteProgress formats progress information from a ProgressReader.
|
||||||
|
@ -120,6 +122,9 @@ func (out *progressOutput) WriteProgress(prog progress.Progress) error {
|
||||||
jsonProgress := jsonmessage.JSONProgress{Current: prog.Current, Total: prog.Total, HideCounts: prog.HideCounts, Units: prog.Units}
|
jsonProgress := jsonmessage.JSONProgress{Current: prog.Current, Total: prog.Total, HideCounts: prog.HideCounts, Units: prog.Units}
|
||||||
formatted = out.sf.formatProgress(prog.ID, prog.Action, &jsonProgress, prog.Aux)
|
formatted = out.sf.formatProgress(prog.ID, prog.Action, &jsonProgress, prog.Aux)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out.mu.Lock()
|
||||||
|
defer out.mu.Unlock()
|
||||||
_, err := out.out.Write(formatted)
|
_, err := out.out.Write(formatted)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -53,7 +53,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 v25.0.3+incompatible
|
# github.com/docker/docker v25.0.4-0.20240301160236-51e876cd964c+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
|
||||||
|
|
Loading…
Reference in New Issue