9916 Commits

Author SHA1 Message Date
Paweł Gronowski
0a0245a31a Merge pull request #51700 from jschfflr/45939-nil-check-tx-cleanup
layer: Fix orphan creation in registerWithDescriptor
2025-12-12 11:44:46 +00:00
Jan Scheffler
70004549fb layer: Fix orphan creation in registerWithDescriptor
Start the metadata transaction before creating the overlay2 directory.
This ensures that if driver.Create() fails, we can properly cancel the
transaction. Previously, if StartTransaction() failed after driver.Create()
succeeded, the defer cleanup would not run (not registered yet), leaving
an orphaned overlay2 directory.

The fix reorders operations so that:
1. Transaction is started first (no filesystem changes yet)
2. Overlay2 directory is created second (transaction ready for cleanup)
3. Defer is registered after both succeed (tx is guaranteed non-nil)

If driver.Create() fails, the transaction is explicitly cancelled before
returning. The nil check for tx in the defer is no longer needed since
tx is guaranteed to exist when the defer runs.

Related to moby/moby#45939

Signed-off-by: Jan Scheffler <jan.scheffler@qodev.ai>
2025-12-12 09:44:04 +00:00
Albin Kerouanton
3cba626582 Merge pull request #50744 from dmcgowan/add-grpc-support
Natively support gRPC on the docker socket
2025-12-12 10:25:15 +01:00
Paweł Gronowski
31184e608e Merge pull request #51692 from akerouanton/remove-dead-ctrs-on-startup
daemon: clean up dead containers on start
2025-12-11 20:45:23 +00:00
Albin Kerouanton
ec9315cd4f daemon: clean up dead containers on start
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>
2025-12-11 13:40:23 -06:00
Paweł Gronowski
849afcc5be daemon: use WithExtraDialOpts for containerd client connection
Replace WithDialOpts with WithExtraDialOpts when creating containerd
clients to preserve the containerd client's default dial options while
adding our custom options.

Previously, using WithDialOpts would overwrite all of containerd's
default dial options, requiring us to sync them.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-11 20:26:08 +01:00
Paweł Gronowski
5ce3964834 Merge pull request #51683 from thaJeztah/fix_nil_map
daemon: buildCreateEndpointOptions: fix panic with "publish all"
2025-12-11 14:19:34 +00:00
Sebastiaan van Stijn
2a191665b8 daemon/container: Container.BackfillEmptyPBs: prevent nil map
Make sure PortBindings is not a nil-map to match the behavior
we have when creating a container;
c64b781df2/daemon/internal/runconfig/config.go (L30-L47)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-11 12:09:32 +01:00
Albin Kerouanton
43780fe40c daemon: disallow container port 0
Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
2025-12-11 11:07:42 +01:00
Sebastiaan van Stijn
695010ba2e daemon: buildCreateEndpointOptions: fix panic with "publish all"
This code was added in 85b260fba8, but didn't
account for maps.Clone returning a `nil` map if the map cloned was `nil`.

