Compare commits

..

99 Commits

Author SHA1 Message Date
Paweł Gronowski
08440b6ee8 Merge pull request #51830 from thaJeztah/29.x_backport_windows-network-none
[docker-29.x backport] daemon/libnetwork: Fix panic in findHNSEp when IP networks are nil
2026-01-08 16:57:22 +00:00
Paweł Gronowski
b0e62060b0 Merge pull request #51829 from thaJeztah/29.x_backport_fix-image-mount
[docker-29.x backport] daemon/volumes: More fs friendly image mount layer names
2026-01-08 16:57:12 +00:00
Sebastiaan van Stijn
515dbc8c71 Merge pull request #51826 from thaJeztah/29.x_backport_45939-init-layer-cleanup
[docker-29.x backport] layer: Clean up init layer if initialization fails
2026-01-08 17:24:06 +01:00
Sebastiaan van Stijn
adf3073cb6 Merge pull request #51825 from thaJeztah/29.x_backport_archive_rm_deprecated
[docker-29.x backport] remove uses of deprecated go-archive consts
2026-01-08 17:23:43 +01:00
Sebastiaan van Stijn
8b2c317218 Merge pull request #51824 from thaJeztah/29.x_backport_45939-rw-layer-cleanup
[docker-29.x backport] layer: Clean up RW layer if mount metadata save fails
2026-01-08 17:23:09 +01:00
Paweł Gronowski
3eca177282 daemon/libnetwork: Fix panic in findHNSEp when IP networks are nil
Can happen for `docker run --network none ...`

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit fadd8dc47c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-08 16:59:22 +01:00
Paweł Gronowski
c4f4c6765e daemon/volumes: More fs friendly image mount layer names
Hash the container ID, mount source and destination together to form a
layer name.

This ensures the generated names are filesystem-friendly and don't
exceed path length limits while maintaining uniqueness across different
mount points and containers.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit cb88c6ba10)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-08 16:56:18 +01:00
Sebastiaan van Stijn
f942bce11a Merge pull request #51821 from vvoland/51740-docker-29.x
[docker-29.x backport] vendor: github.com/moby/buildkit v0.26.3
2026-01-08 16:41:14 +01:00
Paweł Gronowski
a1f7fff7a9 daemon/layer_store: Use named return error for defer
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 26bb1af7e6)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-08 11:00:00 +01:00
Jan Scheffler
0e600c7fc4 layer: Clean up init layer if initialization fails
Add cleanup for the init layer directory if any operation fails after
driver.CreateReadWrite() succeeds in initMount(). Previously, failures
in driver.Get(), initFunc(), or driver.Put() would leave an orphaned
overlay2 directory.

Related to moby/moby#45939

Signed-off-by: Jan Scheffler <jan.scheffler@qodev.ai>
(cherry picked from commit 3fdde529e7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-08 11:00:00 +01:00
Sebastiaan van Stijn
734bb626e4 remove uses of deprecated go-archive consts
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 7239c72eca)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-08 10:54:50 +01:00
Jan Scheffler
5eaae6db52 layer: Clean up RW layer if mount metadata save fails
Add cleanup for the RW layer directory if saveMount() fails after
driver.CreateReadWrite() succeeds. Previously, this failure path would
leave an orphaned overlay2 directory with no corresponding metadata.

Related to moby/moby#45939

Signed-off-by: Jan Scheffler <jan.scheffler@qodev.ai>
(cherry picked from commit d7a6250b91)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-01-08 10:49:11 +01:00
Jonathan A. Sternberg
8ebb104e36 vendor: github.com/moby/buildkit v0.26.3
Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
(cherry picked from commit c63bf203bf)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2026-01-07 16:44:38 +01:00
Paweł Gronowski
fbf3ed25f8 Merge pull request #51703 from vvoland/51700-docker-29.x
[docker-29.x backport] layer: Fix orphan creation in registerWithDescriptor
2025-12-12 13:08:08 +00:00
Jan Scheffler
518779c90b 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>
(cherry picked from commit 70004549fb)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-12 12:45:16 +01:00
Sebastiaan van Stijn
ecf8643fe1 Merge pull request #51699 from vvoland/51697-docker-29.x
[docker-29.x backport] vendor: github.com/containernetworking/plugins v1.9.0
2025-12-12 11:38:17 +01:00
Sebastiaan van Stijn
5a99e1d1a4 vendor: github.com/containernetworking/plugins v1.9.0
no changes in vendored code

includes a fix for CVE-2025-67499

full diff: https://github.com/containernetworking/plugins/compare/v1.8.0...v1.9.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 24bac4495e)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-12 10:39:19 +01:00
Sebastiaan van Stijn
bae170eeb7 Merge pull request #51695 from vvoland/51684-docker-29.x
[docker-29.x backport] daemon: disallow container port 0
2025-12-11 23:11:07 +01:00
Sebastiaan van Stijn
8f33623c5d Merge pull request #51691 from vvoland/51683-docker-29.x
[docker-29.x backport] daemon: buildCreateEndpointOptions: fix panic with "publish all"
2025-12-11 23:10:00 +01:00
Paweł Gronowski
bdc1e7b0fe Merge pull request #51693 from vvoland/51692-docker-29.x
[docker-29.x backport] daemon: clean up dead containers on start
2025-12-11 20:50:59 +00:00
Albin Kerouanton
298e2f7d52 daemon: disallow container port 0
Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
(cherry picked from commit 43780fe40c)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-11 21:42:30 +01:00
Albin Kerouanton
3376758770 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>
(cherry picked from commit ec9315cd4f)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-11 20:55:04 +01:00
Sebastiaan van Stijn
bb2e099c3a 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>
(cherry picked from commit 2a191665b8)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-11 16:40:38 +01:00
Sebastiaan van Stijn
5898ee60f4 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>
(cherry picked from commit 695010ba2e)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-11 16:40:38 +01:00
Paweł Gronowski
05a5be917d Merge pull request #51689 from vvoland/51688-docker-29.x
[docker-29.x backport] gha: Fix PR branch validation
2025-12-11 15:39:25 +00:00
Paweł Gronowski
ab55325b58 gha: Fix PR branch validation
Make it work with `docker-XYZ` branches.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit c74203adbb)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-11 16:35:09 +01:00
Paweł Gronowski
5c69198edd Merge pull request #51685 from vvoland/sync-29.x
[docker-29.x] Move to `29.1`
2025-12-11 15:25:58 +00:00
Paweł Gronowski
cbaccdaf6d Merge tag 'docker-v29.1.2' into docker-29.x
v29.1.2
2025-12-11 13:38:34 +01:00
Paweł Gronowski
09d5128bff Merge tag 'docker-v29.1.1' into docker-29.x
v29.1.1
2025-12-11 13:38:32 +01:00
Paweł Gronowski
b54adb2d03 Merge tag 'docker-v29.1.0' into docker-29.x
v29.1.0

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-11 13:37:59 +01:00
Sebastiaan van Stijn
de45c2ae4f Merge pull request #51648 from vvoland/update-go
update to go1.25.5
2025-12-02 21:58:47 +01:00
Sebastiaan van Stijn
4212eb0abf Merge pull request #51650 from thaJeztah/bump_actions
gha: update actions/checkout@v6, actions/upload-artifact@v5, actions/download-artifact@v6
2025-12-02 21:28:40 +01:00
Paweł Gronowski
6f9d1ec3fb update to go1.25.5
These releases include 2 security fixes following the security policy:

- crypto/x509: excessive resource consumption in printing error string for host certificate validation

    Within HostnameError.Error(), when constructing an error string, there is no limit to the number of hosts that will be printed out.
    Furthermore, the error string is constructed by repeated string concatenation, leading to quadratic runtime.

    Therefore, a certificate provided by a malicious actor can result in excessive resource consumption.
    HostnameError.Error() now limits the number of hosts and utilizes strings.Builder when constructing an error string.

    Thanks to Philippe Antoine (Catena cyber) for reporting this issue.

    This is CVE-2025-61729 and Go issue https://go.dev/issue/76445.

- crypto/x509: excluded subdomain constraint does not restrict wildcard SANs

    An excluded subdomain constraint in a certificate chain does not restrict the
    usage of wildcard SANs in the leaf certificate. For example a constraint that
    excludes the subdomain test.example.com does not prevent a leaf certificate from
    claiming the SAN *.example.com.

    This is CVE-2025-61727 and Go issue https://go.dev/issue/76442.

View the release notes for more information:
https://go.dev/doc/devel/release#go1.25.5

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-02 20:30:08 +01:00
Sebastiaan van Stijn
f132381992 Merge pull request #51649 from thaJeztah/bump_setup_action
gha: update to actions/setup-go@v6
2025-12-02 20:29:39 +01:00
Sebastiaan van Stijn
81d930f527 gha: update to actions/setup-go@v6
Includes a change to use go.dev/dl instead of storage.googleapis.com/golang
as fallback URL, because storage.googleapis.com/golang is deprecated.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-02 20:07:34 +01:00
Sebastiaan van Stijn
7000f92763 gha: update actions/download-artifact@v6
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-02 20:03:48 +01:00
Sebastiaan van Stijn
69963d84f8 gha: update actions/upload-artifact@v5
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-02 20:02:48 +01:00
Sebastiaan van Stijn
43ed81ed85 gha: update actions/checkout@v6
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-02 20:01:27 +01:00
Sebastiaan van Stijn
bced6f6100 Merge pull request #51647 from thaJeztah/bump_compress
vendor: github.com/klauspost/compress v1.18.2
2025-12-02 17:00:04 +01:00
Sebastiaan van Stijn
4b8f9dd251 vendor: github.com/klauspost/compress v1.18.2
No changes in vendored code

Fixes a regression in v1.18.1 that resulted in invalid flate/zip/gzip encoding.
The v1.18.1 tag has been retracted.

full diff: https://github.com/klauspost/compress/compare/v1.18.1...v1.18.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-02 16:45:38 +01:00
Paweł Gronowski
e4f1408738 Merge pull request #51628 from locnnil/patch-1
Dockerfile: Update buildx to 0.30.1
2025-12-02 15:23:36 +00:00
Paweł Gronowski
5ecc72679d Merge pull request #51645 from thaJeztah/api_relax_replace_check
hack/validate/module-replace: relax check
2025-12-02 15:23:02 +00:00
Sebastiaan van Stijn
7687298e0a hack/validate/module-replace: relax check
Do not require replace rules to be added if there's no code-changes
in the module. Note that changes in api/swagger.yaml may result in
changes in generated code, but this should be checked separate from
the swagger itself.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-02 16:14:07 +01:00
Paweł Gronowski
45be1a39b3 Merge pull request #51617 from vvoland/validate-share-image
gha/test-validate: Reuse the dev image
2025-12-02 15:13:03 +00:00
Lincoln Wallace
a828af4d8d Dockerfile: Update buildx to 0.30.1
Signed-off-by: Lincoln Wallace <lincoln.wallace@canonical.com>
2025-12-02 16:00:28 +01:00
Paweł Gronowski
616e53c12b Merge pull request #51633 from Xeeynamo/bump-runc-v134
Dockerfile: update runc binary to v1.3.4
2025-12-02 11:45:39 +00: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
Luciano Ciccariello
f97f234729 Dockerfile: update runc binary to v1.3.4
- release notes: https://github.com/opencontainers/runc/releases/tag/v1.4.0
- full diff: opencontainers/runc@v1.3.3...v1.4.0

This version bump aims to fix a regression in runc v1.3.3, which caused
/dev/shm to have inappropriate permissions exposed to containers:
* https://github.com/opencontainers/runc/issues/4971
* https://github.com/opencontainers/runc/pull/4976

Signed-off-by: Luciano Ciccariello <xeeynamo@hotmail.com>
2025-12-02 09:31:00 +00: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
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
4ff8942d0d Merge pull request #51621 from robmry/fix-crash-with-nil-portbindings
PublishAllPorts: don't crash with nil PortBindings
2025-12-01 17:22:34 +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
Paweł Gronowski
3964729182 Merge pull request #51622 from AkihiroSuda/fix-51602
dockerd-rootless-setuptool.sh: fix `nsenter: no namespace specified`
2025-12-01 10:06:50 +00:00
Akihiro Suda
8c0751aa4d dockerd-rootless-setuptool.sh: fix nsenter: no namespace specified
Fix issue 51602

Corresponds to https://github.com/containerd/nerdctl/blob/v2.2.0/extras/rootless/containerd-rootless-setuptool.sh#L654

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2025-12-01 16:43:46 +09: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
Sebastiaan van Stijn
2faf258d4d Merge pull request #51616 from akerouanton/fix-51591
libnet/pms/nat: don't bind IPv6 ports if not supported by port driver
2025-11-29 00:54:16 +01: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
Paweł Gronowski
955650b33f gha/test-validate: Reuse the dev image
Don't build the dev image separately for each validation.

