23 Commits

Author SHA1 Message Date
Sebastiaan van Stijn
29ad05b130 client: ContainerWaitResult: use singular for channels
These channels should ever only return a single result, so rename
them to match that expectation.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-29 12:37:46 +01:00
Sebastiaan van Stijn
51a0584088 client: ContainerWait: touch-up GoDoc, remove legacy code
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-29 12:37:42 +01:00
Austin Vazquez
cf173bc941 client: refactor ContainerWait to use client defined options/results structs
Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
2025-10-28 18:15:01 -05:00
Sebastiaan van Stijn
7652f38c28 client: remove API-version compatibility for API < v1.44
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-08 23:43:59 +02:00
Sebastiaan van Stijn
195a6bbb1e client: touch-up godoc
Not perfect yet, but addressing some godoc "doc" links that needed
to be updated, and touching up some references.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-02 17:12:05 +02:00
Derek McGowan
afd6487b2e Create github.com/moby/moby/api module
Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-07-21 09:30:05 -07:00
Sebastiaan van Stijn
4856e8ffad client: remove // import comments
These comments were added to enforce using the correct import path for
our packages ("github.com/docker/docker", not "github.com/moby/moby").
However, when working in go module mode (not GOPATH / vendor), they have
no effect, so their impact is limited.

Remove these imports in preparation of migrating our code to become an
actual go module.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-05-30 15:59:10 +02:00
Sebastiaan van Stijn
72c91e378d client: remove serverResponse and use http.Response directly
Looking in history to learn why this struct existed, shows that this type
was mostly the result of tech-debt accumulating over time;

- originally ([moby@1aa7f13]) most of the request handling was internal;
  the [`call()` function][1] would make a request, read the `response.Body`,
  and return it as a `[]byte` (or an error if one happened).
- some features needed the statuscode, so [moby@a4bcf7e] added an extra
  output variable to return the `response.StatusCode`.
- some new features required streaming, so [moby@fdd8d4b] changed the
  function to return the `response.Body` as a `io.ReadCloser`, instead
  of a `[]byte`.
- some features needed access to the content-type header, so a new
  `clientRequest` method was introduced in [moby@6b2eeaf] to read the
  `Content-Type` header from `response.Headers` and return it as a string.
- of course, `Content-Type` may not be the only header needed, so [moby@0cdc3b7]
  changed the signature to return `response.Headers` as a whole as a
  `http.Header`
- things became a bit unwieldy now, with the function having four (4) output
  variables, so [moby@126529c] chose to refactor this code, introducing a
  `serverResponse` struct to wrap them all, not realizing that all these
  values were effectively deconstructed from the `url.Response`, so now
  re-assembling them into our own "URL response", only preserving a subset
  of the information available.
- now that we had a custom struct, it was possible to add more information
  to it without changing the signature. When there was a need to know the
  URL of the request that initiated the response, [moby@27ef09a] introduced
  a `reqURL` field to hold the `request.URL` which notably also is available
  in `response.Request.URL`.

In short;

- The original implementation tried to (pre-maturely) abstract the underlying
  response to provide a simplified interface.
- While initially not needed, abstracting caused relevant information from
  the response (and request) to be unavailable to callers.
- As a result, we ended up in a situation where we are deconstructing the
  original `url.Response`, only to re-assemble it into our own, custom struct
  (`serverResponsee`) with only a subset of the information preserved.

This patch removes the `serverResponse` struct, instead returning the
`url.Response` as-is, so that all information is preserved, allowing callers
to use the information they need.

There is one follow-up change to consider; commit [moby@589df17] introduced
a `ensureReaderClosed` utility. Before that commit, the response body would
be closed in a more idiomatic way through a [`defer serverResp.body.Close()`][2].
A later change in [docker/engine-api@5dd6452] added an optimization to that
utility, draining the response to allow connections to be reused. While
skipping that utility (and not draining the response) would not be a critical
issue, it may be easy to overlook that utility, and to close the response
body in the "idiomatic" way, resulting in a possible performance regression.

