Stopping the Engine while a container with autoremove set is running may
leave behind dead containers on disk. These containers aren't reclaimed
on next start, appear as "dead" in `docker ps -a` and can't be
inspected or removed by the user.
This bug has existed since a long time but became user visible with
9f5f4f5a42. Prior to that commit,
containers with no rwlayer weren't added to the in-memory viewdb, so
they weren't visible in `docker ps -a`. However, some dangling files
would still live on disk (e.g. folder in /var/lib/docker/containers,
mount points, etc).
The underlying issue is that when the daemon stops, it tries to stop all
running containers and then closes the containerd client. This leaves a
small window of time where the Engine might receive 'task stop' events
from containerd, and trigger autoremove. If the containerd client is
closed in parallel, the Engine is unable to complete the removal,
leaving the container in 'dead' state. In such case, the Engine logs the
following error:
cannot remove container "bcbc98b4f5c2b072eb3c4ca673fa1c222d2a8af00bf58eae0f37085b9724ea46": Canceled: grpc: the client connection is closing: context canceled
Solving the underlying issue would require complex changes to the
shutdown sequence. Moreover, the same issue could also happen if the
daemon crashes while it deletes a container. Thus, add a cleanup step
on daemon startup to remove these dead containers.
Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
Add integration tests for Windows container functionality focusing on network drivers and container isolation modes.
Signed-off-by: Sopho Merkviladze <smerkviladze@mirantis.com>
Add WithAPIVersion and WithAPIVersionFromEnv to be more clear on
the intent, and to align with other related options and fields.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Use a cancelReadCloser to automatically close the reader when the context
is cancelled. Consumers are still recommended to manually close the reader,
but the cancelReadCloser makes the Close idempotent.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Use a cancelReadCloser to automatically close the reader when the context
is cancelled. Consumers are still recommended to manually close the reader,
but the cancelReadCloser makes the Close idempotent.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Use a cancelReadCloser to automatically close the reader when the context
is cancelled. Consumers are still recommended to manually close the reader,
but the cancelReadCloser makes the Close idempotent.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Migrate TestAPIStatsContainerNotFound from the deprecated integration-cli
test suite to the modern integration test framework in integration/container.
The test verifies that the container stats API returns a NotFound error
for non-existent containers, testing both streaming and non-streaming modes.
Changes made:
- Migrated test to integration/container/stats_test.go using standard
Go testing patterns
- Refactored to use test array pattern for better test organization
- Removed test from integration-cli/docker_api_stats_test.go
- Removed unused imports from integration-cli file
- Removed Windows skip as it may not be necessary
Signed-off-by: Salim Dohri <dohri.salim@gmail.com>
Make invalid states unrepresentable by moving away from stringly-typed
MAC address values in API structs. As go.dev/issue/29678 has not yet
been implemented, provide our own HardwareAddr byte-slice type which
implements TextMarshaler and TextUnmarshaler to retain compatibility
with the API wire format.
When stdlib's net.HardwareAddr type implements TextMarshaler and
TextUnmarshaler and GODEBUG=netmarshal becomes the default, we should be
able to make the type a straight alias for stdlib net.HardwareAddr as a
non-breaking change.
Signed-off-by: Cory Snider <csnider@mirantis.com>
Use a more idiomatic name so that it can be used as `client.New()`.
We should look if we want `New()` to have different / updated defaults
i.e., enable `WithEnv` as default, and have an opt-out and have API-
version negotiation enabled by default (with an opt-out option).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The `ExecInspectResult` type was embedding `ExecInspect`, which is also
defined by the client, so there's no need to abstract it.
While updating, also;
- Rename `ExecID` to `ID`, to match the field-name returned by the API.
- Rename `Pid` to `PID`, to be in the right casing.
- Remove `json` labels, as option-types are not (un)marshaled to JSON.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The `ExecCreateResult` was embedding the `container.ExecCreateRespons`,
which in itself was an alias for `common.IDResponse`. This type has a
single field (`ID`) currently, but the embedding made it awkward to use,
for example, when mocking a `ExecCreateResult` using struct-literals:
func execCreateWithID(_ string, _ client.ExecCreateOptions) (client.ExecCreateResult, error) {
return client.ExecCreateResult{ExecCreateResponse: container.ExecCreateResponse{ID: "execid"}}, nil
}
This patch defines it as a local type with the `ID` as field.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>