Build it once and then cache it so the validations can reuse it.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-28 16:26:29 +01:00
Sebastiaan van Stijn
9a84135d52 Merge pull request #51615 from akerouanton/revert-51507
Revert "libnet: setupDNS: don't overwrite user-modified resolv.conf"
2025-11-28 11:31:49 +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
Rob Murray
710302ecf2 Merge pull request #51612 from robmry/client-v0.2.1
vendor: update to client 0.2.1
2025-11-27 16:38:00 +00:00
Rob Murray
4219768511 vendor: update to client 0.2.1
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-27 16:28:48 +00:00
Paweł Gronowski
b6f067c0cf Merge pull request #51607 from robmry/fix-api-vendor
client - use tagged api module
2025-11-27 16:45:56 +01:00
Rob Murray
ea539d267d client - use tagged api module
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-27 15:33:52 +00:00
Paweł Gronowski
e7cd814b67 Merge pull request #51610 from vvoland/validate-nofailfast
gha/validate: Actually dont fail fast
2025-11-27 16:31:17 +01:00
Paweł Gronowski
c74559df60 gha/validate: Actually dont fail fast
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-27 16:27:28 +01:00
Paweł Gronowski
e22cc91c8d Merge pull request #51609 from vvoland/validate-nofailfast
gha/validate: Don't fail fast
2025-11-27 16:17:47 +01:00
Paweł Gronowski
ecf4446e46 gha/validate: Don't fail fast
Allow other validate checks to finish even if one of them failed.

Sometimes a check is faulty and its failure is expected - in such case
we want to ignore that one validation fail but still run all the others.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-27 16:13:15 +01:00
Paweł Gronowski
e7d3eb855e Merge pull request #51608 from vvoland/validate-modulereplace-fix
validate/module-replace: Fix check
2025-11-27 16:10:11 +01:00
Paweł Gronowski
46ca7f19cd validate/module-replace: Fix check
The bash array usage was wrong - change to a simpler check that just
compares if the diff is empty.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-27 15:58:26 +01:00
Rob Murray
5a6be3fb51 Merge pull request #51606 from robmry/vendor-client-0.2.0
vendor: client/0.2.0
2025-11-27 14:12:11 +00:00
Rob Murray
f745fe7f14 vendor: client/0.2.0
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-27 14:05:10 +00:00
Paweł Gronowski
4612690e23 Merge pull request #51583 from vvoland/51577-docker-29.x
[docker-29.x backport] Allow configured address with no configured subnet
2025-11-24 18:44:28 +00:00
Rob Murray
6280a80f32 Allow configured address with no configured subnet
Signed-off-by: Rob Murray <rob.murray@docker.com>
(cherry picked from commit 84a251d039)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-24 17:33:10 +01:00
Rob Murray
9cbafeac46 Update docker-py in test-docker-py
Pick up fixes for:
- test_create_with_ipv6_address
- test_connect_with_ipv6_address

65f7f0c..df3f8e2

Signed-off-by: Rob Murray <rob.murray@docker.com>
(cherry picked from commit 7e14b4d931)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-24 17:33:07 +01:00
Sebastiaan van Stijn
1fa8a31556 Merge pull request #51558 from robmry/backport-29.x-replace_lock_in_remote_nw_driver
[docker-29.x backport] Restore missing nwEndpointsMu.Lock
2025-11-19 16:37:22 +00:00
Rob Murray
3c6e5f0f5a Restore missing nwEndpointsMu.Lock
- introduced by 4f7afb8 (Remove libnet's logic to track a driver's
  port mapping state)

Signed-off-by: Rob Murray <rob.murray@docker.com>
(cherry picked from commit ed10b98506)
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-18 16:02:30 +00:00
Sebastiaan van Stijn
e9ff10bf36 Merge pull request #51538 from thaJeztah/29.x_backport_dont-remove-removed-gateway
[docker-29.x backport] Don't try to remove cleared docker_gwbridge endpoint
2025-11-16 17:26:01 +01:00
Rob Murray
7faaa44e18 Don't try to remove cleared docker_gwbridge endpoint
If a container is using a docker_gwbridge endpoint as its gateway,
when it's connected to another network that provides a gateway, the
docker_gwbridge endpoint is removed when that endpoint is added (in
a recursive nightmare).

So, the "before" gateway for the container has been removed
before the new gateway is updateExternalConnectivity'd.

Don't pass the old gateway to updateExternalConnectivity in that
case, because the network driver's already forgotten about it.

Signed-off-by: Rob Murray <rob.murray@docker.com>
(cherry picked from commit 1731e9e729)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-16 15:16:49 +01:00
Rob Murray
e9f9d7a81e Merge pull request #51545 from thaJeztah/29.x_backport_skip_TestBuildWithHugeFile
[docker-29.x backport] integration: skip TestBuildWithHugeFile
2025-11-16 14:14:51 +00:00
Sebastiaan van Stijn
28665176e5 Merge pull request #51543 from robmry/backport-29.x/rootless-noipv6
[docker-29.x backport] rootless: ignore error when enabling IPv6 forwarding
2025-11-16 14:21:56 +01:00
Sebastiaan van Stijn
43f91f775a integration: skip TestBuildWithHugeFile
We've seen various failures recently where GitHub actions runners are
running out of space. Skip this test for now.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 3e4a3cb03e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-16 14:18:27 +01:00
Rob Murray
bb0d79cb1a rootless: ignore error when enabling IPv6 forwarding
For hosts with IPv6 disabled.

Signed-off-by: Rob Murray <rob.murray@docker.com>
(cherry picked from commit 5c9f2e0388)
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-16 11:59:07 +00:00
Paweł Gronowski
198b5e3ed5 Merge pull request #51528 from akerouanton/backport-revendor-ishidawataru-sctp
[docker-29.x backport] Backport revendor ishidawataru sctp
2025-11-14 16:23:22 +01:00
Albin Kerouanton
2ad480ccf5 vendor: github.com/ishidawataru/sctp v0.0.0-20251114114122-1
full diff: 4b890084db..19ddcbc6aa

Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
2025-11-14 16:08:51 +01:00
Paweł Gronowski
cb6c1c3aca Merge pull request #51516 from vvoland/51492-docker-29.x
[docker-29.x backport] daemon: Fix image store choice priority for prior graphdriver state
2025-11-14 09:25:54 +01:00
Paweł Gronowski
2a18530fb2 Merge pull request #51513 from vvoland/51503-docker-29.x
[docker-29.x backport] hack/test/unit: Fix api and client module testing without replace rules
2025-11-14 09:25:21 +01:00
Paweł Gronowski
14c4e0d73a Merge pull request #51514 from vvoland/51493-docker-29.x
[docker-29.x backport] c8d/builder-next: Don't force unpack
2025-11-14 09:25:01 +01:00
Rob Murray
d23fd38f8b Merge pull request #51515 from vvoland/51495-docker-29.x
[docker-29.x backport] libnet: create DNS records on sbJoin (if not agent node)
2025-11-13 22:35:23 +00:00
Paweł Gronowski
3076530aa6 daemon: Fix image store choice priority for prior graphdriver state
The priority order for determining image store choice was incorrect when
a prior graphdriver existed.

The issue occurred because the prior graphdriver check happened after
processing explicit driver configuration, effectively ignoring user
intent when prior state existed.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 391247ce96)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-13 20:44:49 +01:00
Paweł Gronowski
7a3cdd2c86 daemon: Add TestDetermineImageStoreChoice
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit c5d0e3e6fa)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-13 20:44:37 +01:00
Albin Kerouanton
d7b6f3a7d3 inte/networking: TestDisableIPv6OnInterface: add '-c1' to ping
If the DNS name still resolves to an IP address, and that address is
assigned to a running container, the ping command will run indefinitely
and the test suite will time out for 10 mins.

This is confusing, as it looks like a daemon hang, or a test suite hang,
whereas it's just a test failure. Add '-c1' to ping to make it return
immediately.

Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
(cherry picked from commit 53ea70ea46)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-13 20:44:17 +01:00
Albin Kerouanton
7f5694cda1 inte/networking: test DNS resolution for non swarm-scoped nws
Previous commit reverted a faulty change that broke DNS resolution for
non swarm-scoped networks once a node has joined a Swarm cluster.

This commit adds an integration test to verify that we don't break DNS
resolution again.

Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
(cherry picked from commit 47bd247d4d)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-13 20:44:16 +01:00
Albin Kerouanton
0e2d804e48 libnet: create DNS records on sbJoin (if not agent node)
Commit a8b9eff90 removed a call to Network.updateSvcRecord from
Network.createEndpoint on the grounds that:

> all callers of Network.createEndpoint follow up with an Endpoint.Join,
> which also sets up the DNS entry.

However, the original call in Network.createEndpoint was gated by:

```
if !n.getController().isSwarmNode() || n.Scope() != scope.Swarm || !n.driverIsMultihost() {
	n.updateSvcRecord(context.WithoutCancel(ctx), ep, true)
}
```

whereas the call in Endpoint.sbJoin() (invoked by Endpoint.Join()) is
gated by:

```
if !n.getController().isAgent() {
    if !n.getController().isSwarmNode() || n.Scope() != scope.Swarm || !n.driverIsMultihost() {
	    n.updateSvcRecord(context.WithoutCancel(ctx), ep, true)
    }
}
```

As a result, once a node has joined a Swarm cluster, no DNS entries are
created for non swarm-scoped networks.

Change the condition used by `sbJoin` to match the original condition
used in `createEndpoint`.

Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
(cherry picked from commit 2e41476a5f)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-13 20:44:09 +01:00
Paweł Gronowski
7242ccd7a0 c8d/builder-next: Don't force unpack
The image exporter wrapper was unconditionally setting `unpack=true` for
all build exports, preventing users from controlling this behavior
through buildkit's output image exporter option.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit b4f9bd1cb3)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-13 20:43:42 +01:00
Paweł Gronowski
b6705d5e1a hack/test/unit: Fix api and client module testing without replace rules
Running sub-package tests from the root module without readding the
replace rules wasn't running the tests from the local in-tree versions
of these submodules.

Fix by cd-ing into their directories before running tests.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 0f597561e8)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-11-13 20:42:58 +01:00
70 changed files with 1015 additions and 418 deletions

View File

@@ -25,7 +25,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
-

View File