We need to check if that optimization is still relevant or if later changes
in Go itself already take care of this; we should also look if context
cancellation is handled correctly for these. If it's still relevant, we could

- Wrap the the `url.Response` in a custom struct ("drainCloser") to provide
  a `Close()` function handling the draining and closing; this would re-
  introduce a custom type to be returned, so perhaps not what we want.
- Wrap the `url.Response.Body` in the response returned (so, calling)
  `response.Body.Close()` would call the wrapped closer.
- Change the signature of `Client.sendRequest()` (and related) to return
  a `close()` func to handle this; doing so would more strongly encourage
  callers to close the response body.

[1]: 1aa7f1392d/commands.go (L1008-L1027)
[2]: 589df17a1a/api/client/ps.go (L84-L89)
[moby@1aa7f13]: 1aa7f1392d
[moby@a4bcf7e]: a4bcf7e1ac
[moby@fdd8d4b]: fdd8d4b7d9
[moby@6b2eeaf]: 6b2eeaf896
[moby@0cdc3b7]: 0cdc3b7539
[moby@126529c]: 126529c6d0
[moby@27ef09a]: 27ef09a46f
[moby@589df17]: 589df17a1a
[docker/engine-api@5dd6452]: 5dd6452d4d

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-02-11 13:20:27 +01:00
Sebastiaan van Stijn
329b2a26f3 client: normalize and validate empty ID / name arguments to fail early
In situations where an empty ID was passed, the client would construct an
invalid API endpoint URL, which either resulted in the "not found" handler
being hit (resulting in a "page not found" error), or even the wrong endpoint
being hit if the client follows redirects.

For example, `/containers/<empty id>/json` (inspect) redirects to `/containers/json`
(docker ps))

Given that empty IDs should never be expected (especially if they're part of
the API URL path), we can validate these and return early.

Its worth noting that a few methods already had an error in place; those
methods were related to the situation mentioned above, where (e.g.) an
"inspect" would redirect to a "list" endpoint. The existing errors, for
convenience, mimicked a "not found" error; this patch changes such errors
to an "Invalid Parameter" instead, which is more correct, but it could be
a breaking change for some edge cases where users parsed the output;

    git grep 'objectNotFoundError{'
    client/config_inspect.go:        return swarm.Config{}, nil, objectNotFoundError{object: "config", id: id}
    client/container_inspect.go:     return container.InspectResponse{}, nil, objectNotFoundError{object: "container", id: containerID}
    client/container_inspect.go:     return container.InspectResponse{}, objectNotFoundError{object: "container", id: containerID}
    client/distribution_inspect.go:  return distributionInspect, objectNotFoundError{object: "distribution", id: imageRef}
    client/image_inspect.go:         return image.InspectResponse{}, nil, objectNotFoundError{object: "image", id: imageID}
    client/network_inspect.go:       return network.Inspect{}, nil, objectNotFoundError{object: "network", id: networkID}
    client/node_inspect.go:          return swarm.Node{}, nil, objectNotFoundError{object: "node", id: nodeID}
    client/plugin_inspect.go:        return nil, nil, objectNotFoundError{object: "plugin", id: name}
    client/secret_inspect.go:        return swarm.Secret{}, nil, objectNotFoundError{object: "secret", id: id}
    client/service_inspect.go:       return swarm.Service{}, nil, objectNotFoundError{object: "service", id: serviceID}
    client/task_inspect.go:          return swarm.Task{}, nil, objectNotFoundError{object: "task", id: taskID}
    client/volume_inspect.go:        return volume.Volume{}, nil, objectNotFoundError{object: "volume", id: volumeID}

Two such errors are still left, as "ID or name" would probably be confusing,
but perhaps we can use a more generic error to include those as well (e.g.
"invalid <object> reference: value is empty");

    client/distribution_inspect.go:  return distributionInspect, objectNotFoundError{object: "distribution", id: imageRef}
    client/image_inspect.go:         return image.InspectResponse{}, nil, objectNotFoundError{object: "image", id: imageID}