This could lead to a panic, similar to the panic that was fixed in
7517464283d29969c4d3615397b369abd99ce395;

    panic: assignment to entry in nil map

    goroutine 498 [running]:

    github.com/moby/moby/v2/daemon.buildPortsRelatedCreateEndpointOptions(0x400042f348, 0xaaaabcc8f458?, 0x40006feb40)
        /root/build-deb/engine/daemon/network.go:1047 +0x844
    github.com/moby/moby/v2/daemon.buildCreateEndpointOptions(0x400042f348, 0x4001015040, 0x400027d320, 0x40006feb40, {0x0, 0x0, 0x4001506cb8?})
        /root/build-deb/engine/daemon/network.go:988 +0x20c
    github.com/moby/moby/v2/daemon.(*Daemon).connectToNetwork(0x4000898008, {0xaaaabe21d9f8, 0x4000f12b10}, 0x400089a008, 0x400042f348, {0x400077a9f0, 0x6}, 0x400027d320)
        /root/build-deb/engine/daemon/container_operations.go:738 +0x66c
    github.com/moby/moby/v2/daemon.(*Daemon).allocateNetwork(0x4000898008, {0xaaaabe21d9f8, 0x4000f12b10}, 0x400089a008, 0x400042f348)
        /root/build-deb/engine/daemon/container_operations.go:421 +0x298
    github.com/moby/moby/v2/daemon.(*Daemon).initializeCreatedTask(0x4000898008, {0xaaaabe21d9f8, 0x4000f12b10}, 0x400089a008, {0xaaaabe23dc60, 0x4000eb21c8}, 0x400042f348, 0xaaaabd4db3df?)
        /root/build-deb/engine/daemon/start_linux.go:37 +0x260
    github.com/moby/moby/v2/daemon.(*Daemon).containerStart(0x4000898008, {0xaaaabe21d9c0, 0xaaaabfa05300}, 0x400089a008, 0x400042f348, {0x0, 0x0}, {0x0, 0x0}, 0x1)
        /root/build-deb/engine/daemon/start.go:242 +0xba8
    github.com/moby/moby/v2/daemon.(*Daemon).restore.func4(0x400042f348, 0x400117f1f0)
        /root/build-deb/engine/daemon/daemon.go:633 +0x308
    created by github.com/moby/moby/v2/daemon.(*Daemon).restore in goroutine 1
        /root/build-deb/engine/daemon/daemon.go:607 +0x5ec

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-11 10:11:15 +01:00
Rob Murray
8cf9e64738 NRI: report container state to plugins
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-12-10 17:49:28 +00:00
Rob Murray
dc1fe0be82 NRI: minor cleanups
Address some post-merge review comments.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-12-10 15:10:38 +00:00
Albin Kerouanton
07024223e2 Merge pull request #51674 from robmry/nri-env-vars
NRI: allow plugins to see/modify env vars
2025-12-10 15:52:42 +01:00
Rob Murray
b67f0c0449 NRI: add ContainerCreate hook, allow env-var adjustments
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-12-10 10:30:44 +00:00
Sebastiaan van Stijn
99066209a2 libnetwork/options: GenerateFromModel: use generics
Use generics so that the produced output is already in the right
type.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-10 01:48:48 +01:00
Sebastiaan van Stijn
14c5cd377d libnetwork/options: GenerateFromModel: reduce reflection
Re-use some of the reflection results where possible.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-10 01:48:45 +01:00
Derek McGowan
d210449d85 Natively support GRPC on the docker socket
Use the GRPC server when requests are for the grpc content type.

Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-12-09 21:03:04 +01:00
Rob Murray
14906f8023 NRI: use the daemon's logger
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-12-08 16:12:09 +00:00
Rob Murray
282868dabf NRI: instantiate and start/stop NRI adaptation
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-12-08 16:11:59 +00:00
Rob Murray
4941b36883 NRI: import containerd's NRI adaptation package
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-12-08 16:09:31 +00:00
Rob Murray
a230544000 NRI: add daemon.json/command line options
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-12-05 15:19:33 +00:00
kumy
b56d077034 fix: Correct typo in error message
Signed-off-by: kumy <kumy@users.noreply.github.com>
2025-12-03 13:13:46 +01:00
Sebastiaan van Stijn
19c48ee826 Merge pull request #51423 from thaJeztah/cleanup_token_errs
daemon/containerd: cleanup registry error-handling
2025-12-03 12:29:18 +01:00
Sebastiaan van Stijn
587d38292b Merge pull request #51629 from vvoland/c8d-fix-images
c8d/inspect: Fix image inspect for incomplete images
2025-12-02 12:35:27 +01:00
Brian Goff
a1836eb283 Merge pull request #51631 from thaJeztah/fix_df_shared_usage
system: df: fix SharedUsage on non-containerd
2025-12-01 13:30:07 -08:00
Akihiro Suda
a55f610e2a cdi: resolve symlinks
Fix using /etc/cdi entries in rootless mode:

> level=warning msg="Refreshing the CDI registry generated errors"
> error="failed to monitor for changes: no such file or directory\nfailed to monitor for changes: no such file or directory"

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2025-12-02 02:30:14 +09:00
Akihiro Suda
e29eaedf65 cdi: skip scanning non-readable dirs
This simplifies `dockerd-rootless.sh` by removing the workaround for
`CDI: Error associated with spec file /etc/cdi: failed to monitor for changes: permission denied`.

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2025-12-02 02:30:14 +09:00
Akihiro Suda
cd4397b4dc cdi: read XDG_CONFIG_HOME/cdi and XDG_RUNTIME_DIR/cdi for rootless
Fix issue 51601

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2025-12-02 02:30:14 +09:00
Paweł Gronowski
2e3a23c8ec c8d/inspect: Fix image inspect for incomplete images
When inspecting multi-platform images where some layer blobs were
missing from the content store, the image inspect operation would return
too early causing some data (like config details or unpacked size) to be
omitted even though are available.

This ensures that `docker image inspect` returns as much information as
possible.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-01 17:38:45 +01:00
Sebastiaan van Stijn
69c4ea7aad system: df: fix SharedUsage on non-containerd
The value was calculated, but due to 0af2962fdd
changing to a non-pointer, the value was not written back to the resulting
slice.

Before this patch:

    docker pull nginx:alpine
    docker pull alpine

    docker system df -v
    Images space usage:

    REPOSITORY   TAG       IMAGE ID       CREATED       SIZE      SHARED SIZE   UNIQUE SIZE   CONTAINERS
    nginx        alpine    cbad6347cca2   4 weeks ago   53.4MB    N/A           N/A           0
    alpine       latest    171e65262c80   7 weeks ago   8.51MB    N/A           N/A           0

With this patch:

    docker system df -v
    Images space usage:

    REPOSITORY   TAG       IMAGE ID       CREATED       SIZE      SHARED SIZE   UNIQUE SIZE   CONTAINERS
    nginx        alpine    cbad6347cca2   4 weeks ago   53.4MB    8.512MB       44.91MB       0
    alpine       latest    171e65262c80   7 weeks ago   8.51MB    8.512MB       0B            0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-01 16:45:38 +01:00