@@ -16,7 +16,7 @@ on:
workflow_call:
env:
GO_VERSION: "1.25.4"
GO_VERSION: "1.25.5"
GOTESTLIST_VERSION: v0.3.1
TESTSTAT_VERSION: v0.1.25
SETUP_BUILDX_VERSION: edge
@@ -36,7 +36,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Set up runner
uses: ./.github/actions/setup-runner
@@ -87,7 +87,7 @@ jobs:
-
name: Upload reports
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: test-reports-unit--${{ matrix.mode }}
path: /tmp/reports/*
@@ -103,13 +103,13 @@ jobs:
steps:
-
name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
-
name: Download reports
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
pattern: test-reports-unit-*
path: /tmp/reports

View File

@@ -21,7 +21,7 @@ on:
default: "graphdriver"
env:
GO_VERSION: "1.25.4"
GO_VERSION: "1.25.5"
GOTESTLIST_VERSION: v0.3.1
TESTSTAT_VERSION: v0.1.25
ITG_CLI_MATRIX_SIZE: 6
@@ -39,7 +39,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Set up runner
uses: ./.github/actions/setup-runner
@@ -82,7 +82,7 @@ jobs:
-
name: Upload reports
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: test-reports-docker-py-${{ inputs.storage }}
path: /tmp/reports/*
@@ -95,7 +95,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Set up runner
uses: ./.github/actions/setup-runner
@@ -169,7 +169,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Set up runner
uses: ./.github/actions/setup-runner
@@ -250,7 +250,7 @@ jobs:
-
name: Upload reports
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: test-reports-integration-${{ inputs.storage }}-${{ env.TESTREPORTS_NAME }}
path: /tmp/reports/*
@@ -266,13 +266,13 @@ jobs:
steps:
-
name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
-
name: Download reports
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
path: /tmp/reports
pattern: test-reports-integration-${{ inputs.storage }}-*
@@ -295,10 +295,10 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
@@ -393,7 +393,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Set up runner
uses: ./.github/actions/setup-runner
@@ -466,7 +466,7 @@ jobs:
-
name: Upload reports
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: test-reports-integration-cli-${{ inputs.storage }}-${{ matrix.mode }}-${{ env.TESTREPORTS_NAME }}
path: /tmp/reports/*
@@ -482,13 +482,13 @@ jobs:
steps:
-
name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
-
name: Download reports
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
path: /tmp/reports
pattern: test-reports-integration-cli-${{ inputs.storage }}-${{ matrix.mode }}-*

View File

@@ -20,7 +20,7 @@ on:
type: string
env:
GO_VERSION: "1.25.4"
GO_VERSION: "1.25.5"
TESTSTAT_VERSION: v0.1.25
jobs:
@@ -39,7 +39,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Set up Lima
uses: lima-vm/lima-actions/setup@03b96d61959e83b2c737e44162c3088e81de0886 # v1.0.1
@@ -167,7 +167,7 @@ jobs:
-
name: Upload reports
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: test-reports-integration-${{ env.TESTREPORTS_NAME }}
path: /tmp/reports/*
@@ -183,7 +183,7 @@ jobs:
steps:
-
name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
@@ -192,7 +192,7 @@ jobs:
run: echo "TESTREPORTS_NAME=$(basename ${{ inputs.template }})*" >> $GITHUB_ENV
-
name: Download reports
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
path: /tmp/reports
pattern: test-reports-integration-${{ env.TESTREPORTS_NAME }}

View File

@@ -28,7 +28,7 @@ on:
default: false
env:
GO_VERSION: "1.25.4"
GO_VERSION: "1.25.5"
GOTESTLIST_VERSION: v0.3.1
TESTSTAT_VERSION: v0.1.25
WINDOWS_BASE_IMAGE: mcr.microsoft.com/windows/servercore
@@ -53,7 +53,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
path: ${{ env.GOPATH }}/src/github.com/docker/docker
-
@@ -98,7 +98,7 @@ jobs:
docker cp "${{ env.TEST_CTN_NAME }}`:c`:\containerd\bin\containerd-shim-runhcs-v1.exe" ${{ env.BIN_OUT }}\
-
name: Upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: build-${{ inputs.storage }}-${{ inputs.os }}
path: ${{ env.BIN_OUT }}/*
@@ -117,7 +117,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
path: ${{ env.GOPATH }}/src/github.com/docker/docker
-
@@ -166,7 +166,7 @@ jobs:
-
name: Upload reports
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: ${{ inputs.os }}-${{ inputs.storage }}-unit-reports
path: ${{ env.GOPATH }}\src\github.com\docker\docker\bundles\*
@@ -181,13 +181,13 @@ jobs:
steps:
-
name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
-
name: Download artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
name: ${{ inputs.os }}-${{ inputs.storage }}-unit-reports
path: /tmp/artifacts
@@ -208,10 +208,10 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
@@ -264,12 +264,12 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
path: ${{ env.GOPATH }}/src/github.com/docker/docker
-
name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
@@ -292,7 +292,7 @@ jobs:
Get-ChildItem Env: | Out-String
-
name: Download artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
name: build-${{ inputs.storage }}-${{ inputs.os }}
path: ${{ env.BIN_OUT }}
@@ -469,7 +469,7 @@ jobs:
-
name: Upload reports
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: ${{ inputs.os }}-${{ inputs.storage }}-integration-reports-${{ matrix.runtime }}-${{ env.TESTREPORTS_NAME }}
path: ${{ env.GOPATH }}\src\github.com\docker\docker\bundles\*
@@ -496,13 +496,13 @@ jobs:
steps:
-
name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
-
name: Download reports
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
path: /tmp/reports
pattern: ${{ inputs.os }}-${{ inputs.storage }}-integration-reports-${{ matrix.runtime }}-*

View File

@@ -23,7 +23,7 @@ on:
pull_request:
env:
GO_VERSION: "1.25.4"
GO_VERSION: "1.25.5"
TESTSTAT_VERSION: v0.1.25
DESTDIR: ./build
SETUP_BUILDX_VERSION: edge
@@ -101,7 +101,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Set up runner
uses: ./.github/actions/setup-runner
@@ -146,7 +146,7 @@ jobs:
-
name: Upload reports
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: test-reports-unit-arm64-graphdriver
path: /tmp/reports/*
@@ -162,13 +162,13 @@ jobs:
steps:
-
name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
-
name: Download reports
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
pattern: test-reports-unit-arm64-*
path: /tmp/reports
@@ -191,7 +191,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Set up runner
uses: ./.github/actions/setup-runner
@@ -250,7 +250,7 @@ jobs:
-
name: Upload reports
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: test-reports-integration-arm64-graphdriver
path: /tmp/reports/*
@@ -266,13 +266,13 @@ jobs:
steps:
-
name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
-
name: Download reports
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
path: /tmp/reports
pattern: test-reports-integration-arm64-*

View File

@@ -49,7 +49,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Docker meta
id: meta
@@ -83,7 +83,7 @@ jobs:
mv "${bakeFile#cwd://}" "/tmp/bake-meta.json"
-
name: Upload meta bake definition
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: bake-meta
path: /tmp/bake-meta.json
@@ -109,7 +109,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
-
@@ -119,7 +119,7 @@ jobs:
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
-
name: Download meta bake definition
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
name: bake-meta
path: /tmp
@@ -164,7 +164,7 @@ jobs:
-
name: Upload digest
if: github.event_name != 'pull_request' && github.repository == 'moby/moby'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
@@ -180,13 +180,13 @@ jobs:
steps:
-
name: Download meta bake definition
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
name: bake-meta
path: /tmp
-
name: Download digests
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
path: /tmp/digests
pattern: digests-*

View File

@@ -23,7 +23,7 @@ on:
pull_request:
env:
GO_VERSION: "1.25.4"
GO_VERSION: "1.25.5"
DESTDIR: ./build
SETUP_BUILDX_VERSION: edge
SETUP_BUILDKIT_IMAGE: moby/buildkit:latest
@@ -53,7 +53,7 @@ jobs:
targets: binary
-
name: Upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: binary
path: ${{ env.DESTDIR }}
@@ -100,12 +100,12 @@ jobs:
uses: crazy-max/ghaction-github-runtime@v3
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
path: moby
-
name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
@@ -116,7 +116,7 @@ jobs:
working-directory: moby
-
name: Checkout BuildKit ${{ env.BUILDKIT_REF }}
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
repository: ${{ env.BUILDKIT_REPO }}
ref: ${{ env.BUILDKIT_REF }}
@@ -133,7 +133,7 @@ jobs:
buildkitd-flags: --debug
-
name: Download binary artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
name: binary
path: ./buildkit/build/moby/
@@ -184,7 +184,7 @@ jobs:
working-directory: ${{ env.GOPATH }}/src/github.com/docker/docker
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
path: ${{ env.GOPATH }}/src/github.com/docker/docker
@@ -199,7 +199,7 @@ jobs:
echo "WINDOWS_BASE_IMAGE_TAG=${{ env.WINDOWS_BASE_TAG_2022 }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
- name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
@@ -225,7 +225,7 @@ jobs:
go install github.com/distribution/distribution/v3/cmd/registry@latest
- name: Checkout BuildKit
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
repository: moby/buildkit
ref: master
@@ -248,7 +248,7 @@ jobs:
cp ${{ env.GOPATH }}\bin\buildctl.exe ${{ env.BIN_OUT }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: build-windows
path: ${{ env.BIN_OUT }}/*
@@ -307,12 +307,12 @@ jobs:
uses: crazy-max/ghaction-github-runtime@v3
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
path: moby
- name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false
@@ -324,14 +324,14 @@ jobs:
working-directory: moby
- name: Checkout BuildKit ${{ env.BUILDKIT_REF }}
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
repository: ${{ env.BUILDKIT_REPO }}
ref: ${{ env.BUILDKIT_REF }}
path: buildkit
- name: Download Moby artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v6
with:
name: build-windows
path: ${{ env.BIN_OUT }}

View File

@@ -75,7 +75,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Create matrix
id: platforms

View File

@@ -34,7 +34,7 @@ on:
- cron: '0 9 * * 4'
env:
GO_VERSION: "1.25.4"
GO_VERSION: "1.25.5"
jobs:
codeql:
@@ -47,11 +47,11 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 2
- name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache: false

View File

@@ -23,7 +23,7 @@ on:
pull_request:
env:
GO_VERSION: "1.25.4"
GO_VERSION: "1.25.5"
GIT_PAGER: "cat"
PAGER: "cat"
SETUP_BUILDX_VERSION: edge
@@ -67,7 +67,14 @@ jobs:
set: |
*.cache-from=type=gha,scope=dev${{ matrix.mode }}
*.cache-to=type=gha,scope=dev${{ matrix.mode }}
*.output=type=cacheonly
${{ matrix.mode == '' && '*.output=type=docker,dest=/tmp/dev-image.tar' || '*.output=type=cacheonly' }}
-
name: Cache dev image
if: matrix.mode == ''
uses: actions/cache/save@v4
with:
key: dev-image-${{ github.run_id }}
path: /tmp/dev-image.tar
test:
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
@@ -103,7 +110,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Create matrix
id: scripts
@@ -122,13 +129,12 @@ jobs:
- validate-prepare
- build-dev
strategy:
fail-fast: true
matrix:
script: ${{ fromJson(needs.validate-prepare.outputs.matrix) }}
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
-
@@ -139,15 +145,19 @@ jobs:
uses: docker/setup-buildx-action@v3
with:
version: ${{ env.SETUP_BUILDX_VERSION }}
driver-opts: image=${{ env.SETUP_BUILDKIT_IMAGE }}
driver: docker
buildkitd-flags: --debug
-
name: Build dev image
uses: docker/bake-action@v6
name: Restore dev image
uses: actions/cache/restore@v4
with:
targets: dev
set: |
dev.cache-from=type=gha,scope=dev
key: dev-image-${{ github.run_id }}
path: /tmp/dev-image.tar
fail-on-cache-miss: true
-
name: Load dev image
run: |
docker load -i /tmp/dev-image.tar
-
name: Validate
run: |
@@ -164,7 +174,7 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
-
name: Create matrix
id: platforms

View File

@@ -81,13 +81,24 @@ jobs:
- name: Check release branch
id: title_branch
run: |
# If PR targets a different branch than master, the PR title should mention the target branch in square brackets, for example:
# [27.1 backport] Some change that needs backporting to 27.1
# [27.1] Change directly targeting the 27.1 branch
# [docker-29.x] Change directly targeting the docker-29.x branch
# [docker-29.x backport] Some change that needs backporting to docker-29.x
# get the intended major version prefix ("[27.1 backport]" -> "27.") from the PR title.
[[ "$PR_TITLE" =~ ^\[([0-9]*\.)[^]]*\] ]] && branch="${BASH_REMATCH[1]}"
target_branch=$(echo "$PR_TITLE" | sed -nE 's/^\[([^]]+)\].*/\1/p' | sed 's/ backport$//')
# get major version prefix from the release branch ("27.x -> "27.")
[[ "$GITHUB_BASE_REF" =~ ^([0-9]*\.) ]] && target_branch="${BASH_REMATCH[1]}" || target_branch="$GITHUB_BASE_REF"
echo "target_branch: $target_branch"
echo "GITHUB_BASE_REF: $GITHUB_BASE_REF"
if [[ "$target_branch" != "$branch" ]] && ! [[ "$GITHUB_BASE_REF" == "master" && "$branch" == "" ]]; then
# If the PR is opened against the master branch and the target branch is not specified, exit early.
if [[ "$GITHUB_BASE_REF" == "master" && "$target_branch" == "" ]]; then
exit 0
fi
if [[ "$target_branch" != "$GITHUB_BASE_REF" ]]; then
echo "::error::PR is opened against the $GITHUB_BASE_REF branch, but its title suggests otherwise."
exit 1
fi

View File

@@ -3,7 +3,7 @@ version: "2"
run:
# prevent golangci-lint from deducting the go version to lint for through go.mod,
# which causes it to fallback to go1.17 semantics.
go: "1.25.4"
go: "1.25.5"
concurrency: 2
# Only supported with go modules enabled (build flag -mod=vendor only valid when using modules)
# modules-download-mode: vendor

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.25.4
ARG GO_VERSION=1.25.5
ARG BASE_DEBIAN_DISTRO="bookworm"
ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}"
@@ -21,7 +21,7 @@ ARG DOCKERCLI_INTEGRATION_REPOSITORY="https://github.com/docker/cli.git"
ARG DOCKERCLI_INTEGRATION_VERSION=v25.0.5
# BUILDX_VERSION is the version of buildx to install in the dev container.
ARG BUILDX_VERSION=0.29.1
ARG BUILDX_VERSION=0.30.1
# COMPOSE_VERSION is the version of compose to install in the dev container.
ARG COMPOSE_VERSION=v2.40.0
@@ -254,7 +254,7 @@ RUN git init . && git remote add origin "https://github.com/opencontainers/runc.
# This version should usually match the version that is used by the containerd version
# that is used. If you need to update runc, open a pull request in the containerd
# project first, and update both after that is merged.
ARG RUNC_VERSION=v1.3.3
ARG RUNC_VERSION=v1.3.4
RUN git fetch -q --depth 1 origin "${RUNC_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD
FROM base AS runc-build

View File

@@ -5,7 +5,7 @@
# This represents the bare minimum required to build and test Docker.
ARG GO_VERSION=1.25.4
ARG GO_VERSION=1.25.5
ARG BASE_DEBIAN_DISTRO="bookworm"
ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}"

View File

@@ -161,7 +161,7 @@ FROM ${WINDOWS_BASE_IMAGE}:${WINDOWS_BASE_IMAGE_TAG}
# Use PowerShell as the default shell
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
ARG GO_VERSION=1.25.4
ARG GO_VERSION=1.25.5
# GOTESTSUM_VERSION is the version of gotest.tools/gotestsum to install.
ARG GOTESTSUM_VERSION=v1.13.0

View File