Before this patch:

    docker container start ""
    Error response from daemon: page not found
    Error: failed to start containers:

    docker container start " "
    Error response from daemon: No such container:
    Error: failed to start containers:

With this patch:

    docker container start ""
    invalid container name or ID: value is empty
    Error: failed to start containers:

    docker container start " "
    invalid container name or ID: value is empty
    Error: failed to start containers:

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-02-03 11:21:51 +01:00
Sebastiaan van Stijn
6aea26b431 client: fix connection-errors being shadowed by API version mismatch errors
Commit e6907243af applied a fix for situations
where the client was configured with API-version negotiation, but did not yet
negotiate a version.

However, the checkVersion() function that was implemented copied the semantics
of cli.NegotiateAPIVersion, which ignored connection failures with the
assumption that connection errors would still surface further down.

However, when using the result of a failed negotiation for NewVersionError,
an API version mismatch error would be produced, masking the actual connection
error.

This patch changes the signature of checkVersion to return unexpected errors,
including failures to connect to the API.

Before this patch:

    docker -H unix:///no/such/socket.sock secret ls
    "secret list" requires API version 1.25, but the Docker daemon API version is 1.24

With this patch applied:

    docker -H unix:///no/such/socket.sock secret ls
    Cannot connect to the Docker daemon at unix:///no/such/socket.sock. Is the docker daemon running?

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-02-23 15:17:10 +01:00
Stefan Gehrig
0d27579fc7 Ensure that non-JSON-parsing errors are returned to the caller
Signed-off-by: Stefan Gehrig <stefan.gehrig.hn@googlemail.com>
Co-authored-by: Cory Snider <corhere@gmail.com>
2023-10-17 10:32:42 +02:00
Sebastiaan van Stijn
e6907243af client: negotiate api version before handling version-specific code
We try to perform API-version negotiation as lazy as possible (and only execute
when we are about to make an API request). However, some code requires API-version
dependent handling (to set options, or remove options based on the version of the
API we're using).

Currently this code depended on the caller code to perform API negotiation (or
to configure the API version) first, which may not happen, and because of that
we may be missing options (or set options that are not supported on older API
versions).

This patch:

- splits the code that triggered API-version negotiation to a separate
  Client.checkVersion() function.
- updates NewVersionError to accept a context
- updates NewVersionError to perform API-version negotiation (if enabled)
- updates various Client functions to manually trigger API-version negotiation

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-20 15:23:27 +02:00
Nick Santos
9900c7a348 client: improve error messaging on crash
Repro steps:
- Run Docker Desktop
- Run `docker run busybox tail -f /dev/null`
- Run `pkill "Docker Desktop"

Expected:
An error message that indicates that Docker Desktop is shutting down.

Actual:
An error message that looks like this:

```
error waiting for container: invalid character 's' looking for beginning of value
```

here's an example:

https://github.com/docker/for-mac/issues/6575#issuecomment-1324879001

After this change, you get an error message like:

```
error waiting for container: copying response body from Docker: unexpected EOF
```

which is a bit more explicit.

Signed-off-by: Nick Santos <nick.santos@docker.com>
2023-01-26 15:52:01 -05:00
Sebastiaan van Stijn
7293857456 api: rename ContainerWaitOKBody to container.WaitResponse
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-04-28 22:38:20 +02:00
Sebastiaan van Stijn
a832635e51 client.ContainerWait(): don't send empty "condition" query parameter
The client would always send a value, even if no `condition` was set;

    Calling POST /v1.41/containers/foo/wait?condition=

This patch changes the client to not send the parameter if it's empty (and the
API default value should be used).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-02-14 21:47:53 +01:00
Kir Kolyshkin
7d62e40f7e Switch from x/net/context -> context
Since Go 1.7, context is a standard package. Since Go 1.9, everything
that is provided by "x/net/context" is a couple of type aliases to
types in "context".

Many vendored packages still use x/net/context, so vendor entry remains
for now.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2018-04-23 13:52:44 -07:00
Daniel Nephin
4f0d95fa6e Add canonical import comment
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2018-02-05 16:51:57 -05:00
Josh Soref
39bcaee47b Spelling fixes
* additional
* ambiguous
* anonymous
* anything
* application
* because
* before
* building
* capabilities
* circumstances
* commit
* committer
* compresses
* concatenated
* config
* container
* container's
* current
* definition
* delimiter
* disassociates
* discovery
* distributed
* doesnotexist
* downloads
* duplicates
* either
* enhancing
* enumerate
* escapable
* exactly
* expect
* expectations
* expected
* explicitly
* false
* filesystem
* following
* forbidden
* git with
* healthcheck
* ignore
* independent
* inheritance
* investigating
* irrelevant
* it
* logging
* looking
* membership
* mimic
* minimum
* modify
* mountpoint
* multiline
* notifier
* outputting
* outside
* overridden
* override
* parsable
* plugins
* precedence
* propagation
* provided
* provides
* registries
* repositories
* returning
* settings
* should
* signals
* someone
* something
* specifically
* successfully
* synchronize
* they've
* thinking
* uninitialized
* unintentionally
* unmarshaling
* unnamed
* unreferenced
* verify

Signed-off-by: Josh Soref <jsoref@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-07-03 13:13:09 -07:00
Chen Min
2b62eb434b Fix Typos: continer,contianer -> container
Signed-off-by: Chen Min <chenmin46@huawei.com>
2017-06-01 19:21:01 +08:00
Simon Menke
4d2d2ea393 Remove deadlock in ContainerWait
when `cli.post(...)` fails `errC <- err` blocks because `errC` is unbufferd.

Signed-off-by: Simon Menke <simon.menke@gmail.com>
2017-05-19 09:23:52 +02:00
Josh Hawn
4921171587 Update ContainerWait API
This patch adds the untilRemoved option to the ContainerWait API which
allows the client to wait until the container is not only exited but
also removed.

This patch also adds some more CLI integration tests for waiting for a
created container and waiting with the new --until-removed flag.

Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)

Handle detach sequence in CLI

Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)

Update Container Wait Conditions

Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)

Apply container wait changes to API 1.30

The set of changes to the containerWait API missed the cut for the
Docker 17.05 release (API version 1.29). This patch bumps the version
checks to use 1.30 instead.

This patch also makes a minor update to a testfile which was added to
the builder/dockerfile package.

Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)

Remove wait changes from CLI

Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)

Address minor nits on wait changes

- Changed the name of the tty Proxy wrapper to `escapeProxy`
- Removed the unnecessary Error() method on container.State
- Fixes a typo in comment (repeated word)

Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)

Use router.WithCancel in the containerWait handler

This handler previously added this functionality manually but now uses
the existing wrapper which does it for us.

Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)

Add WaitCondition constants to api/types/container

Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)

Address more ContainerWait review comments

- Update ContainerWait backend interface to not return pointer values
  for container.StateStatus type.
- Updated container state's Wait() method comments to clarify that a
  context MUST be used for cancelling the request, setting timeouts,
  and to avoid goroutine leaks.
- Removed unnecessary buffering when making channels in the client's
  ContainerWait methods.
- Renamed result and error channels in client's ContainerWait methods
  to clarify that only a single result or error value would be sent
  on the channel.

Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)

Move container.WaitCondition type to separate file

... to avoid conflict with swagger-generated code for API response

Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)

Address more ContainerWait review comments

Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
2017-05-16 15:11:39 -07:00
Daniel Nephin
181562c2e5 Generate ContainerWait response from the swagger spec.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2016-10-31 11:19:53 -04:00
Michael Crosby
7c36a1af03 Move engine-api client package
This moves the engine-api client package to `/docker/docker/client`.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
2016-09-07 11:05:58 -07:00