Rob Murray
7517464283 PublishAllPorts: don't crash with nil PortBindings
Introduced by commit 85b260f ("PublishAllPorts: create
port mappings for exposed ports").

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-29 19:43:30 +00:00
Albin Kerouanton
310aa9241a libnet/pm: log when stopping userland proxy
Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
2025-11-28 19:40:37 +01:00
Albin Kerouanton
52fae09ec0 libnet/pms/nat: don't bind IPv6 ports if not supported by port driver
In rootless mode, the Engine needs to call the rootless port driver to
know which IP address it should bind to inside of its network namespace.

The slirp4netns port drivers doesn't support binding to IPv6 address, so
we need to detect that before listening on the port.

Before commit 201968cc0, this wasn't a problem because the Engine was
binding the port, then calling rootless port driver to learn whether the
proto/IP family was supported, and listen on the port if so.

Starting with that commit, the Engine does bind + listen in one go, and
then calls the port driver — this is too late. Fix the bug by checking
if the port driver supports the PortBindingReq, and only allocate the
port if so.

Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
2025-11-28 19:40:34 +01:00
Albin Kerouanton
56e8e43339 Revert "libnet: populateNetworkResourcesOS: updateDNS only if !needResolver"
This reverts commit 937246a868.

Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
2025-11-28 09:47:07 +01:00
Albin Kerouanton
83f00e9f2b Revert "libnet: rebuildDNS: update the hash file"
This reverts commit eb18b398d4.

Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
2025-11-28 09:47:04 +01:00
Albin Kerouanton
14a955db2f Revert "libnet: setupDNS: don't overwrite user-modified resolv.conf"
This reverts commit 7639e193ff.

Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
2025-11-28 09:47:01 +01:00
Albin Kerouanton
20634eddce Merge pull request #51496 from thaJeztah/discoverapi_cleanups
libnetwork: some minor refactor / cleanups
2025-11-27 12:22:01 +01:00
Rob Murray
baf59d62d6 Merge pull request #51592 from robmry/sbleave_gw_config_error
Suppress errors from gateway re-config when disconnecting a network
2025-11-26 16:07:41 +00:00
Rob Murray
8f2aa3e0f5 Network disconnect: log rather than error on gateway update
During a network disconnect, log rather than returning an error
if it's not possible to set up a new gateway.

This restores the behaviour from before commit 53390f8 ("Put
clearNetworkResources() inline in its only caller"). It's not
ideal, but by the time new gateways are selected the old
endpoint has been disconnected - and nothing puts things back.
Until that's cleaned up, a broken state is inevitable, but
letting endpoint deletion complete means the container can
be restarted or re-connected to the network without a zombie
endpoint causing further issues.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-26 14:45:18 +00:00
Derek McGowan
e4a1657762 Check containerd client before using on Windows
Throw an error if the containerd snapshotter is enabled on Windows but
containerd has not been configured. This fixes a panic in this case when
trying to use an uninitialized client.

Signed-off-by: Derek McGowan <derek@mcg.dev>
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-26 15:40:08 +01:00
Rob Murray
18d2a08fcf Merge pull request #51587 from robmry/unmap_ipv6_addr
Unmap() more netip.Addr vars created from slices
2025-11-25 19:30:27 +00:00
Rob Murray
731ae07e65 Endpint.sbLeave: when deleting container, no new gateway
When the endpoint providing a container's default gateway
is removed, there's no need to select a new gateway if the
container is being removed.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-25 18:11:07 +00:00
Albin Kerouanton
03797acd88 Merge pull request #51586 from robmry/ep_options_exposed_ports
PublishAllPorts: create port mappings for exposed ports
2025-11-25 18:21:59 +01:00
Rob Murray
abd4c104dc Merge pull request #51526 from robmry/refactor-create-mounts
Refactor Daemon.create - prep for call to NRI plugin
2025-11-25 16:13:57 +00:00
Rob Murray
56dda25227 Merge pull request #51507 from zhangguanzhang/fix-pause-restart
libnet: setupDNS: don't overwrite user-modified resolv.conf
2025-11-25 13:53:10 +00:00
zhangguanzhang
7639e193ff libnet: setupDNS: don't overwrite user-modified resolv.conf
Call resolvconf.UserModified() in sandbox.setupDNS() to check if
resolv.conf was manually modified before regenerating it during
container restart for non-host network modes.

Signed-off-by: zhangguanzhang <zhangguanzhang@qq.com>
Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
2025-11-25 20:32:40 +08:00
Albin Kerouanton
eb18b398d4 libnet: rebuildDNS: update the hash file
Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
2025-11-25 11:51:27 +01:00
Albin Kerouanton
937246a868 libnet: populateNetworkResourcesOS: updateDNS only if !needResolver
When ep.needResolver() is true, sb.startResolver() calls sb.rebuildDNS()
which doesn't update the resolv.conf hash file.

Subsequent calls to sb.updateDNS() (which is only called by
populateNetworkResourcesOS) won't have any effect since it'll compare
the hash file and consider that the file was manually modified.

Make this explicit by gating the call to updateDNS() on !needResolver().

Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
2025-11-25 11:43:36 +01:00
Rob Murray
85b260fba8 PublishAllPorts: create port mappings for exposed ports
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-24 20:38:46 +00:00
Rob Murray
a2de9bb334 Unmap more netip.Addr vars created using AddrFromSlice
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-24 16:51:14 +00:00