@@ -10,7 +10,7 @@ require (
github.com/docker/go-connections v0.6.0
github.com/docker/go-units v0.5.0
github.com/google/go-cmp v0.7.0
github.com/moby/moby/api v1.52.1-0.20251127112201-20634eddce67
github.com/moby/moby/api v1.52.0
github.com/moby/term v0.5.2
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.1

View File

@@ -29,8 +29,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/moby/api v1.52.1-0.20251127112201-20634eddce67 h1:n3faoyhuHCuKrrJNJOYaYKYTX5ZbZ9Zp7dMdlsZCOFw=
github.com/moby/moby/api v1.52.1-0.20251127112201-20634eddce67/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=
github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg=
github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=

View File

@@ -556,4 +556,5 @@ if ! command -v "cmd_entrypoint_${command}" > /dev/null 2>&1; then
fi
# main
shift
"cmd_entrypoint_${command}" "$@"

View File

@@ -8,6 +8,7 @@ import (
"github.com/moby/go-archive"
"github.com/moby/go-archive/chrootarchive"
"github.com/moby/go-archive/compression"
containertypes "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/events"
"github.com/moby/moby/v2/daemon/container"
@@ -278,7 +279,7 @@ func (daemon *Daemon) containerCopy(container *container.Container, resource str
filter = []string{f}
}
archv, err := chrootarchive.Tar(basePath, &archive.TarOptions{
Compression: archive.Uncompressed,
Compression: compression.None,
IncludeFiles: filter,
}, container.BaseFS)
if err != nil {

View File

@@ -7,6 +7,7 @@ import (
"github.com/moby/buildkit/frontend/dockerfile/instructions"
"github.com/moby/go-archive"
"github.com/moby/go-archive/compression"
"github.com/moby/moby/v2/daemon/builder/remotecontext"
"github.com/moby/sys/reexec"
"gotest.tools/v3/assert"
@@ -105,7 +106,7 @@ func TestDispatch(t *testing.T) {
createTestTempFile(t, contextDir, filename, content, 0o777)
}
tarStream, err := archive.Tar(contextDir, archive.Uncompressed)
tarStream, err := archive.Tar(contextDir, compression.None)
if err != nil {
t.Fatalf("Error when creating tar stream: %s", err)
}

View File

@@ -7,6 +7,7 @@ import (
"testing"
"github.com/moby/go-archive"
"github.com/moby/go-archive/compression"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/network"
"github.com/moby/moby/v2/daemon/builder"
@@ -61,7 +62,7 @@ func readAndCheckDockerfile(t *testing.T, testName, contextDir, dockerfilePath,
if runtime.GOOS != "windows" {
skip.If(t, os.Getuid() != 0, "skipping test that requires root")
}
tarStream, err := archive.Tar(contextDir, archive.Uncompressed)
tarStream, err := archive.Tar(contextDir, compression.None)
assert.NilError(t, err)
defer func() {

View File

@@ -6,6 +6,7 @@ import (
"github.com/containerd/log"
"github.com/moby/go-archive"
"github.com/moby/go-archive/compression"
"github.com/moby/moby/v2/daemon/builder"
"github.com/moby/moby/v2/daemon/builder/remotecontext/git"
)
@@ -17,7 +18,7 @@ func MakeGitContext(gitURL string) (builder.Source, error) {
return nil, err
}
c, err := archive.Tar(root, archive.Uncompressed)
c, err := archive.Tar(root, compression.None)
if err != nil {
return nil, err
}

View File

@@ -6,6 +6,7 @@ import (
"testing"
"github.com/moby/go-archive"
"github.com/moby/go-archive/compression"
"github.com/moby/moby/v2/daemon/builder"
"github.com/moby/sys/reexec"
"github.com/pkg/errors"
@@ -128,7 +129,7 @@ func TestRemoveDirectory(t *testing.T) {
func makeTestArchiveContext(t *testing.T, dir string) builder.Source {
skip.If(t, os.Getuid() != 0, "skipping test that requires root")
tarStream, err := archive.Tar(dir, archive.Uncompressed)
tarStream, err := archive.Tar(dir, compression.None)
if err != nil {
t.Fatalf("error: %s", err)
}

View File

@@ -335,7 +335,7 @@ func validateHealthCheck(healthConfig *containertypes.HealthConfig) error {
func validatePortBindings(ports networktypes.PortMap) error {
for port := range ports {
if !port.IsValid() {
if !port.IsValid() || port.Num() == 0 {
return errors.Errorf("invalid port specification: %q", port.String())
}

View File

@@ -647,7 +647,10 @@ func (container *Container) BackfillEmptyPBs() {
if container.HostConfig == nil {
return
}
if container.HostConfig.PortBindings == nil {
container.HostConfig.PortBindings = networktypes.PortMap{}
return
}
for portProto, pb := range container.HostConfig.PortBindings {
if len(pb) > 0 || pb == nil {
continue

View File

@@ -2,6 +2,7 @@ package containerd
import (
"context"
"fmt"
"sync/atomic"
"time"
@@ -63,13 +64,6 @@ func (i *ImageService) ImageInspect(ctx context.Context, refOrID string, opts im
}
}
var img dockerspec.DockerOCIImage
if multi.Best != nil {
if err := multi.Best.ReadConfig(ctx, &img); err != nil {
return nil, err
}
}
parent, err := i.getImageLabelByDigest(ctx, target.Digest, imageLabelClassicBuilderParent)
if err != nil {
log.G(ctx).WithError(err).Warn("failed to determine Parent property")
@@ -104,29 +98,36 @@ func (i *ImageService) ImageInspect(ctx context.Context, refOrID string, opts im
GraphDriverLegacy: &storage.DriverData{Name: i.snapshotter},
}
var img dockerspec.DockerOCIImage
if multi.Best != nil {
imgConfig := img.Config
resp.Author = img.Author
resp.Config = &imgConfig
resp.Architecture = img.Architecture
resp.Variant = img.Variant
resp.Os = img.OS
resp.OsVersion = img.OSVersion
if err := multi.Best.ReadConfig(ctx, &img); err != nil && !cerrdefs.IsNotFound(err) {
return nil, fmt.Errorf("failed to read image config: %w", err)
}
}
if len(img.History) > 0 {
resp.Comment = img.History[len(img.History)-1].Comment
}
// Copy the config
imgConfig := img.Config
resp.Config = &imgConfig
if img.Created != nil {
resp.Created = img.Created.Format(time.RFC3339Nano)
}
resp.Author = img.Author
resp.Architecture = img.Architecture
resp.Variant = img.Variant
resp.Os = img.OS
resp.OsVersion = img.OSVersion
resp.RootFS = imagetypes.RootFS{
Type: img.RootFS.Type,
}
for _, layer := range img.RootFS.DiffIDs {
resp.RootFS.Layers = append(resp.RootFS.Layers, layer.String())
}
if len(img.History) > 0 {
resp.Comment = img.History[len(img.History)-1].Comment
}
if img.Created != nil {
resp.Created = img.Created.Format(time.RFC3339Nano)
}
resp.RootFS = imagetypes.RootFS{
Type: img.RootFS.Type,
}
for _, layer := range img.RootFS.DiffIDs {
resp.RootFS.Layers = append(resp.RootFS.Layers, layer.String())
}
return resp, nil

View File

@@ -61,6 +61,32 @@ func TestImageInspect(t *testing.T) {
}
})
t.Run("inspect image with one layer missing", func(t *testing.T) {
ctx := logtest.WithT(ctx, t)
service := fakeImageService(t, ctx, cs)
img := toContainerdImage(t, specialimage.MultiLayer)
_, err := service.images.Create(ctx, img)
assert.NilError(t, err)
// Get the manifest to access the layers
mfst, err := c8dimages.Manifest(ctx, cs, img.Target, nil)
assert.NilError(t, err)
assert.Check(t, len(mfst.Layers) > 0, "image should have at least one layer")
// Delete the last layer from the content store
lastLayer := mfst.Layers[len(mfst.Layers)-1]
err = cs.Delete(ctx, lastLayer.Digest)
assert.NilError(t, err)
inspect, err := service.ImageInspect(ctx, img.Name, imagebackend.ImageInspectOpts{})
assert.NilError(t, err)
assert.Check(t, inspect.Config != nil)
assert.Check(t, is.Len(inspect.RootFS.Layers, len(mfst.Layers)))
})
t.Run("inspect image with platform parameter", func(t *testing.T) {
ctx := logtest.WithT(ctx, t)
service := fakeImageService(t, ctx, cs)

View File

@@ -305,34 +305,33 @@ func (i *ImageService) multiPlatformSummary(ctx context.Context, img c8dimages.I
mfstSummary.ImageData.Platform = *target.Platform
}
if !available {
return nil
}
var dockerImage dockerspec.DockerOCIImage
if err := img.ReadConfig(ctx, &dockerImage); err != nil {
if err := img.ReadConfig(ctx, &dockerImage); err != nil && !cerrdefs.IsNotFound(err) {
logger.WithError(err).Warn("failed to read image config")
return nil
}
if target.Platform == nil {
mfstSummary.ImageData.Platform = dockerImage.Platform
if dockerImage.Platform.OS != "" {
if target.Platform == nil {
mfstSummary.ImageData.Platform = dockerImage.Platform
}
logger = logger.WithField("platform", mfstSummary.ImageData.Platform)
}
logger = logger.WithField("platform", mfstSummary.ImageData.Platform)
chainIDs := identity.ChainIDs(dockerImage.RootFS.DiffIDs)
if dockerImage.RootFS.DiffIDs != nil {
chainIDs := identity.ChainIDs(dockerImage.RootFS.DiffIDs)
snapshotUsage, err := img.SnapshotUsage(ctx, i.snapshotterService(i.snapshotter))
if err != nil {
logger.WithFields(log.Fields{"error": err}).Warn("failed to determine platform specific unpacked size")
snapshotUsage, err := img.SnapshotUsage(ctx, i.snapshotterService(i.snapshotter))
if err != nil {
logger.WithFields(log.Fields{"error": err}).Warn("failed to determine platform specific unpacked size")
}
unpackedSize := snapshotUsage.Size
mfstSummary.ImageData.Size.Unpacked = unpackedSize
mfstSummary.Size.Total += unpackedSize
summary.TotalSize += unpackedSize
summary.AllChainIDs = append(summary.AllChainIDs, chainIDs...)
}
unpackedSize := snapshotUsage.Size
mfstSummary.ImageData.Size.Unpacked = unpackedSize
mfstSummary.Size.Total += unpackedSize
summary.TotalSize += unpackedSize
summary.AllChainIDs = append(summary.AllChainIDs, chainIDs...)
for _, c := range i.containers.List() {
if c.ImageManifest != nil && c.ImageManifest.Digest == target.Digest {
@@ -360,8 +359,9 @@ func (i *ImageService) multiPlatformSummary(ctx context.Context, img c8dimages.I
if err != nil {
if errors.Is(err, errNotManifestOrIndex) {
log.G(ctx).WithFields(log.Fields{
"error": err,
"image": img.Name,
"error": err,
"image": img.Name,
"descriptor": img.Target,
}).Warn("unexpected image target (neither a manifest nor index)")
} else {
return nil, err
@@ -443,15 +443,6 @@ func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore con
}
}
cfgDesc, err := imageManifest.Image.Config(ctx)
if err != nil {
return nil, err
}
var cfg configLabels
if err := readJSON(ctx, contentStore, cfgDesc, &cfg); err != nil {
return nil, err
}
var unpackedSize int64
if snapshotUsage, err := imageManifest.SnapshotUsage(ctx, i.snapshotterService(i.snapshotter)); err != nil {
log.G(ctx).WithFields(log.Fields{"image": imageManifest.Name(), "error": err}).Warn("failed to calculate unpacked size of image")
@@ -474,7 +465,6 @@ func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore con
RepoDigests: repoDigests,
RepoTags: repoTags,
Size: totalSize,
Labels: cfg.Config.Labels,
// -1 indicates that the value has not been set (avoids ambiguity
// between 0 (default) and "not set". We cannot use a pointer (nil)
// for this, as the JSON representation uses "omitempty", which would
@@ -482,9 +472,25 @@ func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore con
SharedSize: -1,
Containers: -1,
}
var cfg configLabels
if err := imageManifest.ReadConfig(ctx, &cfg); err != nil {
if !cerrdefs.IsNotFound(err) {
log.G(ctx).WithFields(log.Fields{
"image": imageManifest.Name(),
"error": err,
}).Warn("failed to read image config")
}
}
if cfg.Created != nil {
summary.Created = cfg.Created.Unix()
}
if cfg.Config.Labels != nil {
summary.Labels = cfg.Config.Labels
} else {
summary.Labels = map[string]string{}
}
return summary, nil
}

View File

@@ -15,6 +15,7 @@ import (
cerrdefs "github.com/containerd/errdefs"
"github.com/containerd/platforms"
"github.com/moby/go-archive"
"github.com/moby/go-archive/compression"
"github.com/moby/moby/v2/daemon/server/imagebackend"
"github.com/moby/moby/v2/internal/testutil/labelstore"
"github.com/moby/moby/v2/internal/testutil/specialimage"
@@ -39,7 +40,7 @@ func TestImageLoad(t *testing.T) {
imgSvc.defaultPlatformOverride = platforms.Only(linuxAmd64)
tryLoad := func(ctx context.Context, t *testing.T, dir string, platformList []ocispec.Platform) error {
tarRc, err := archive.Tar(dir, archive.Uncompressed)
tarRc, err := archive.Tar(dir, compression.None)
assert.NilError(t, err)
defer tarRc.Close()

View File

@@ -641,18 +641,25 @@ func (daemon *Daemon) restore(ctx context.Context, cfg *configStore, containers
}
group.Wait()
for id := range removeContainers {
for id, c := range removeContainers {
group.Add(1)
go func(cid string) {
go func(cid string, c *container.Container) {
_ = sem.Acquire(context.Background(), 1)
defer group.Done()
defer sem.Release(1)
if c.State.IsDead() {
if err := daemon.cleanupContainer(c, backend.ContainerRmConfig{ForceRemove: true, RemoveVolume: true}); err != nil {
log.G(ctx).WithField("container", cid).WithError(err).Error("failed to remove dead container")
}
return
}
if err := daemon.containerRm(&cfg.Config, cid, &backend.ContainerRmConfig{ForceRemove: true, RemoveVolume: true}); err != nil {
log.G(ctx).WithField("container", cid).WithError(err).Error("failed to remove container")
}
sem.Release(1)
group.Done()
}(id)
}(id, c)
}
group.Wait()

View File

@@ -300,6 +300,18 @@ func TestValidateContainerIsolation(t *testing.T) {
assert.Check(t, is.Error(err, "invalid isolation 'invalid' on "+runtime.GOOS))
}
func TestInvalidContainerPort0(t *testing.T) {
d := Daemon{}
hc := containertypes.HostConfig{
PortBindings: map[network.Port][]network.PortBinding{
network.MustParsePort("0/tcp"): {},
},
}
_, err := d.verifyContainerSettings(&configStore{}, &hc, nil, false)
assert.Error(t, err, `invalid port specification: "0/tcp"`)
}
func TestFindNetworkErrorType(t *testing.T) {
d := Daemon{}
_, err := d.FindNetwork("fakeNet")

View File

@@ -9,6 +9,7 @@ import (
"github.com/containerd/log"
"github.com/moby/go-archive"
"github.com/moby/go-archive/chrootarchive"
"github.com/moby/go-archive/compression"
"github.com/moby/moby/api/types/events"
"github.com/moby/moby/v2/daemon/container"
"github.com/moby/moby/v2/errdefs"
@@ -65,7 +66,7 @@ func (daemon *Daemon) containerExport(ctx context.Context, ctr *container.Contai
}()
archv, err := chrootarchive.Tar(basefs, &archive.TarOptions{
Compression: archive.Uncompressed,
Compression: compression.None,
IDMap: daemon.idMapping,
}, basefs)
if err != nil {

View File

@@ -8,6 +8,7 @@ import (
"github.com/containerd/log"
"github.com/moby/go-archive"
"github.com/moby/go-archive/chrootarchive"
"github.com/moby/go-archive/compression"
"github.com/moby/moby/v2/pkg/ioutils"
"github.com/moby/sys/user"
)
@@ -64,7 +65,7 @@ func (gdw *NaiveDiffDriver) Diff(id, parent string) (arch io.ReadCloser, retErr
}()
if parent == "" {
tarArchive, err := archive.Tar(layerFs, archive.Uncompressed)
tarArchive, err := archive.Tar(layerFs, compression.None)
if err != nil {
return nil, err
}

View File

@@ -19,6 +19,7 @@ import (
"github.com/docker/go-units"
"github.com/moby/go-archive"
"github.com/moby/go-archive/chrootarchive"
"github.com/moby/go-archive/compression"
"github.com/moby/locker"
"github.com/moby/moby/v2/daemon/graphdriver"
"github.com/moby/moby/v2/daemon/graphdriver/overlayutils"
@@ -721,7 +722,7 @@ func (d *Driver) Diff(id, parent string) (io.ReadCloser, error) {
diffPath := d.getDiffPath(id)
logger.Debugf("Tar with options on %s", diffPath)
return archive.TarWithOptions(diffPath, &archive.TarOptions{
Compression: archive.Uncompressed,
Compression: compression.None,
IDMap: d.idMap,
WhiteoutFormat: archive.OverlayWhiteoutFormat,
})

View File

@@ -103,8 +103,7 @@ func (i *ImageService) Images(ctx context.Context, opts imagebackend.ListOptions
}
var (
summaries = make([]imagetypes.Summary, 0, len(selectedImages))
summaryMap = make(map[*image.Image]imagetypes.Summary, len(selectedImages))
summaryMap = make(map[*image.Image]*imagetypes.Summary, len(selectedImages))
allContainers []*container.Container
)
for id, img := range selectedImages {
@@ -210,8 +209,7 @@ func (i *ImageService) Images(ctx context.Context, opts imagebackend.ListOptions
}
}
summary.Containers = containersCount
summaryMap[img] = *summary
summaries = append(summaries, *summary)
summaryMap[img] = summary
}
if opts.SharedSize {
@@ -257,6 +255,10 @@ func (i *ImageService) Images(ctx context.Context, opts imagebackend.ListOptions
}
}
summaries := make([]imagetypes.Summary, 0, len(summaryMap))
for _, summary := range summaryMap {
summaries = append(summaries, *summary)
}
sort.Sort(sort.Reverse(byCreated(summaries)))
return summaries, nil

View File

@@ -17,6 +17,7 @@ import (
"github.com/distribution/reference"
"github.com/docker/distribution"
"github.com/moby/go-archive"
"github.com/moby/go-archive/compression"
"github.com/moby/moby/api/types/events"
"github.com/moby/moby/v2/daemon/internal/image"
v1 "github.com/moby/moby/v2/daemon/internal/image/v1"
@@ -395,7 +396,7 @@ func (s *saveSession) writeTar(ctx context.Context, tempDir string, outStream io
ctx, span := tracing.StartSpan(ctx, "writeTar")
defer span.End()
fs, err := archive.Tar(tempDir, archive.Uncompressed)
fs, err := archive.Tar(tempDir, compression.None)
if err != nil {
span.SetStatus(err)
return err

View File

@@ -294,12 +294,15 @@ func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, descr
descriptor: descriptor,
}
if cErr = ls.driver.Create(layer.cacheID, pid, nil); cErr != nil {
tx, cErr := ls.store.StartTransaction()
if cErr != nil {
return nil, cErr
}
tx, cErr := ls.store.StartTransaction()
if cErr != nil {
if cErr = ls.driver.Create(layer.cacheID, pid, nil); cErr != nil {
if err := tx.Cancel(); err != nil {
log.G(context.TODO()).WithFields(log.Fields{"cache-id": layer.cacheID, "error": err}).Error("Error canceling metadata transaction")
}
return nil, cErr
}
@@ -532,6 +535,9 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWL
return nil, err
}
if err := ls.saveMount(m); err != nil {
if removeErr := ls.driver.Remove(m.mountID); removeErr != nil {
log.G(context.TODO()).WithFields(log.Fields{"mount-id": m.mountID, "error": removeErr}).Error("Failed to clean up RW layer after mount save failure")
}
return nil, err
}
@@ -642,7 +648,7 @@ func (ls *layerStore) saveMount(mount *mountedLayer) error {
return nil
}
func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc MountInit, storageOpt map[string]string) (string, error) {
func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc MountInit, storageOpt map[string]string) (_ string, retErr error) {
// Use "<graph-id>-init" to maintain compatibility with graph drivers
// which are expecting this layer with this special name. If all
// graph drivers can be updated to not rely on knowing about this layer
@@ -657,6 +663,16 @@ func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc Mou
if err := ls.driver.CreateReadWrite(initID, parent, createOpts); err != nil {
return "", err
}
// Clean up init layer if any subsequent operation fails
defer func() {
if retErr != nil {
if err := ls.driver.Remove(initID); err != nil {
log.G(context.TODO()).WithFields(log.Fields{"init-id": initID, "error": err}).Error("Failed to clean up init layer after error")
}
}
}()
p, err := ls.driver.Get(initID, "")
if err != nil {
return "", err

View File

@@ -12,6 +12,7 @@ import (
"github.com/containerd/continuity/driver"
"github.com/moby/go-archive"
"github.com/moby/go-archive/compression"
"github.com/moby/moby/v2/daemon/graphdriver"
"github.com/moby/moby/v2/daemon/graphdriver/vfs"
"github.com/moby/moby/v2/daemon/internal/stringid"
@@ -587,7 +588,7 @@ func tarFromFiles(files ...FileApplier) ([]byte, error) {
}
}
r, err := archive.Tar(td, archive.Uncompressed)
r, err := archive.Tar(td, compression.None)
if err != nil {
return nil, err
}

View File

@@ -42,6 +42,9 @@ func decodeCreateRequest(src io.Reader) (container.CreateRequest, error) {
if w.HostConfig == nil {
w.HostConfig = &container.HostConfig{}
}
if w.HostConfig.PortBindings == nil {
w.HostConfig.PortBindings = make(network.PortMap)
}
// Make sure NetworkMode has an acceptable value. We do this to ensure
// backwards compatible API behavior.
//

View File

@@ -220,7 +220,7 @@ func TestAddPortMappings(t *testing.T) {
enableProxy bool
hairpin bool
busyPortIPv4 int
rootless bool
newPDC func() nat.PortDriverClient
hostAddrs []string
noProxy6To4 bool
@@ -667,7 +667,7 @@ func TestAddPortMappings(t *testing.T) {
{PortBinding: types.PortBinding{Proto: types.TCP, Port: 80}},
},
enableProxy: true,
rootless: true,
newPDC: func() nat.PortDriverClient { return newMockPortDriverClient(true) },
expPBs: []types.PortBinding{
{Proto: types.TCP, IP: ctrIP4.IP, Port: 22, HostIP: net.IPv4zero, HostPort: firstEphemPort},
{Proto: types.TCP, IP: ctrIP6.IP, Port: 22, HostIP: net.IPv6zero, HostPort: firstEphemPort},
@@ -675,6 +675,21 @@ func TestAddPortMappings(t *testing.T) {
{Proto: types.TCP, IP: ctrIP6.IP, Port: 80, HostIP: net.IPv6zero, HostPort: firstEphemPort + 1},
},
},
{
name: "rootless, ipv6 not supported",
epAddrV4: ctrIP4,
epAddrV6: ctrIP6,
cfg: []portmapperapi.PortBindingReq{
{PortBinding: types.PortBinding{Proto: types.TCP, Port: 22}},
{PortBinding: types.PortBinding{Proto: types.TCP, Port: 80}},
},
enableProxy: true,
newPDC: func() nat.PortDriverClient { return newMockPortDriverClient(false) },
expPBs: []types.PortBinding{
{Proto: types.TCP, IP: ctrIP4.IP, Port: 22, HostIP: net.IPv4zero, HostPort: firstEphemPort},
{Proto: types.TCP, IP: ctrIP4.IP, Port: 80, HostIP: net.IPv4zero, HostPort: firstEphemPort + 1},
},
},
{
name: "rootless without proxy",
epAddrV4: ctrIP4,
@@ -683,8 +698,8 @@ func TestAddPortMappings(t *testing.T) {
{PortBinding: types.PortBinding{Proto: types.TCP, Port: 22}},
{PortBinding: types.PortBinding{Proto: types.TCP, Port: 80}},
},
rootless: true,
hairpin: true,
newPDC: func() nat.PortDriverClient { return newMockPortDriverClient(true) },
hairpin: true,
expPBs: []types.PortBinding{
{Proto: types.TCP, IP: ctrIP4.IP, Port: 22, HostIP: net.IPv4zero, HostPort: firstEphemPort},
{Proto: types.TCP, IP: ctrIP6.IP, Port: 22, HostIP: net.IPv6zero, HostPort: firstEphemPort},
@@ -745,8 +760,8 @@ func TestAddPortMappings(t *testing.T) {
}
var pdc nat.PortDriverClient
if tc.rootless {
pdc = newMockPortDriverClient()
if tc.newPDC != nil {
pdc = tc.newPDC()
}
pms := &drvregistry.PortMappers{}
@@ -780,7 +795,7 @@ func TestAddPortMappings(t *testing.T) {
n.firewallerNetwork = fwn
expChildIP := func(hostIP net.IP) net.IP {
if !tc.rootless {
if pdc == nil {
return hostIP
}
if hostIP.To4() == nil {
@@ -938,16 +953,21 @@ func (p mockPortDriverPort) String() string {
type mockPortDriverClient struct {
openPorts map[mockPortDriverPort]bool
supportV6 bool
}
func newMockPortDriverClient() *mockPortDriverClient {
func newMockPortDriverClient(supportV6 bool) *mockPortDriverClient {
return &mockPortDriverClient{
openPorts: map[mockPortDriverPort]bool{},
supportV6: supportV6,
}
}
func (c *mockPortDriverClient) ChildHostIP(hostIP netip.Addr) netip.Addr {
func (c *mockPortDriverClient) ChildHostIP(proto string, hostIP netip.Addr) netip.Addr {
if hostIP.Is6() {
if !c.supportV6 {
return netip.Addr{}
}
return netip.IPv6Loopback()
}
return netip.MustParseAddr("127.0.0.1")

View File

@@ -75,14 +75,38 @@ func NewPortDriverClient(ctx context.Context) (*PortDriverClient, error) {
return pdc, nil
}
// proto normalizes the protocol to match what the rootlesskit API expects.
func (c *PortDriverClient) proto(proto string, hostIP netip.Addr) string {
// proto is like "tcp", but we need to convert it to "tcp4" or "tcp6" explicitly
// for libnetwork >= 20201216
//
// See https://github.com/moby/libnetwork/pull/2604/files#diff-8fa48beed55dd033bf8e4f8c40b31cf69d0b2cc5d4bb53cde8594670ea6c938aR20
// See also https://github.com/rootless-containers/rootlesskit/issues/231
apiProto := proto
if !strings.HasSuffix(apiProto, "4") && !strings.HasSuffix(apiProto, "6") {
if hostIP.Is6() {
apiProto += "6"
} else {
apiProto += "4"
}
}
return apiProto
}
// ChildHostIP returns the address that must be used in the child network
// namespace in place of hostIP, a host IP address. In particular, port
// mappings from host IP addresses, and DNAT rules, must use this child
// address in place of the real host address.
func (c *PortDriverClient) ChildHostIP(hostIP netip.Addr) netip.Addr {
// address in place of the real host address. It may return an invalid
// netip.Addr if the proto and IP family aren't supported.
func (c *PortDriverClient) ChildHostIP(proto string, hostIP netip.Addr) netip.Addr {
if c == nil {
return hostIP
}
if _, ok := c.protos[c.proto(proto, hostIP)]; !ok {
// This happens when apiProto="tcp6", portDriverName="slirp4netns",
// because "slirp4netns" port driver does not support listening on IPv6 yet.
return netip.Addr{}
}
if c.childIP.IsValid() {
return c.childIP
}
@@ -117,20 +141,8 @@ func (c *PortDriverClient) AddPort(
if c == nil {
return func() error { return nil }, nil
}
// proto is like "tcp", but we need to convert it to "tcp4" or "tcp6" explicitly
// for libnetwork >= 20201216
//
// See https://github.com/moby/libnetwork/pull/2604/files#diff-8fa48beed55dd033bf8e4f8c40b31cf69d0b2cc5d4bb53cde8594670ea6c938aR20
// See also https://github.com/rootless-containers/rootlesskit/issues/231
apiProto := proto
if !strings.HasSuffix(apiProto, "4") && !strings.HasSuffix(apiProto, "6") {
if hostIP.Is6() {
apiProto += "6"
} else {
apiProto += "4"
}
}
apiProto := c.proto(proto, hostIP)
if _, ok := c.protos[apiProto]; !ok {
// This happens when apiProto="tcp6", portDriverName="slirp4netns",
// because "slirp4netns" port driver does not support listening on IPv6 yet.

View File

@@ -251,9 +251,14 @@ func deleteEpFromResolverImpl(
}
func findHNSEp(ip4, ip6 *net.IPNet, hnsEndpoints []hcsshim.HNSEndpoint) *hcsshim.HNSEndpoint {
if ip4 == nil && ip6 == nil {
return nil
}
for _, hnsEp := range hnsEndpoints {
if (hnsEp.IPAddress != nil && hnsEp.IPAddress.Equal(ip4.IP)) ||
(hnsEp.IPv6Address != nil && hnsEp.IPv6Address.Equal(ip6.IP)) {
if ip4 != nil && hnsEp.IPAddress != nil && hnsEp.IPAddress.Equal(ip4.IP) {
return &hnsEp
}
if ip6 != nil && hnsEp.IPv6Address != nil && hnsEp.IPv6Address.Equal(ip6.IP) {
return &hnsEp
}
}

View File

@@ -135,6 +135,7 @@ func StartProxy(pb types.PortBinding,
return nil
}
stopped.Store(true)
log.G(context.Background()).WithField("pb", pb).Debug("Stopping userland proxy")
if err := cmd.Process.Signal(os.Interrupt); err != nil {
return err
}

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"net"
"net/netip"
"slices"
"strconv"
"github.com/containerd/log"
@@ -13,12 +14,13 @@ import (
"github.com/moby/moby/v2/daemon/libnetwork/portallocator"
"github.com/moby/moby/v2/daemon/libnetwork/portmapperapi"
"github.com/moby/moby/v2/daemon/libnetwork/types"
"github.com/moby/moby/v2/internal/sliceutil"
)
const driverName = "nat"
type PortDriverClient interface {
ChildHostIP(hostIP netip.Addr) netip.Addr
ChildHostIP(proto string, hostIP netip.Addr) netip.Addr
AddPort(ctx context.Context, proto string, hostIP, childIP netip.Addr, hostPort int) (func() error, error)
}
@@ -73,12 +75,18 @@ func (pm PortMapper) MapPorts(ctx context.Context, cfg []portmapperapi.PortBindi
}
}()
addrs := make([]net.IP, 0, len(cfg))
for i := range cfg {
cfg[i] = setChildHostIP(pm.pdc, cfg[i])
addrs = append(addrs, cfg[i].ChildHostIP)
for i := len(cfg) - 1; i >= 0; i-- {
var supported bool
if cfg[i], supported = setChildHostIP(pm.pdc, cfg[i]); !supported {
cfg = slices.Delete(cfg, i, i+1)
continue
}
}
addrs := sliceutil.Map(cfg, func(req portmapperapi.PortBindingReq) net.IP {
return req.ChildHostIP
})
pa := portallocator.NewOSAllocator()
allocatedPort, socks, err := pa.RequestPortsInRange(addrs, proto, int(hostPort), int(hostPortEnd))
if err != nil {
@@ -127,14 +135,21 @@ func (pm PortMapper) UnmapPorts(ctx context.Context, pbs []portmapperapi.PortBin
return errors.Join(errs...)
}
func setChildHostIP(pdc PortDriverClient, req portmapperapi.PortBindingReq) portmapperapi.PortBindingReq {
// setChildHostIP returns a modified PortBindingReq that contains the IP
// address that should be used for port allocation, firewall rules, etc. It
// returns false when the PortBindingReq isn't supported by the PortDriverClient.
func setChildHostIP(pdc PortDriverClient, req portmapperapi.PortBindingReq) (portmapperapi.PortBindingReq, bool) {
if pdc == nil {
req.ChildHostIP = req.HostIP
return req
return req, true
}
hip, _ := netip.AddrFromSlice(req.HostIP)
req.ChildHostIP = pdc.ChildHostIP(hip.Unmap()).AsSlice()
return req
chip := pdc.ChildHostIP(req.Proto.String(), hip.Unmap())
if !chip.IsValid() {
return req, false
}
req.ChildHostIP = chip.AsSlice()
return req, true
}
// configPortDriver passes the port binding's details to rootlesskit, and updates the

View File

@@ -264,17 +264,8 @@ func (sb *Sandbox) loadResolvConf(path string) (*resolvconf.ResolvConf, error) {
// be a copy of the host's file, with overrides for nameservers, options and search
// domains applied.
func (sb *Sandbox) setupDNS() error {
sb.restoreResolvConfPath()
// When the container is restarted, a new Sandbox is created but the same resolv.conf is re-used. If it was
// user-modified, do not attempt to overwrite it.
if !sb.config.useDefaultSandBox {
if mod, err := resolvconf.UserModified(sb.config.resolvConfPath, sb.config.resolvConfHashFile); err != nil || mod {
return err
}
}
// Make sure the directory exists.
sb.restoreResolvConfPath()
dir, _ := filepath.Split(sb.config.resolvConfPath)
if err := createBasePath(dir); err != nil {
return err
@@ -338,7 +329,15 @@ func (sb *Sandbox) rebuildDNS() error {
// upstream nameservers.
sb.setExternalResolvers(extNameServers)
return rc.WriteFile(sb.config.resolvConfPath, sb.config.resolvConfHashFile, filePerm)
// Write the file for the container - preserving old behaviour, not updating the
// hash file (so, no further updates will be made).
// TODO(robmry) - I think that's probably accidental, I can't find a reason for it,
// and the old resolvconf.Build() function wrote the file but not the hash, which
// is surprising. But, before fixing it, a guard/flag needs to be added to
// sb.updateDNS() to make sure that when an endpoint joins a sandbox that already
// has an internal resolver, the container's resolv.conf is still (re)configured
// for an internal resolver.
return rc.WriteFile(sb.config.resolvConfPath, "", filePerm)
}
func createBasePath(dir string) error {

View File

@@ -14,17 +14,12 @@ import (
is "gotest.tools/v3/assert/cmp"
)
func getResolvConf(t *testing.T, rcPath string) resolvconf.ResolvConf {
func getResolvConfOptions(t *testing.T, rcPath string) []string {
t.Helper()
resolv, err := os.ReadFile(rcPath)
assert.NilError(t, err)
rc, err := resolvconf.Parse(bytes.NewBuffer(resolv), "")
assert.NilError(t, err)
return rc
}
func getResolvConfOptions(t *testing.T, rcPath string) []string {
rc := getResolvConf(t, rcPath)
return rc.Options()
}
@@ -95,60 +90,3 @@ func TestDNSOptions(t *testing.T) {
dnsOptionsList = getResolvConfOptions(t, sb2.config.resolvConfPath)
assert.Check(t, is.DeepEqual([]string{"ndots:0"}, dnsOptionsList))
}
func TestNonHostNetDNSRestart(t *testing.T) {
c, err := New(context.Background(), config.OptionDataDir(t.TempDir()))
assert.NilError(t, err)
// Step 1: Create initial sandbox (simulating first container start)
sb, err := c.NewSandbox(context.Background(), "cnt1")
assert.NilError(t, err)
defer func() {
_ = sb.Delete(context.Background())
}()
sb.startResolver(false)
err = sb.setupDNS()
assert.NilError(t, err)
err = sb.rebuildDNS()
assert.NilError(t, err)
// Step 2: Simulate user manually overwriting the container's resolv.conf
resolvConfPath := sb.config.resolvConfPath
modifiedContent := []byte(`nameserver 1.1.1.1`)
err = os.WriteFile(resolvConfPath, modifiedContent, 0644)
assert.NilError(t, err)
// Step 3: Delete the sandbox (simulating container stop)
err = sb.Delete(context.Background())
assert.NilError(t, err)
// Step 4: Create a new sandbox (simulating container restart)
sbRestart, err := c.NewSandbox(context.Background(), "cnt1",
OptionResolvConfPath(resolvConfPath),
)
assert.NilError(t, err)
defer func() {
if err := sbRestart.Delete(context.Background()); err != nil {
t.Error(err)
}
}()
sbRestart.startResolver(false)
// Step 5: Call setupDNS on restart - should preserve user modifications
err = sbRestart.setupDNS()
assert.NilError(t, err)
rc := getResolvConf(t, sbRestart.config.resolvConfPath)
assert.Check(t, is.Equal("1.1.1.1", rc.NameServers()[0].String()))
// Step 6: Call rebuildDNS on restart - should preserve user modifications
err = sbRestart.rebuildDNS()
assert.NilError(t, err)
rc = getResolvConf(t, sbRestart.config.resolvConfPath)
assert.Check(t, is.Equal("1.1.1.1", rc.NameServers()[0].String()))
}

View File

@@ -366,11 +366,6 @@ func (sb *Sandbox) populateNetworkResourcesOS(ctx context.Context, ep *Endpoint)
if ep.needResolver() {
sb.startResolver(false)
} else {
// Make sure /etc/resolv.conf is set up.
if err := sb.updateDNS(ep.getNetwork().enableIPv6); err != nil {
return err
}
}
if i != nil && i.srcName != "" {
@@ -453,6 +448,10 @@ func (sb *Sandbox) populateNetworkResourcesOS(ctx context.Context, ep *Endpoint)
}
sb.addHostsEntries(ctx, ep.getEtcHostsAddrs())
// Make sure /etc/resolv.conf is set up.
if err := sb.updateDNS(ep.getNetwork().enableIPv6); err != nil {
return err
}
// Populate load balancer only after updating all the other
// information including gateway and other routes so that

View File

@@ -1038,10 +1038,13 @@ func buildPortsRelatedCreateEndpointOptions(c *container.Container, n *libnetwor
)
ports := c.HostConfig.PortBindings
if c.HostConfig.PublishAllPorts {
if c.HostConfig.PublishAllPorts && len(c.Config.ExposedPorts) > 0 {
// Add exposed ports to a copy of the map to make sure a "publishedPorts" entry is created
// for each exposed port, even if there's no specific binding.
ports = maps.Clone(c.HostConfig.PortBindings)
if ports == nil {
ports = networktypes.PortMap{}
}
for p := range c.Config.ExposedPorts {
if _, exists := ports[p]; !exists {
ports[p] = nil

View File

@@ -2,6 +2,7 @@ package daemon
import (
"context"
"crypto/sha256"
"encoding/hex"
"os"
"path/filepath"
@@ -259,10 +260,11 @@ func (daemon *Daemon) registerMountPoints(ctr *container.Container, defaultReadO
StorageOpt: ctr.HostConfig.StorageOpt,
}
// Include the destination in the layer name to make it unique for each mount point and container.
// Hash the source and destination to create a safe, unique identifier for each mount point and container.
// This makes sure that the same image can be mounted multiple times with different destinations.
// Hex encode the destination to create a safe, unique identifier
layerName := hex.EncodeToString([]byte(ctr.ID + ",src=" + mp.Source + ",dst=" + mp.Destination))
// We hash it so that the snapshot name is friendly to the underlying filesystem and doesn't exceed path length limits.
destHash := sha256.Sum256([]byte(ctr.ID + "-src=" + mp.Source + "-dst=" + mp.Destination))
layerName := hex.EncodeToString(destHash[:])
layer, err := daemon.imageService.CreateLayerFromImage(img, layerName, rwLayerOpts)
if err != nil {
return err

10
go.mod
View File

@@ -56,13 +56,13 @@ require (
github.com/miekg/dns v1.1.66
github.com/mistifyio/go-zfs/v3 v3.1.0
github.com/mitchellh/copystructure v1.2.0
github.com/moby/buildkit v0.26.2
github.com/moby/buildkit v0.26.3
github.com/moby/docker-image-spec v1.3.1
github.com/moby/go-archive v0.1.0
github.com/moby/ipvs v1.1.0
github.com/moby/locker v1.0.1
github.com/moby/moby/api v1.52.1-0.20251127112201-20634eddce67
github.com/moby/moby/client v0.1.1-0.20251127130102-d55f77dbfc3e
github.com/moby/moby/api v1.52.0
github.com/moby/moby/client v0.2.1
github.com/moby/patternmatcher v0.6.0
github.com/moby/policy-helpers v0.0.0-20251105011237-bcaa71c99f14
github.com/moby/profiles/apparmor v0.1.0
@@ -160,7 +160,7 @@ require (
github.com/containerd/stargz-snapshotter/estargz v0.17.0 // indirect
github.com/containerd/ttrpc v1.2.7 // indirect
github.com/containernetworking/cni v1.3.0 // indirect
github.com/containernetworking/plugins v1.8.0 // indirect
github.com/containernetworking/plugins v1.9.0 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/cyphar/filepath-securejoin v0.6.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
@@ -193,7 +193,7 @@ require (
github.com/hiddeco/sshsig v0.2.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmoiron/sqlx v1.3.3 // indirect
github.com/klauspost/compress v1.18.1 // indirect
github.com/klauspost/compress v1.18.2 // indirect
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/sys/capability v0.4.0 // indirect

20
go.sum
View File

@@ -168,8 +168,8 @@ github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
github.com/containernetworking/cni v1.3.0 h1:v6EpN8RznAZj9765HhXQrtXgX+ECGebEYEmnuFjskwo=
github.com/containernetworking/cni v1.3.0/go.mod h1:Bs8glZjjFfGPHMw6hQu82RUgEPNGEaBb9KS5KtNMnJ4=
github.com/containernetworking/plugins v1.8.0 h1:WjGbV/0UQyo8A4qBsAh6GaDAtu1hevxVxsEuqtBqUFk=
github.com/containernetworking/plugins v1.8.0/go.mod h1:JG3BxoJifxxHBhG3hFyxyhid7JgRVBu/wtooGEvWf1c=
github.com/containernetworking/plugins v1.9.0 h1:Mg3SXBdRGkdXyFC4lcwr6u2ZB2SDeL6LC3U+QrEANuQ=
github.com/containernetworking/plugins v1.9.0/go.mod h1:JG3BxoJifxxHBhG3hFyxyhid7JgRVBu/wtooGEvWf1c=
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo=
@@ -375,8 +375,8 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=
github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0=
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -417,8 +417,8 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
github.com/mitchellh/mapstructure v0.0.0-20170523030023-d0303fe80992/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/buildkit v0.26.2 h1:EIh5j0gzRsCZmQzvgNNWzSDbuKqwUIiBH7ssqLv8RU8=
github.com/moby/buildkit v0.26.2/go.mod h1:ylDa7IqzVJgLdi/wO7H1qLREFQpmhFbw2fbn4yoTw40=
github.com/moby/buildkit v0.26.3 h1:D+ruZVAk/3ipRq5XRxBH9/DIFpRjSlTtMbghT5gQP9g=
github.com/moby/buildkit v0.26.3/go.mod h1:4T4wJzQS4kYWIfFRjsbJry4QoxDBjK+UGOEOs1izL7w=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
@@ -427,10 +427,10 @@ github.com/moby/ipvs v1.1.0 h1:ONN4pGaZQgAx+1Scz5RvWV4Q7Gb+mvfRh3NsPS+1XQQ=
github.com/moby/ipvs v1.1.0/go.mod h1:4VJMWuf098bsUMmZEiD4Tjk/O7mOn3l1PTD3s4OoYAs=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/moby/api v1.52.1-0.20251127112201-20634eddce67 h1:n3faoyhuHCuKrrJNJOYaYKYTX5ZbZ9Zp7dMdlsZCOFw=
github.com/moby/moby/api v1.52.1-0.20251127112201-20634eddce67/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=
github.com/moby/moby/client v0.1.1-0.20251127130102-d55f77dbfc3e h1:HrWrBVqHS4Oy0xL7RQJFlBlOGyYuu5btzLytX9DXyJc=
github.com/moby/moby/client v0.1.1-0.20251127130102-d55f77dbfc3e/go.mod h1:8rNHNx7Fo0vnFNjztsJuFrOjai5x2qge2VvK5gAz90Y=
github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg=
github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=
github.com/moby/moby/client v0.2.1 h1:1Grh1552mvv6i+sYOdY+xKKVTvzJegcVMhuXocyDz/k=
github.com/moby/moby/client v0.2.1/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE=
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/policy-helpers v0.0.0-20251105011237-bcaa71c99f14 h1:JO22uXMy3CN7wh7A/wrtYQWV1WYQMg2gh6d8YO325k4=

View File

@@ -7,7 +7,7 @@ set -e
# The version of runc should match the version that is used by the containerd
# version that is used. If you need to update runc, open a pull request in
# the containerd project first, and update both after that is merged.
: "${RUNC_VERSION:=v1.3.3}"
: "${RUNC_VERSION:=v1.3.4}"
install_runc() {
RUNC_BUILDTAGS="${RUNC_BUILDTAGS:-"seccomp"}"

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.25.4
ARG GO_VERSION=1.25.5
ARG BASE_DEBIAN_DISTRO="bookworm"
ARG PROTOC_VERSION=3.11.4

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.25.4
ARG GO_VERSION=1.25.5
ARG GOVULNCHECK_VERSION=v1.1.4
ARG FORMAT=text

View File

@@ -4,17 +4,23 @@ set -e
SCRIPTDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPTDIR}/.validate"
IFS=$'\n'
api_files=$(validate_diff --diff-filter=ACMR --name-only -- 'api/' || true)
api_files=$(
validate_diff --diff-filter=ACMR --name-only -- \
'api/' \
':(exclude)api/README.md' \
':(exclude)api/swagger.yaml' \
':(exclude)api/docs/' \
|| true
)
client_files=$(validate_diff --diff-filter=ACMR --name-only -- 'client/' || true)
unset IFS
has_errors=0
cat go.mod
# Check if changes to ./api require a replace rule in go.mod
if [ -n "${TEST_FORCE_VALIDATE:-}" ] || [ ${#api_files[@]} -gt 0 ]; then
if [ -n "${TEST_FORCE_VALIDATE:-}" ] || [ -n "${api_files}" ]; then
echo "Detected changes in ./api directory, checking for replace rule..."
if ! go list -mod=readonly -m -json github.com/moby/moby/api | jq -e '.Replace'; then
echo >&2 "ERROR: Changes detected in ./api but go.mod is missing a replace rule for github.com/moby/moby/api"
@@ -26,7 +32,7 @@ if [ -n "${TEST_FORCE_VALIDATE:-}" ] || [ ${#api_files[@]} -gt 0 ]; then
fi
# Check if changes to ./client require a replace rule in go.mod
if [ -n "${TEST_FORCE_VALIDATE:-}" ] || [ ${#client_files[@]} -gt 0 ]; then
if [ -n "${TEST_FORCE_VALIDATE:-}" ] || [ -n "${client_files}" ]; then
echo "Detected changes in ./client directory, checking for replace rule..."
if ! go list -mod=readonly -m -json github.com/moby/moby/client | jq -e '.Replace'; then
echo >&2 "ERROR: Changes detected in ./client but go.mod is missing a replace rule for github.com/moby/moby/client"

View File

@@ -2024,11 +2024,11 @@ CMD ["cat", "/foo"]`),
}
func (s *DockerCLIBuildSuite) TestBuildContextTarGzip(c *testing.T) {
testContextTar(c, archive.Gzip)
testContextTar(c, compression.Gzip)
}
func (s *DockerCLIBuildSuite) TestBuildContextTarNoCompression(c *testing.T) {
testContextTar(c, archive.Uncompressed)
testContextTar(c, compression.None)
}
func (s *DockerCLIBuildSuite) TestBuildNoContext(c *testing.T) {

View File

@@ -8,6 +8,7 @@ import (
containertypes "github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/container"
"github.com/moby/moby/v2/internal/testutil/daemon"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/fs"
@@ -107,3 +108,26 @@ func TestRemoveInvalidContainer(t *testing.T) {
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
assert.Check(t, is.ErrorContains(err, "No such container"))
}
func TestRemoveDeadContainersOnDaemonRestart(t *testing.T) {
skip.If(t, testEnv.IsRemoteDaemon)
skip.If(t, testEnv.DaemonInfo.OSType == "windows", "FIXME: Windows CI does not support multiple daemons yet")
ctx := setupTest(t)
d := daemon.New(t)
d.StartWithBusybox(ctx, t)
defer d.Stop(t)
apiClient := d.NewClientT(t)
container.Run(ctx, t, apiClient, container.WithCmd("top"), container.WithAutoRemove)
list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{All: true})
assert.NilError(t, err)
assert.Check(t, is.Len(list.Items, 1))
d.Restart(t)
list, err = apiClient.ContainerList(ctx, client.ContainerListOptions{All: true})
assert.NilError(t, err)
assert.Check(t, is.Len(list.Items, 0))
}

View File

@@ -82,6 +82,74 @@ func TestImageInspectDescriptor(t *testing.T) {
assert.Check(t, inspect.Descriptor.Size > 0)
}
// Regression test for: https://github.com/moby/moby/issues/51566
//
// This can be reproduced with two image that share the same uncompressed layer
// but have a different compressed blob is pulled.
//
// Example:
// ```
// docker pull nginx@sha256:3b7732505933ca591ce4a6d860cb713ad96a3176b82f7979a8dfa9973486a0d6
// docker pull gotenberg/gotenberg@sha256:b116a40a1c24917e2bf3e153692da5acd2e78e7cd67e1b2d243b47c178f31c90
// ```
//
// In this case, it's the base debian trixie image that's used as a base.
// They're effectively the same layer (unpacked diff ID
// `sha256:1d46119d249f7719e1820e24a311aa7c453f166f714969cffe89504678eaa447`),
// but different compressed blobs:
//
// # nginx
// {
// "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
// "size": 29777766,
// "digest": "sha256:8c7716127147648c1751940b9709b6325f2256290d3201662eca2701cadb2cdf"
// }
//
// # gotenberg
// {
// "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
// "size": 30781333,
// "digest": "sha256:b96413fb491a5ed179bb2746ff3be6cbddd72e14c6503bea80d58e579a3b92bc"
// },
func TestImageInspectWithoutSomeBlobs(t *testing.T) {
t.Skip("TODO(vvoland): Come up with minimal images for this test")
skip.If(t, testEnv.DaemonInfo.OSType != "linux", "The test images are Linux-only")
ctx := setupTest(t)
apiClient := testEnv.APIClient()
const baseImage = "nginx@sha256:3b7732505933ca591ce4a6d860cb713ad96a3176b82f7979a8dfa9973486a0d6"
const childImage = "gotenberg/gotenberg:8.24@sha256:b116a40a1c24917e2bf3e153692da5acd2e78e7cd67e1b2d243b47c178f31c90"
// Pull the base image first and then the child image
for _, image := range []string{baseImage, childImage} {
rdr, err := apiClient.ImagePull(ctx, image, client.ImagePullOptions{})
assert.NilError(t, err)
assert.NilError(t, rdr.Wait(ctx))
t.Cleanup(func() {
_, _ = apiClient.ImageRemove(ctx, image, client.ImageRemoveOptions{})
})
}
var raw bytes.Buffer
inspect, err := apiClient.ImageInspect(ctx, childImage, client.ImageInspectWithRawResponse(&raw))
assert.NilError(t, err)
var rawJson map[string]any
err = json.Unmarshal(raw.Bytes(), &rawJson)
assert.NilError(t, err)
configVal, hasConfig := rawJson["Config"]
assert.Check(t, hasConfig, "Config field should exist in JSON response")
if assert.Check(t, configVal != nil, "Config should not be null in JSON response") {
assert.Check(t, is.DeepEqual(inspect.Config.Cmd, []string{"gotenberg"}))
assert.Check(t, inspect.Os != "")
assert.Check(t, inspect.Architecture != "")
}
}
func TestImageInspectWithPlatform(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType == "windows", "The test image is a Linux image")
ctx := setupTest(t)

View File

@@ -72,6 +72,13 @@ func WithSysctls(sysctls map[string]string) func(*TestContainerConfig) {
}
}
// WithPublishAllPorts sets PublishAllPorts.
func WithPublishAllPorts(publishAll bool) func(*TestContainerConfig) {
return func(c *TestContainerConfig) {
c.HostConfig.PublishAllPorts = publishAll
}
}
// WithExposedPorts sets the exposed ports of the container
func WithExposedPorts(ports ...string) func(*TestContainerConfig) {
return func(c *TestContainerConfig) {

View File

@@ -22,12 +22,14 @@ import (
"github.com/moby/moby/v2/daemon/libnetwork/drivers/bridge"
"github.com/moby/moby/v2/daemon/libnetwork/iptables"
"github.com/moby/moby/v2/daemon/libnetwork/netlabel"
"github.com/moby/moby/v2/integration/internal/build"
"github.com/moby/moby/v2/integration/internal/container"
"github.com/moby/moby/v2/integration/internal/network"
"github.com/moby/moby/v2/integration/internal/testutils/networking"
n "github.com/moby/moby/v2/integration/network"
"github.com/moby/moby/v2/internal/testutil"
"github.com/moby/moby/v2/internal/testutil/daemon"
"github.com/moby/moby/v2/internal/testutil/fakecontext"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/icmd"
@@ -2139,3 +2141,18 @@ func TestGatewayErrorOnNetDisconnect(t *testing.T) {
assert.Check(t, is.Contains(ctrInsp.NetworkSettings.Networks, "n1"))
assert.Check(t, is.Contains(ctrInsp.NetworkSettings.Networks, "n2"))
}
// Regression test for https://github.com/moby/moby/issues/51620
func TestPublishAllWithNilPortBindings(t *testing.T) {
ctx := setupTest(t)
c := testEnv.APIClient()
imgWithExpose := container.WithImage(build.Do(ctx, t, c,
fakecontext.New(t, "", fakecontext.WithDockerfile("FROM busybox\nEXPOSE 80/tcp\n"))))
_ = container.Run(ctx, t, c,
container.WithAutoRemove,
container.WithPublishAllPorts(true),
imgWithExpose,
)
}

View File

@@ -212,41 +212,3 @@ func TestNslookupWindows(t *testing.T) {
// can only be changed in daemon.json using feature flag "windows-dns-proxy".
assert.Check(t, is.Contains(res.Stdout.String(), "Addresses:"))
}
// TestResolvConfPreservedOnRestart verifies that external modifications to
// /etc/resolv.conf are preserved when a non-host network container is restarted.
// Regression test for https://github.com/moby/moby/issues/51490
func TestResolvConfPreservedOnRestart(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType == "windows", "No /etc/resolv.conf on Windows")
ctx := setupTest(t)
d := daemon.New(t, daemon.WithResolvConf(network.GenResolvConf("8.8.8.8")))
d.StartWithBusybox(ctx, t)
defer d.Stop(t)
c := d.NewClientT(t)
defer c.Close()
const ctrName = "test-resolvconf-preserved-on-restart"
id := container.Run(ctx, t, c, container.WithName(ctrName))
defer c.ContainerRemove(ctx, id, client.ContainerRemoveOptions{Force: true})
appendContent := `# hello`
res, err := container.Exec(ctx, c, ctrName, []string{
"sh", "-c",
"echo '" + appendContent + "' >> /etc/resolv.conf",
})
assert.NilError(t, err)
assert.Check(t, is.Equal(res.ExitCode, 0))
// Restart the container.
_, err = c.ContainerRestart(ctx, ctrName, client.ContainerRestartOptions{})
assert.Assert(t, is.Nil(err))
// Verify the modification was preserved
res, err = container.Exec(ctx, c, ctrName, []string{"tail", "-n", "1", "/etc/resolv.conf"})
assert.NilError(t, err)
assert.Check(t, is.Equal(res.ExitCode, 0))
assert.Check(t, is.Contains(res.Stdout(), appendContent))
}

View File

@@ -10,6 +10,7 @@ import (
"time"
"github.com/moby/go-archive"
"github.com/moby/go-archive/compression"
"github.com/moby/moby/api/types/events"
plugintypes "github.com/moby/moby/api/types/plugin"
"github.com/moby/moby/api/types/registry"
@@ -209,7 +210,7 @@ func makePluginBundle(inPath string, opts ...CreateOpt) (io.ReadCloser, error) {
if err := archive.NewDefaultArchiver().CopyFileWithTar(cfg.binPath, filepath.Join(inPath, "rootfs", p.Entrypoint[0])); err != nil {
return nil, errors.Wrap(err, "error copying plugin binary to rootfs path")
}
tar, err := archive.Tar(inPath, archive.Uncompressed)
tar, err := archive.Tar(inPath, compression.None)
return tar, errors.Wrap(err, "error making plugin archive")
}

View File

@@ -11,6 +11,7 @@ import (
"github.com/distribution/reference"
"github.com/google/uuid"
"github.com/moby/go-archive"
"github.com/moby/go-archive/compression"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -137,7 +138,7 @@ func fileArchive(dir string, name string, content []byte) (io.ReadCloser, error)
return nil, err
}
return archive.Tar(tmp, archive.Uncompressed)
return archive.Tar(tmp, compression.None)
}
func writeLayerWithOneFile(dir string, filename string, content []byte) (ocispec.Descriptor, error) {

View File

@@ -27,6 +27,16 @@ Use the links above for more information on each.
# changelog
* Oct 20, 2025 - [1.18.1](https://github.com/klauspost/compress/releases/tag/v1.18.1)
* zstd: Add simple zstd EncodeTo/DecodeTo functions https://github.com/klauspost/compress/pull/1079
* zstd: Fix incorrect buffer size in dictionary encodes https://github.com/klauspost/compress/pull/1059
* s2: check for cap, not len of buffer in EncodeBetter/Best by @vdarulis in https://github.com/klauspost/compress/pull/1080
* zlib: Avoiding extra allocation in zlib.reader.Reset by @travelpolicy in https://github.com/klauspost/compress/pull/1086
* gzhttp: remove redundant err check in zstdReader by @ryanfowler in https://github.com/klauspost/compress/pull/1090
* flate: Faster load+store https://github.com/klauspost/compress/pull/1104
* flate: Simplify matchlen https://github.com/klauspost/compress/pull/1101
* flate: Use exact sizes for huffman tables https://github.com/klauspost/compress/pull/1103
* Feb 19th, 2025 - [1.18.0](https://github.com/klauspost/compress/releases/tag/v1.18.0)
* Add unsafe little endian loaders https://github.com/klauspost/compress/pull/1036
* fix: check `r.err != nil` but return a nil value error `err` by @alingse in https://github.com/klauspost/compress/pull/1028
@@ -36,6 +46,9 @@ Use the links above for more information on each.
* flate: Fix matchlen L5+L6 https://github.com/klauspost/compress/pull/1049
* flate: Cleanup & reduce casts https://github.com/klauspost/compress/pull/1050
<details>
<summary>See changes to v1.17.x</summary>
* Oct 11th, 2024 - [1.17.11](https://github.com/klauspost/compress/releases/tag/v1.17.11)
* zstd: Fix extra CRC written with multiple Close calls https://github.com/klauspost/compress/pull/1017
* s2: Don't use stack for index tables https://github.com/klauspost/compress/pull/1014
@@ -102,7 +115,8 @@ https://github.com/klauspost/compress/pull/919 https://github.com/klauspost/comp
* s2: Do 2 overlapping match checks https://github.com/klauspost/compress/pull/839
* flate: Add amd64 assembly matchlen https://github.com/klauspost/compress/pull/837
* gzip: Copy bufio.Reader on Reset by @thatguystone in https://github.com/klauspost/compress/pull/860
</details>
<details>
<summary>See changes to v1.16.x</summary>
@@ -669,3 +683,4 @@ Here are other packages of good quality and pure Go (no cgo wrappers or autoconv
# license
This code is licensed under the same conditions as the original Go code. See LICENSE file.

View File

@@ -653,43 +653,7 @@ func (lbf *llbBridgeForwarder) ResolveSourceMeta(ctx context.Context, req *pb.Re
if err != nil {
return nil, err
}
r := &pb.ResolveSourceMetaResponse{
Source: resp.Op,
}
if resp.Image != nil {
r.Image = &pb.ResolveSourceImageResponse{
Digest: string(resp.Image.Digest),
Config: resp.Image.Config,
}
if resp.Image.AttestationChain != nil {
r.Image.AttestationChain = toPBAttestationChain(resp.Image.AttestationChain)
}
}
if resp.Git != nil {
r.Git = &pb.ResolveSourceGitResponse{
Checksum: resp.Git.Checksum,
Ref: resp.Git.Ref,
CommitChecksum: resp.Git.CommitChecksum,
CommitObject: resp.Git.CommitObject,
TagObject: resp.Git.TagObject,
}
}
if resp.HTTP != nil {
var lastModified *timestamp.Timestamp
if resp.HTTP.LastModified != nil {
lastModified = &timestamp.Timestamp{
Seconds: resp.HTTP.LastModified.Unix(),
}
}
r.HTTP = &pb.ResolveSourceHTTPResponse{
Checksum: resp.HTTP.Digest.String(),
Filename: resp.HTTP.Filename,
LastModified: lastModified,
}
}
return r, nil
return ToPBResolveSourceMetaResponse(resp), nil
}
func (lbf *llbBridgeForwarder) ResolveImageConfig(ctx context.Context, req *pb.ResolveImageConfigRequest) (*pb.ResolveImageConfigResponse, error) {
@@ -1705,6 +1669,45 @@ func getCaps(label string) map[string]struct{} {
return out
}
func ToPBResolveSourceMetaResponse(in *sourceresolver.MetaResponse) *pb.ResolveSourceMetaResponse {
r := &pb.ResolveSourceMetaResponse{
Source: in.Op,
}
if in.Image != nil {
r.Image = &pb.ResolveSourceImageResponse{
Digest: string(in.Image.Digest),
Config: in.Image.Config,
}
if in.Image.AttestationChain != nil {
r.Image.AttestationChain = toPBAttestationChain(in.Image.AttestationChain)
}
}
if in.Git != nil {
r.Git = &pb.ResolveSourceGitResponse{
Checksum: in.Git.Checksum,
Ref: in.Git.Ref,
CommitChecksum: in.Git.CommitChecksum,
CommitObject: in.Git.CommitObject,
TagObject: in.Git.TagObject,
}
}
if in.HTTP != nil {
var lastModified *timestamp.Timestamp
if in.HTTP.LastModified != nil {
lastModified = &timestamp.Timestamp{
Seconds: in.HTTP.LastModified.Unix(),
}
}
r.HTTP = &pb.ResolveSourceHTTPResponse{
Checksum: in.HTTP.Digest.String(),
Filename: in.HTTP.Filename,
LastModified: lastModified,
}
}
return r
}
func toPBAttestationChain(ac *sourceresolver.AttestationChain) *pb.AttestationChain {
if ac == nil {
return nil

View File

@@ -5,6 +5,7 @@ import (
"strings"
"github.com/moby/buildkit/client/llb/sourceresolver"
"github.com/moby/buildkit/frontend/gateway"
gatewaypb "github.com/moby/buildkit/frontend/gateway/pb"
"github.com/moby/buildkit/solver/pb"
"github.com/moby/buildkit/sourcepolicy"
@@ -88,19 +89,26 @@ func (p *policyEvaluator) Evaluate(ctx context.Context, op *pb.Op) (bool, error)
Platform: toOCIPlatform(metareq.Platform),
}
}
if metareq.Image != nil {
if op.ImageOpt == nil {
op.ImageOpt = &sourceresolver.ResolveImageOpt{}
}
op.ImageOpt.NoConfig = metareq.Image.NoConfig
op.ImageOpt.AttestationChain = metareq.Image.AttestationChain
}
if metareq.Git != nil {
op.GitOpt = &sourceresolver.ResolveGitOpt{
ReturnObject: metareq.Git.ReturnObject,
}
}
resp, err := p.resolveSourceMetadata(ctx, metareq.Source, op, false)
if err != nil {
return false, errors.Wrap(err, "error resolving source metadata from policy request")
}
req.Source = &gatewaypb.ResolveSourceMetaResponse{
Source: resp.Op,
}
if resp.Image != nil {
req.Source.Image = &gatewaypb.ResolveSourceImageResponse{
Digest: resp.Image.Digest.String(),
Config: resp.Image.Config,
}
}
req.Source = gateway.ToPBResolveSourceMetaResponse(resp)
continue
}

191
vendor/github.com/moby/moby/api/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,191 @@
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2013-2018 Docker, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

191
vendor/github.com/moby/moby/client/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,191 @@
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2013-2018 Docker, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

10
vendor/modules.txt vendored
View File

@@ -525,7 +525,7 @@ github.com/containernetworking/cni/pkg/types/create
github.com/containernetworking/cni/pkg/types/internal
github.com/containernetworking/cni/pkg/utils
github.com/containernetworking/cni/pkg/version
# github.com/containernetworking/plugins v1.8.0
# github.com/containernetworking/plugins v1.9.0
## explicit; go 1.24.2
github.com/containernetworking/plugins/pkg/ns
# github.com/coreos/go-semver v0.3.1
@@ -813,7 +813,7 @@ github.com/ishidawataru/sctp
# github.com/jmoiron/sqlx v1.3.3
## explicit; go 1.10
github.com/jmoiron/sqlx/types
# github.com/klauspost/compress v1.18.1
# github.com/klauspost/compress v1.18.2
## explicit; go 1.23
github.com/klauspost/compress
github.com/klauspost/compress/fse
@@ -838,7 +838,7 @@ github.com/mitchellh/hashstructure/v2
# github.com/mitchellh/reflectwalk v1.0.2
## explicit
github.com/mitchellh/reflectwalk
# github.com/moby/buildkit v0.26.2
# github.com/moby/buildkit v0.26.3
## explicit; go 1.24.3
github.com/moby/buildkit/api/services/control
github.com/moby/buildkit/api/types
@@ -1028,7 +1028,7 @@ github.com/moby/ipvs
# github.com/moby/locker v1.0.1
## explicit; go 1.13
github.com/moby/locker
# github.com/moby/moby/api v1.52.1-0.20251127112201-20634eddce67
# github.com/moby/moby/api v1.52.0
## explicit; go 1.24.0
github.com/moby/moby/api/pkg/authconfig
github.com/moby/moby/api/pkg/stdcopy
@@ -1050,7 +1050,7 @@ github.com/moby/moby/api/types/storage
github.com/moby/moby/api/types/swarm
github.com/moby/moby/api/types/system
github.com/moby/moby/api/types/volume
# github.com/moby/moby/client v0.1.1-0.20251127130102-d55f77dbfc3e
# github.com/moby/moby/client v0.2.1
## explicit; go 1.24.0
github.com/moby/moby/client
github.com/moby/moby/client/internal