Compare commits

...

445 Commits

Author SHA1 Message Date
Sebastiaan van Stijn
311b9ff0aa Merge pull request #46697 from thaJeztah/24.0_backport_restart_nocancel
[24.0 backport] daemon: daemon.containerRestart: don't cancel restart on context cancel
2023-10-26 09:51:05 +02:00
Sebastiaan van Stijn
af608045ee Merge pull request from GHSA-jq35-85cj-fj4p
[24.0 backport] deny /sys/devices/virtual/powercap
2023-10-25 23:57:51 +02:00
Sebastiaan van Stijn
3cf363e1ee Merge pull request #46709 from thaJeztah/24.0_backport_bump_compress
[24.0 backport] vendor: github.com/klauspost/compress v1.17.2
2023-10-24 16:30:50 +02:00
Sebastiaan van Stijn
05d7386665 daemon: daemon.containerRestart: don't cancel restart on context cancel
commit def549c8f6 passed through the context
to the daemon.ContainerStart function. As a result, restarting containers
no longer is an atomic operation, because a context cancellation could
interrupt the restart (between "stopping" and "(re)starting"), resulting
in the container being stopped, but not restarted.

Restarting a container, or more factually; making a successful request on
the `/containers/{id]/restart` endpoint, should be an atomic operation.

This patch uses a context.WithoutCancel for restart requests.

It's worth noting that daemon.containerStop already uses context.WithoutCancel,
so in that function, we'll be wrapping the context twice, but this should
likely not cause issues (just redundant for this code-path).

Before this patch, starting a container that bind-mounts the docker socket,
then restarting itself from within the container would cancel the restart
operation. The container would be stopped, but not started after that:

    docker run -dit --name myself -v /var/run/docker.sock:/var/run/docker.sock docker:cli sh
    docker exec myself sh -c 'docker restart myself'

    docker ps -a
    CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS                       PORTS     NAMES
    3a2a741c65ff   docker:cli    "docker-entrypoint.s…"   26 seconds ago   Exited (128) 7 seconds ago             myself

With this patch: the stop still cancels the exec, but does not cancel the
restart operation, and the container is started again:

    docker run -dit --name myself -v /var/run/docker.sock:/var/run/docker.sock docker:cli sh
    docker exec myself sh -c 'docker restart myself'
    docker ps
    CONTAINER ID   IMAGE        COMMAND                  CREATED              STATUS         PORTS     NAMES
    4393a01f7c75   docker:cli   "docker-entrypoint.s…"   About a minute ago   Up 4 seconds             myself

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit aeb8972281)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-24 16:29:20 +02:00
Cory Snider
649c9440f2 Merge pull request #46703 from thaJeztah/24.0_backport_atomic-layer-data-write
[24.0 backport] daemon: overlay2: Write layer metadata atomically
2023-10-24 10:22:09 -04:00
Sebastiaan van Stijn
9b20b1a5fe Merge pull request #46702 from thaJeztah/24.0_backport_releaseNetwork_NetworkDisabled
[24.0 backport] daemon: release sandbox even when NetworkDisabled
2023-10-24 16:10:17 +02:00
Sebastiaan van Stijn
dd37b0b960 vendor: github.com/klauspost/compress v1.17.2
fixes data corruption with zstd output in "best"

- 1.17.2 diff: https://github.com/klauspost/compress/compare/v1.17.1...v1.17.2
- full diff: https://github.com/klauspost/compress/compare/v1.16.5...v1.17.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit f2c67ea82f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-24 12:38:21 +02:00
Sebastiaan van Stijn
7058c0d24d vendor: github.com/klauspost/compress v1.16.5
full diff: https://github.com/klauspost/compress/compare/v1.16.3...v1.16.5

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 0354791147)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-24 12:37:02 +02:00
Mike Sul
57bd388582 daemon: overlay2: Write layer metadata atomically
When the daemon process or the host running it is abruptly terminated,
the layer metadata file can become inconsistent on the file system.
Specifically, `link` and `lower` files may exist but be empty, leading
to overlay mounting errors during layer extraction, such as:
"failed to register layer: error creating overlay mount to <path>:
too many levels of symbolic links."

This commit introduces the use of `AtomicWriteFile` to ensure that the
layer metadata files contain correct data when they exist on the file system.

Signed-off-by: Mike <mike.sul@foundries.io>
(cherry picked from commit de2447c2ab)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-23 20:15:21 +02:00
payall4u
05d95fd503 daemon: release sandbox even when NetworkDisabled
When the default bridge is disabled by setting dockerd's `--bridge=none`
option, the daemon still creates a sandbox for containers with no
network attachment specified. In that case `NetworkDisabled` will be set
to true.

However, currently the `releaseNetwork` call will early return if
NetworkDisabled is true. Thus, these sandboxes won't be deleted until
the daemon is restarted. If a high number of such containers are
created, the daemon would then take few minutes to start.

See https://github.com/moby/moby/issues/42461.

Signed-off-by: payall4u <payall4u@qq.com>
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
(cherry picked from commit 9664f33e0d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-23 20:07:39 +02:00
Sebastiaan van Stijn
c2e7c32b34 Merge pull request #46686 from thaJeztah/24.0_backport_c8d_push_defer_noncancellable_context
[24.0 backport] daemon/c8d: Use non cancellable context in defers
2023-10-23 11:28:04 +02:00
Paweł Gronowski
2783345d3a daemon/c8d: Use non cancellable context in defers
Fixes leases not being released when operation was cancelled.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 6f27bef9fc)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-20 16:55:47 +02:00
Sebastiaan van Stijn
a9e20aeaed daemon/containerd: rename some vars that collided with imports
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit e10eca3d1a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-20 16:51:13 +02:00
Sebastiaan van Stijn
a8d0a58b24 daemon/containerd: newROLayerForImage: remove unused args
Also rename variables that collided with imports.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit aefbd49038)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-20 16:49:23 +02:00
Sebastiaan van Stijn
c981f8aff7 daemon/containerd: log errors when releasing leases
Log a warning if we encounter an error when releasing leases. While it
may not have direct consequences, failing to release the lease should be
unexpected, so let's make them visible.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 28d201feb7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-20 16:48:21 +02:00
Paweł Gronowski
73814c48df internal: Add compatcontext.WithoutCancel
Copy the implementation of `context.WithoutCancel` introduced in Go 1.21
to be able to use it when building with older versions.
This will use the stdlib directly when building with Go 1.21+.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit f6e44bc0e8)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-20 16:43:03 +02:00
Akihiro Suda
7986f70a47 Merge pull request #46671 from thaJeztah/24.0_backport_update_x_net
[24.0 backport] vendor: golang.org/x/net v0.17.0
2023-10-20 11:34:55 +09:00
Sebastiaan van Stijn
88eb323a7f Merge pull request #46676 from moby/backport/46667/24.0
[24.0 backport] Add IP_NF_MANGLE to check-config.sh
2023-10-19 15:19:04 +02:00
Stephan Henningsen
535b70e90c Update check-config.sh
Add IP_NF_MANGLE to "Generally Required" kernel features, since it appears to be necessary for Docker Swarm to work.

Closes https://github.com/moby/moby/issues/46636

Signed-off-by: Stephan Henningsen <stephan-henningsen@users.noreply.github.com>
(cherry picked from commit cf9073397c)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-10-18 15:59:11 -06:00
Sebastiaan van Stijn
dde5995051 vendor: golang.org/x/net v0.17.0
full diff: https://github.com/golang/net/compare/v0.13.0...v0.17.0

This fixes the same CVE as go1.21.3 and go1.20.10;

- net/http: rapid stream resets can cause excessive work

  A malicious HTTP/2 client which rapidly creates requests and
  immediately resets them can cause excessive server resource consumption.
  While the total number of requests is bounded to the
  http2.Server.MaxConcurrentStreams setting, resetting an in-progress
  request allows the attacker to create a new request while the existing
  one is still executing.

  HTTP/2 servers now bound the number of simultaneously executing
  handler goroutines to the stream concurrency limit. New requests
  arriving when at the limit (which can only happen after the client
  has reset an existing, in-flight request) will be queued until a
  handler exits. If the request queue grows too large, the server
  will terminate the connection.

  This issue is also fixed in golang.org/x/net/http2 v0.17.0,
  for users manually configuring HTTP/2.

  The default stream concurrency limit is 250 streams (requests)
  per HTTP/2 connection. This value may be adjusted using the
  golang.org/x/net/http2 package; see the Server.MaxConcurrentStreams
  setting and the ConfigureServer function.

  This is CVE-2023-39325 and Go issue https://go.dev/issue/63417.
  This is also tracked by CVE-2023-44487.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 1800dd0876)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-18 15:41:39 +02:00
Sebastiaan van Stijn
8864727bae vendor: golang.org/x/crypto v0.14.0
full diff: https://github.com/golang/crypto/compare/v0.11.0...v0.14.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 1946aead21)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-18 15:40:15 +02:00
Sebastiaan van Stijn
81d73e17f7 vendor: golang.org/x/text v0.13.0
full diff: https://github.com/golang/text/compare/v0.11.0...v0.13.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 0679ae984b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-18 15:38:53 +02:00
Sebastiaan van Stijn
d8c62df0b6 vendor: golang.org/x/sys v0.13.0
full diff: https://github.com/golang/sys/compare/v0.10.0...v0.13.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit bc33c27796)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-18 15:37:31 +02:00
Sebastiaan van Stijn
d7a1fcef8f vendor: golang.org/x/net v0.13.0, golang.org/x/crypto v0.11.0
full diff: https://github.com/golang/net/compare/v0.10.0...v0.13.0
full diff: https://github.com/golang/crypto/compare/v0.9.0...v0.11.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 2edb858b18)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-18 15:33:42 +02:00
Sebastiaan van Stijn
a22da0d5c4 vendor: golang.org/x/text v0.11.0
full diff: https://github.com/golang/text/compare/v0.9.0...v0.11.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 87de23a6cd)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-18 15:33:32 +02:00
Sebastiaan van Stijn
85234039a6 vendor: golang.org/x/crypto v0.9.0
full diff: https://github.com/golang/crypto/compare/v0.3.0...v0.9.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 9670db3904)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-18 15:33:18 +02:00
Sebastiaan van Stijn
9702281ba0 vendor: golang.org/x/sys v0.10.0
full diff: https://github.com/golang/sys/compare/v0.8.0...v0.10.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a046616249)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-18 15:33:10 +02:00
Sebastiaan van Stijn
01860dc813 vendor: golang.org/x/crypto v0.3.0
full diff: https://github.com/golang/crypto/compare/v0.2.0...v0.3.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 7b66ae1531)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-18 15:32:56 +02:00
Bjorn Neergaard
fad4b16c01 Merge pull request #46659 from thaJeztah/24.0_backport_replace_dockerignore
[24.0 backport] replace dockerfile/dockerignore with patternmatcher/ignorefile
2023-10-16 18:19:36 -07:00
Sebastiaan van Stijn
daf599ea0a replace dockerfile/dockerignore with patternmatcher/ignorefile
The BuildKit dockerignore package was integrated in the patternmatcher
repository / module. This patch updates our uses of the BuildKit package
with its new location.

A small local change was made to keep the format of the existing error message,
because the "ignorefile" package is slightly more agnostic in that respect
and doesn't include ".dockerignore" in the error message.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 3553b4c684)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-16 22:17:23 +02:00
Sebastiaan van Stijn
1dffa3a814 vendor: github.com/moby/patternmatcher v0.6.0
- integrate frontend/dockerfile/dockerignore from buildkit

full diff: https://github.com/moby/patternmatcher/compare/v0.5.0...v0.6.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a479b287c7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-16 22:17:15 +02:00
Sebastiaan van Stijn
f9b8a35ac4 Merge pull request #46626 from AkihiroSuda/cherrypick-46564-24
[24.0 backport] Limit OOMScoreAdj when running in UserNS ("Rootful-in-Rootless")
2023-10-12 08:50:46 +02:00
Cory Snider
a27bf4611e Merge pull request #46619 from xinfengliu/24.0_backport_improve_stats_collector
[24.0 backport] Make one-shot stats faster
2023-10-11 20:49:49 -04:00
Brian Goff
122b11a1fe Merge pull request #46624 from thaJeztah/24.0_update_go1.20.10
[24.0] update to go1.20.10
2023-10-11 16:28:43 -07:00
Akihiro Suda
58c1c7b8dc Limit OOMScoreAdj when running in UserNS ("Rootful-in-Rootless")
Fix issue 46563 "Rootful-in-Rootless dind doesn't work since systemd v250 (due to oom score adj)"

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
(cherry picked from commit ad877271f3)
> Conflicts:
>	daemon/oci_linux.go
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2023-10-12 07:29:15 +09:00
Sebastiaan van Stijn
f87492689e update to go1.20.10
go1.20.10 (released 2023-10-10) includes a security fix to the net/http package.
See the Go 1.20.10 milestone on our issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.20.10+label%3ACherryPickApproved

full diff: https://github.com/golang/go/compare/go1.20.9...go1.20.10

From the security mailing:

[security] Go 1.21.3 and Go 1.20.10 are released

Hello gophers,

We have just released Go versions 1.21.3 and 1.20.10, minor point releases.

These minor releases include 1 security fixes following the security policy:

- net/http: rapid stream resets can cause excessive work

  A malicious HTTP/2 client which rapidly creates requests and
  immediately resets them can cause excessive server resource consumption.
  While the total number of requests is bounded to the
  http2.Server.MaxConcurrentStreams setting, resetting an in-progress
  request allows the attacker to create a new request while the existing
  one is still executing.

  HTTP/2 servers now bound the number of simultaneously executing
  handler goroutines to the stream concurrency limit. New requests
  arriving when at the limit (which can only happen after the client
  has reset an existing, in-flight request) will be queued until a
  handler exits. If the request queue grows too large, the server
  will terminate the connection.

  This issue is also fixed in golang.org/x/net/http2 v0.17.0,
  for users manually configuring HTTP/2.

  The default stream concurrency limit is 250 streams (requests)
  per HTTP/2 connection. This value may be adjusted using the
  golang.org/x/net/http2 package; see the Server.MaxConcurrentStreams
  setting and the ConfigureServer function.

  This is CVE-2023-39325 and Go issue https://go.dev/issue/63417.
  This is also tracked by CVE-2023-44487.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-11 19:58:09 +02:00
Sebastiaan van Stijn
3715eaf078 update to go1.20.9
go1.20.9 (released 2023-10-05) includes one security fixes to the cmd/go package,
as well as bug fixes to the go command and the linker. See the Go 1.20.9
milestone on our issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.20.9+label%3ACherryPickApproved

full diff: https://github.com/golang/go/compare/go1.20.8...go1.20.9

From the security mailing:

[security] Go 1.21.2 and Go 1.20.9 are released

Hello gophers,

We have just released Go versions 1.21.2 and 1.20.9, minor point releases.

These minor releases include 1 security fixes following the security policy:

- cmd/go: line directives allows arbitrary execution during build

  "//line" directives can be used to bypass the restrictions on "//go:cgo_"
  directives, allowing blocked linker and compiler flags to be passed during
  compliation. This can result in unexpected execution of arbitrary code when
  running "go build". The line directive requires the absolute path of the file in
  which the directive lives, which makes exploting this issue significantly more
  complex.

  This is CVE-2023-39323 and Go issue https://go.dev/issue/63211.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-11 19:57:53 +02:00
Sebastiaan van Stijn
3b09657d72 Merge pull request #46586 from cpuguy83/24.0_fix_etwlogs
[24.0] Revert "daemon/logger/etwlogs: rewrite to use go-winio/pkg/etw"
2023-10-11 17:08:47 +02:00
Brian Goff
31f49bd685 Make one-shot stats faster
(cherry picked from commit f6fa56194f)
Signed-off-by: Xinfeng Liu <XinfengLiu@icloud.com>
2023-10-11 20:24:34 +08:00
Brian Goff
37796c7029 Revert "daemon/logger/etwlogs: rewrite to use go-winio/pkg/etw"
This reverts commit a9fa147a92.

This is a broken commit as its creating a provider but never setting
providerHandle which is what is used to write events.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2023-10-03 22:44:30 +00:00
Akihiro Suda
fa2f6f98be Merge pull request #46559 from thaJeztah/24.0_backport_no_min_max
[24.0 backport] rename uses of "max", "min", which are now builtins in go1.21
2023-09-29 03:45:24 +09:00
Sebastiaan van Stijn
51dc5fb58f integration/internal/swarm: rename max/min as it collides with go1.21 builtin
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit fa13b0715f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-28 14:20:46 +02:00
Sebastiaan van Stijn
4e11c149d1 pkg/tailfile: rename max/min as it collides with go1.21 builtin
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 79495c5b6a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-28 14:20:39 +02:00
Sebastiaan van Stijn
0b97ecddb0 pkg/plugins: rename max/min as it collides with go1.21 builtin
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit df2f25a977)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-28 14:20:31 +02:00
Sebastiaan van Stijn
710c748801 pkg/sysinfo: rename max/min as it collides with go1.21 builtin
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 6c036f267f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-28 14:20:23 +02:00
Sebastiaan van Stijn
b340a777c0 pkg/archive: rename max/min as it collides with go1.21 builtin
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 55192de9e3)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-28 14:20:16 +02:00
Sebastiaan van Stijn
e996dffe56 daemon: rename max/min as it collides with go1.21 builtin
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a3867992b7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-28 14:20:08 +02:00
Sebastiaan van Stijn
334719141c api/types/versions: rename max/min as it collides with go1.21 builtin
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 318b3d4fe5)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-28 14:19:59 +02:00
Sebastiaan van Stijn
0702941de6 restartmanager: rename max/min as it collides with go1.21 builtin
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit cb394a62e5)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-28 14:19:51 +02:00
Paweł Gronowski
f0808d3673 Merge pull request #46540 from thaJeztah/24.0_backport_gofumpt_cluster
[24.0 backport] daemon/cluster: format code with gofumpt
2023-09-26 14:46:39 +02:00
Sebastiaan van Stijn
bed0c789dd daemon/cluster: format code with gofumpt
Formatting the code with https://github.com/mvdan/gofumpt

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 2d12dc3a58)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-26 09:59:54 +02:00
Sebastiaan van Stijn
20c688f84d Merge pull request #46505 from vvoland/libcontainerd-windows-reap-fix-24
[24.0 backport] libcontainerd/windows: Fix cleanup on `newIOFromProcess` error
2023-09-19 21:52:22 +02:00
Bjorn Neergaard
19039eae0b profiles/apparmor: deny /sys/devices/virtual/powercap
While this is not strictly necessary as the default OCI config masks this
path, it is possible that the user disabled path masking, passed their
own list, or is using a forked (or future) daemon version that has a
modified default config/allows changing the default config.

Add some defense-in-depth by also masking out this problematic hardware
device with the AppArmor LSM.

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit bddd826d7a)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-09-18 16:43:36 -06:00
Bjorn Neergaard
164a1a0f14 oci/defaults: deny /sys/devices/virtual/powercap
The ability to read these files may offer a power-based sidechannel
attack against any workloads running on the same kernel.

This was originally [CVE-2020-8694][1], which was fixed in
[949dd0104c496fa7c14991a23c03c62e44637e71][2] by restricting read access
to root. However, since many containers run as root, this is not
sufficient for our use case.

While untrusted code should ideally never be run, we can add some
defense in depth here by masking out the device class by default.

[Other mechanisms][3] to access this hardware exist, but they should not
be accessible to a container due to other safeguards in the
kernel/container stack (e.g. capabilities, perf paranoia).

[1]: https://nvd.nist.gov/vuln/detail/CVE-2020-8694
[2]: 949dd0104c
[3]: https://web.eece.maine.edu/~vweaver/projects/rapl/

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 83cac3c3e3)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-09-18 16:43:34 -06:00
Paweł Gronowski
30fe6540a5 libcontainerd/windows: Don't reap on failure
Synchronize the code to do the same thing as Exec.
reap doesn't need to be called before the start event was sent.
There's already a defer block which cleans up the process in case where
an error occurs.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 0937aef261)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-09-18 12:28:03 +02:00
Paweł Gronowski
1320e79bd8 libcontainer/windows: Remove unneeded var declaration
The cleanup defer uses an `outErr` now, so we don't need to worry about
shadowing.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit b805599ef6)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-09-18 12:28:01 +02:00
Paweł Gronowski
a1ba69a82b libcontainer/windows: Fix process not being killed after stdio attach failure
Error check in defer block used wrong error variable which is always nil
if the flow reaches the defer. This caused the `newProcess.Kill` to be
never called if the subsequent attemp to attach to the stdio failed.
Although this only happens in Exec (as Start does overwrite the error),
this also adjusts the Start to also use the returned error to avoid this
kind of mistake in future changes.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 55b664046c)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-09-18 12:27:57 +02:00
Sebastiaan van Stijn
00108c57b5 Merge pull request #46487 from thaJeztah/24.0_backport_update_containerd_binary_1.7.6
[24.0 backport] update containerd binary to v1.7.6
2023-09-16 13:38:47 +02:00
Sebastiaan van Stijn
1f3ea9841e update containerd binary to v1.7.6
Update the version used in testing;

full diff: https://github.com/containerd/containerd/compare/v1.7.3...v1.7.6

v1.7.6 release notes:

full diff: https://github.com/containerd/containerd/compare/v1.7.5...v1.7.6

The sixth patch release for containerd 1.7 contains various fixes and updates.

- Fix log package for clients overwriting the global logger
- Fix blockfile snapshotter copy on Darwin
- Add support for Linux usernames on non-Linux platforms
- Update Windows platform matcher to invoke stable ABI compability function
- Update Golang to 1.20.8
- Update push to inherit distribution sources from parent

v1.7.5 release notes:

full diff: https://github.com/containerd/containerd/compare/v1.7.4...v1.7.5

The fifth patch release for containerd 1.7 fixes a versioning issue from
the previous release and includes some internal logging API changes.

v1.7.4 release notes:

full diff: https://github.com/containerd/containerd/compare/v1.7.3...v1.7.4

The fourth patch release for containerd 1.7 contains remote differ plugin support,
a new block file based snapshotter, and various fixes and updates.

Notable Updates

- Add blockfile snapshotter
- Add remote/proxy differ
- Update runc binary to v1.1.9
- Cri: Don't use rel path for image volumes
- Allow attaching to any combination of stdin/out/err
- Fix ro mount option being passed
- Fix leaked shim caused by high IO pressure
- Add configurable mount options to overlay snapshotter

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 24102aa8ca)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-15 12:22:39 +02:00
Sebastiaan van Stijn
74e3528a5a Merge pull request #46482 from akerouanton/cp-24.0-3e8af081
[24.0 backport] ipam: Replace ChildSubnet with parent Subnet when its mask is bigger
2023-09-14 19:30:43 +02:00
Albin Kerouanton
58224457c3 ipam: Replace ChildSubnet with parent Subnet when its mask is bigger
Prior to moby/moby#44968, libnetwork would happily accept a ChildSubnet
with a bigger mask than its parent subnet. In such case, it was
producing IP addresses based on the parent subnet, and the child subnet
was not allocated from the address pool.

This commit automatically fixes invalid ChildSubnet for networks stored
in libnetwork's datastore.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
(cherry picked from commit 3e8af0817a)
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2023-09-14 17:50:01 +02:00
Sebastiaan van Stijn
b81261f5c0 Merge pull request #46478 from akerouanton/cp-24.0-mac-address
[backport 24.0] daemon: fix under what conditions container's mac-address is applied
2023-09-14 13:51:44 +02:00
Albin Kerouanton
df983b7990 daemon: fix under what conditions container's mac-address is applied
The daemon would pass an EndpointCreateOption to set the interface MAC
address if the network name and the provided network mode were matching.
Obviously, if the network mode is a network ID, it won't work. To make
things worse, the network mode is never normalized if it's a partial ID.

To fix that: 1. the condition under what the container's mac-address is
applied is updated to also match the full ID; 2. the network mode is
normalized to a full ID when it's only a partial one.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
(cherry picked from commit 6cc6682f5f)
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2023-09-14 11:48:16 +02:00
Sebastiaan van Stijn
92563c9688 Merge pull request #46459 from thaJeztah/24.0_backport_update_golang_1.20.8
[24.0 backport] update to go1.20.8
2023-09-12 14:38:05 +02:00
Sebastiaan van Stijn
f014c349a0 update to go1.20.8
go1.20.8 (released 2023-09-06) includes two security fixes to the html/template
package, as well as bug fixes to the compiler, the go command, the runtime,
and the crypto/tls, go/types, net/http, and path/filepath packages. See the
Go 1.20.8 milestone on our issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.20.8+label%3ACherryPickApproved

full diff: https://github.com/golang/go/compare/go1.20.7...go1.20.8

From the security mailing:

[security] Go 1.21.1 and Go 1.20.8 are released

Hello gophers,

We have just released Go versions 1.21.1 and 1.20.8, minor point releases.

These minor releases include 4 security fixes following the security policy:

- cmd/go: go.mod toolchain directive allows arbitrary execution
  The go.mod toolchain directive, introduced in Go 1.21, could be leveraged to
  execute scripts and binaries relative to the root of the module when the "go"
  command was executed within the module. This applies to modules downloaded using
  the "go" command from the module proxy, as well as modules downloaded directly
  using VCS software.

  Thanks to Juho Nurminen of Mattermost for reporting this issue.

  This is CVE-2023-39320 and Go issue https://go.dev/issue/62198.

- html/template: improper handling of HTML-like comments within script contexts
  The html/template package did not properly handle HMTL-like "<!--" and "-->"
  comment tokens, nor hashbang "#!" comment tokens, in <script> contexts. This may
  cause the template parser to improperly interpret the contents of <script>
  contexts, causing actions to be improperly escaped. This could be leveraged to
  perform an XSS attack.

  Thanks to Takeshi Kaneko (GMO Cybersecurity by Ierae, Inc.) for reporting this
  issue.

  This is CVE-2023-39318 and Go issue https://go.dev/issue/62196.

- html/template: improper handling of special tags within script contexts
  The html/template package did not apply the proper rules for handling occurrences
  of "<script", "<!--", and "</script" within JS literals in <script> contexts.
  This may cause the template parser to improperly consider script contexts to be
  terminated early, causing actions to be improperly escaped. This could be
  leveraged to perform an XSS attack.

  Thanks to Takeshi Kaneko (GMO Cybersecurity by Ierae, Inc.) for reporting this
  issue.

  This is CVE-2023-39319 and Go issue https://go.dev/issue/62197.

- crypto/tls: panic when processing post-handshake message on QUIC connections
  Processing an incomplete post-handshake message for a QUIC connection caused a panic.

  Thanks to Marten Seemann for reporting this issue.

  This is CVE-2023-39321 and CVE-2023-39322 and Go issue https://go.dev/issue/62266.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c41121cc48)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-12 11:22:15 +02:00
Sebastiaan van Stijn
eb2607b9f6 Merge pull request #46441 from cpuguy83/24.0_update_builkit
[24.0]: Update buildkit to fix source policy order
2023-09-08 20:35:53 +02:00
Brian Goff
e2ab5f72eb 24.0: Update buildkit to fix source policy order
This brings in moby/buildkit#4215 which fixes a major issue with source
policies in buildkit.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2023-09-08 16:53:06 +00:00
Sebastiaan van Stijn
ab7ac16a64 Merge pull request #46407 from ameyag/24.0-uname-backlash
[24.0 backport] Fixing dockerd-rootless-setuptools.sh when user name contains a backslash
2023-09-06 08:34:35 +02:00
Jean-Michel Rouet
8216da20af more robust dockerd-rootless-setuptools.sh
Fixing case where username may contain a backslash.
This case can happen for winbind/samba active directory domain users.

Signed-off-by: Jean-Michel Rouet <jean-michel.rouet@philips.com>

Use more meaningful variable name

Signed-off-by: Jean-Michel Rouet <jean-michel.rouet@philips.com>

Update contrib/dockerd-rootless-setuptool.sh

Co-authored-by: Akihiro Suda <suda.kyoto@gmail.com>
Signed-off-by: Jean-Michel Rouet <jean-michel.rouet@philips.com>

Use more meaningful variable name

Signed-off-by: Jean-Michel Rouet <jean-michel.rouet@philips.com>

Update contrib/dockerd-rootless-setuptool.sh

Co-authored-by: Akihiro Suda <suda.kyoto@gmail.com>
Signed-off-by: Jean-Michel Rouet <jean-michel.rouet@philips.com>
(cherry picked from commit 2f0ba0a7e5)
Signed-off-by: Ameya Gawde <agawde@mirantis.com>
2023-09-05 12:10:53 -07:00
Sebastiaan van Stijn
1a7969545d Merge pull request #46366 from thaJeztah/24.0_backport_volume-local-restore-mounted-status
[24.0 backport] volume/local: Don't unmount, restore mounted status
2023-08-29 21:14:17 +02:00
Paweł Gronowski
c35376c455 volume/local: Don't unmount, restore mounted status
On startup all local volumes were unmounted as a cleanup mechanism for
the non-clean exit of the last engine process.

This caused live-restored volumes that used special volume opt mount
flags to be broken. While the refcount was restored, the _data directory
was just unmounted, so all new containers mounting this volume would
just have the access to the empty _data directory instead of the real
volume.

With this patch, the mountpoint isn't unmounted. Instead, if the volume
is already mounted, just mark it as mounted, so the next time Mount is
called only the ref count is incremented, but no second attempt to mount
it is performed.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 2689484402)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-29 19:59:05 +02:00
Paweł Gronowski
5d4cc0b5b5 integration/liveRestore: Check volume content
Make sure that the content in the live-restored volume mounted in a new
container is the same as the content in the old container.
This checks if volume's _data directory doesn't get unmounted on
startup.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit aef703fa1b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-29 19:58:57 +02:00
Sebastiaan van Stijn
c78abd96ce Merge pull request #46330 from thaJeztah/24.0_backport_api_docs_update_urls
[24.0 backport] docs: update links to Go documentation
2023-08-25 17:44:23 +02:00
Sebastiaan van Stijn
6282d95b9e Merge pull request #46331 from thaJeztah/24.0_backport_update_golangci_lint
[24.0 backport] update golangci-lint to v1.54.2
2023-08-25 17:27:59 +02:00
Sebastiaan van Stijn
1d983e2e8a update golangci-lint to v1.54.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit cd49f9affd)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 16:24:36 +02:00
Sebastiaan van Stijn
d2e9a19358 CONTRIBUTING.md: update links to golang docs and blog
- docs moved to https://go.dev/doc/
- blog moved to https://go.dev/blog/

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit b18e170631)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 16:22:35 +02:00
Sebastiaan van Stijn
73f6053bb3 api: swagger: update link to Go documentation
Go documentation moved to the `go.dev` domain;

    curl -sI https://golang.org/doc/install/source#environment | grep 'location'
    location: https://go.dev/doc/install/source

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 136e86bb5c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 16:22:35 +02:00
Sebastiaan van Stijn
de13951b9d docs/api: update links to Go documentation
Go documentation moved to the `go.dev` domain;

    curl -sI https://golang.org/doc/install/source#environment | grep 'location'
    location: https://go.dev/doc/install/source

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 4862d39144)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 16:22:32 +02:00
Sebastiaan van Stijn
7741a89966 Merge pull request #46325 from thaJeztah/24.0_backport_hack_less_redirects
[24.0 backport] Dockerfile: Windows: update Golang download domains to cut down redirects
2023-08-25 14:48:40 +02:00
Sebastiaan van Stijn
377af4c9b4 Dockerfile: Windows: update Golang download domains to cut down redirects
The `golang.org` domain moved to `go.dev`, and the download-URLs we were
using resulted in 2 redirects;

    curl -sI https://golang.org/dl/go1.20.windows-amd64.zip | grep 'location'
    location: https://go.dev/dl/go1.20.windows-amd64.zip

    curl -sI https://go.dev/dl/go1.20.windows-amd64.zip | grep 'location'
    location: https://dl.google.com/go/go1.20.windows-amd64.zip

    curl -sI https://dl.google.com/go/go1.20.windows-amd64.zip
    HTTP/2 200
    # ...

This patch cuts it down to one redirects. I decided not to use the "final"
(`dl.google.com`) URL, because that URL is not documented in the Golang docs,
and visiting the domain itself (https://dl.google.com/) redirects to a marketing
page for "Google Chrome".

Trying the `/go/` path (https://dl.google.com/go/) also does not show a landing
page that lists downloads, so I'm considering those URLs to be "unstable".

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit f6a5318f94)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 13:32:24 +02:00
Sebastiaan van Stijn
088cec8f0f hack: update link to GOPATH documentation
This documentation moved to a different page, and the Go documentation
moved to the https://go.dev/ domain.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 2aabd64477)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-25 13:32:10 +02:00
Sebastiaan van Stijn
8ff9ef2a7a Merge pull request #46310 from vvoland/c8d-legacybuilder-fix-layermismatch-24
[24.0 backport] c8d/legacybuilder: Fix `mismatched image rootfs` errors
2023-08-24 15:03:28 +02:00
Paweł Gronowski
ed2f5d1d85 c8d/builder: Don't drop fields from created image
Previous image created a new partially filled image.
This caused child images to lose their parent's layers.

Instead of creating a new object and trying to replace its fields, just
clone the original passed image and change its ID to the manifest
digest.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 01214bafd2)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-08-24 12:47:56 +02:00
Djordje Lukic
aade22d31e Merge pull request #46302 from thaJeztah/24.0_backport_c8d-legacybuilder-fix-from-scratch
[24.0 backport] c8d: Fix building Dockerfiles that have `FROM scratch`
2023-08-23 20:58:41 +02:00
Paweł Gronowski
1d10e8633d daemon: Handle NotFound when deleting container lease
If the lease doesn't exit (for example when creating the container
failed), just ignore the not found error.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit bedcc94de4)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-23 18:59:50 +02:00
Paweł Gronowski
63422515ba c8d/run: Allow running container without image
This allows the legacy builder to apply changes to the `FROM scratch`
layer.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit dfaff9598c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-23 18:59:43 +02:00
Paweł Gronowski
49671250f6 c8d/commit: Don't produce an empty layer
If the diff is empty and don't produce an empty layer.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit eb56493f4e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-23 18:59:27 +02:00
Sebastiaan van Stijn
e0661af25c Merge pull request #46300 from thaJeztah/24.0_backport_fix-platform-check
[24.0 backport] Don't return an error if the lease is not found
2023-08-23 17:41:14 +02:00
Djordje Lukic
b83f5a89f4 Don't return an error if the lease is not found
If the image for the wanted platform doesn't exist then the lease
doesn't exist either. Returning this error hides the real error, so
let's not return it.

Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
(cherry picked from commit b8ff8ea58e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-23 15:55:48 +02:00
Bjorn Neergaard
a7cc790265 Merge pull request #46289 from thaJeztah/24.0_backport_ci-bin-image-repo-origin
[24.0 backport] ci(bin-image): GHA and metadata improvements
2023-08-23 06:23:46 -06:00
Sebastiaan van Stijn
20130006b7 Merge pull request #46286 from thaJeztah/24.0_backport_gha_report_timeout
[24.0 backport] gha: set 10-minute timeout on "report" actions
2023-08-22 00:02:56 +02:00
Bjorn Neergaard
e6c959b172 Merge pull request #46290 from thaJeztah/24.0_backport_v1_deprecation
[24.0 backport] distribution: update warning for deprecated image formats
2023-08-21 14:12:39 -06:00
Bjorn Neergaard
4ac2355d62 hack: use long SHA for DOCKER_GITCOMMIT
This better aligns to GHA/CI settings, and is in general a better
practice in the year 2023.

We also drop the 'unsupported' fallback for `git rev-parse` in the
Makefile; we have a better fallback behavior for an empty
DOCKER_GITCOMMIT in `hack/make.sh`.

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit d125823d3f)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-08-21 14:02:56 -06:00
Bjorn Neergaard
ac2a80fcc3 ci(bin-image): clean up metadata
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 2010f4338e)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-08-21 14:02:55 -06:00
Bjorn Neergaard
5eef5a7f59 ci(bin-image): clean up env var handling
There are still messy special cases (e.g. DOCKER_GITCOMMIT vs VERSION),
but this makes things a little easier to follow, as we keep
GHA-specifics in the GHA files.

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit ad91fc1b00)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-08-21 14:02:54 -06:00
CrazyMax
aaf84dd4cf remove Dockerfile.e2e
Dockerfile.e2e is not used anymore. Integration tests run
through the main Dockerfile.

Also removes the daemon OS/Arch detection script that is not
necessary anymore. It was used to select the Dockerfile based
on the arch like Dockerfile.arm64 but we don't have those
anymore. Was also used to check referenced frozen images
in the Dockerfile.

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 5efe72415d)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-08-21 14:02:49 -06:00
Sebastiaan van Stijn
a99e62fa3d distribution: show image schema deprecation on all registries
When we added this deprecation warning, some registries had not yet
moved away from the deprecated specification, so we made the warning
conditional for pulling from Docker Hub.

That condition was added in 647dfe99a5,
which is over 4 Years ago, which should be time enough for images
and registries to have moved to current specifications.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 8c4af5dacb)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-21 21:06:29 +02:00
Sebastiaan van Stijn
e239799583 distribution: update warning for deprecated image formats
- Use the same warning for both "v1 in manifest-index" and bare "v1" images.
- Update URL to use a "/go/" redirect, which allows the docs team to more
  easily redirect the URL to relevant docs (if things move).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 982bc0e228)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-21 21:05:16 +02:00
CrazyMax
bb22b8a418 ci(bin-image): check repo origin
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 219d4d9db9)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-21 20:52:01 +02:00
Sebastiaan van Stijn
fb6784bdf0 gha: set 10-minute timeout on "report" actions
I had a CI run fail to "Upload reports":

    Exponential backoff for retry #1. Waiting for 4565 milliseconds before continuing the upload at offset 0
    Finished backoff for retry #1, continuing with upload
    Total file count: 211 ---- Processed file #160 (75.8%)
    ...
    Total file count: 211 ---- Processed file #164 (77.7%)
    Total file count: 211 ---- Processed file #164 (77.7%)
    Total file count: 211 ---- Processed file #164 (77.7%)
    A 503 status code has been received, will attempt to retry the upload
    ##### Begin Diagnostic HTTP information #####
    Status Code: 503
    Status Message: Service Unavailable
    Header Information: {
      "content-length": "592",
      "content-type": "application/json; charset=utf-8",
      "date": "Mon, 21 Aug 2023 14:08:10 GMT",
      "server": "Kestrel",
      "cache-control": "no-store,no-cache",
      "pragma": "no-cache",
      "strict-transport-security": "max-age=2592000",
      "x-tfs-processid": "b2fc902c-011a-48be-858d-c62e9c397cb6",
      "activityid": "49a48b53-0411-4ff3-86a7-4528e3f71ba2",
      "x-tfs-session": "49a48b53-0411-4ff3-86a7-4528e3f71ba2",
      "x-vss-e2eid": "49a48b53-0411-4ff3-86a7-4528e3f71ba2",
      "x-vss-senderdeploymentid": "63be6134-28d1-8c82-e969-91f4e88fcdec",
      "x-frame-options": "SAMEORIGIN"
    }
    ###### End Diagnostic HTTP information ######
    Retry limit has been reached for chunk at offset 0 to https://pipelinesghubeus5.actions.githubusercontent.com/Y2huPMnV2RyiTvKoReSyXTCrcRyxUdSDRZYoZr0ONBvpl5e9Nu/_apis/resources/Containers/8331549?itemPath=integration-reports%2Fubuntu-22.04-systemd%2Fbundles%2Ftest-integration%2FTestInfoRegistryMirrors%2Fd20ac12e48cea%2Fdocker.log
    Warning: Aborting upload for /tmp/reports/ubuntu-22.04-systemd/bundles/test-integration/TestInfoRegistryMirrors/d20ac12e48cea/docker.log due to failure
    Error: aborting artifact upload
    Total file count: 211 ---- Processed file #165 (78.1%)
    A 503 status code has been received, will attempt to retry the upload
    Exponential backoff for retry #1. Waiting for 5799 milliseconds before continuing the upload at offset 0

As a result, the "Download reports" continued retrying:

    ...
    Total file count: 1004 ---- Processed file #436 (43.4%)
    Total file count: 1004 ---- Processed file #436 (43.4%)
    Total file count: 1004 ---- Processed file #436 (43.4%)
    An error occurred while attempting to download a file
    Error: Request timeout: /Y2huPMnV2RyiTvKoReSyXTCrcRyxUdSDRZYoZr0ONBvpl5e9Nu/_apis/resources/Containers/8331549?itemPath=integration-reports%2Fubuntu-20.04%2Fbundles%2Ftest-integration%2FTestCreateWithDuplicateNetworkNames%2Fd47798cc212d1%2Fdocker.log
        at ClientRequest.<anonymous> (/home/runner/work/_actions/actions/download-artifact/v3/dist/index.js:3681:26)
        at Object.onceWrapper (node:events:627:28)
        at ClientRequest.emit (node:events:513:28)
        at TLSSocket.emitRequestTimeout (node:_http_client:839:9)
        at Object.onceWrapper (node:events:627:28)
        at TLSSocket.emit (node:events:525:35)
        at TLSSocket.Socket._onTimeout (node:net:550:8)
        at listOnTimeout (node:internal/timers:559:17)
        at processTimers (node:internal/timers:502:7)
    Exponential backoff for retry #1. Waiting for 5305 milliseconds before continuing the download
    Total file count: 1004 ---- Processed file #436 (43.4%)

And, it looks like GitHub doesn't allow cancelling the job, possibly
because it is defined with `if: always()`?

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit d6f340e784)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-21 20:21:13 +02:00
Paweł Gronowski
277429622f Merge pull request #46266 from vvoland/c8d-more-mount-refcount-24
[24.0 backport] c8d integration: Use refcount mounter for diff and export
2023-08-21 12:50:22 +02:00
Sebastiaan van Stijn
8d43772b09 Merge pull request #46244 from vvoland/c8d-inspect-handle-missing-config-24
[24.0 backport] c8d/inspect: Ignore manifest with missing config
2023-08-18 15:36:26 +02:00
Paweł Gronowski
74bf46aea6 c8d/diff: Reuse mount, mount parent as read-only
The container rw layer may already be mounted, so it's not safe to use
it in another overlay mount. Use the ref counted mounter (which will
reuse the existing mount if it exists) to avoid that.

Also, mount the parent mounts (layers of the base image) in a read-only
mode.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 6da42ca830)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-08-18 15:32:24 +02:00
Paweł Gronowski
b76a0c7d00 c8d/export: Use ref counted mounter
To prevent mounting the container rootfs in a rw mode if it's already
mounted.  This can't use `mount.WithReadonlyTempMount` because the
archive code does a chroot with a pivot_root, which creates a new
directory in the rootfs.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 051d51b222)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-08-18 15:32:20 +02:00
Paweł Gronowski
54953f2f5a integration: Add test for not breaking overlayfs
Check that operations that could potentially perform overlayfs mounts
that could cause undefined behaviors.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 303e2b124e)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-08-18 15:32:04 +02:00
Paweł Gronowski
e4ecfef405 Merge pull request #46263 from vvoland/volume-decrement-refcount-typo-24
[24.0 backport] volume/local: Fix debug log typo
2023-08-18 14:58:18 +02:00
Paweł Gronowski
3897724f4a volume/local: Fix debug log typo
Active count is incremented, but message claimed the opposite.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 7f965d55c7)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-08-18 13:12:57 +02:00
Sebastiaan van Stijn
821e6d8b42 Merge pull request #46260 from vvoland/ci-mobybin-sha-24
[24.0 backport] Fix DOCKER_GITCOMMIT in moby-bin
2023-08-18 12:52:11 +02:00
Bjorn Neergaard
0c131f58ba ci(bin-image): populate DOCKER_GITCOMMIT, take 2
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 73ffb48bfb)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-08-18 09:45:37 +02:00
Bjorn Neergaard
448ae33f87 ci(bin-image): populate DOCKER_GITCOMMIT
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 9aed6308d4)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-08-18 09:45:16 +02:00
Paweł Gronowski
3ce0dc7e35 bakefile: Remove default value of DOCKER_GITCOMMIT
"HEAD" will still be used as a version if no DOCKER_COMMIT is provided
(for example when not running via `make`), but it won't prevent it being
set to the GITHUB_SHA variable when it's present.

This should fix `Git commit` reported by `docker version` for the
binaries generated by `moby-bin`.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit d7a9f15775)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-08-18 09:45:09 +02:00
Paweł Gronowski
600aa7b7a5 c8d/inspect: Ignore manifest with missing config
Fix a failure to inspect image if any of its present manifest references
an image config which isn't present locally.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit a64adda4e7)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-08-17 09:49:20 +02:00
Bjorn Neergaard
f1cc5760d9 Merge pull request #46214 from thaJeztah/24.0_backport_allow-all-ipv6-icc
[24.0 backport] libnet/d/bridge: Allow IPv6 ICC from any IP address
2023-08-15 16:07:36 -06:00
Bjorn Neergaard
215c6e7aec Merge pull request #46215 from thaJeztah/24.0_backport_windows_fix_service_register
[24.0 backport] windows: fix --register-service when executed from within binary directory
2023-08-15 16:06:58 -06:00
Bjorn Neergaard
635524ea26 Merge pull request #46218 from thaJeztah/24.0_backport_bump_containerd_1.6.22
[24.0 backport] vendor: github.com/containerd/containerd v1.6.22
2023-08-15 16:06:38 -06:00
Bjorn Neergaard
6f8cf86c30 Merge pull request #46219 from thaJeztah/24.0_backport_with-go-mod_ROOTDIR
[24.0 backport] hack: use Git-free ROOTDIR
2023-08-15 16:06:24 -06:00
Bjorn Neergaard
ad7a03eb33 Merge pull request #46221 from thaJeztah/24.0_backport_capabilites
[24.0 backport] Do not drop effective&permitted set
2023-08-15 16:05:39 -06:00
Bjorn Neergaard
ff50c6e166 Merge pull request #46228 from thaJeztah/24.0_backport_runc_binary_1.1.9
[24.0 backport] update runc binary to v1.1.9
2023-08-15 16:05:06 -06:00
Sebastiaan van Stijn
bb06416756 Merge pull request #46231 from thaJeztah/24.0_backport_remove-ibm-jenkins-jobs
[24.0 backport] remove s390x and ppc64ls pipelines
2023-08-15 20:29:23 +02:00
Sam Thibault
5d2c383d72 remove s390x and ppc64ls pipelines
Signed-off-by: Sam Thibault <sam.thibault@docker.com>
(cherry picked from commit 59aa3dce8a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-14 18:46:28 +02:00
Akihiro Suda
15bd07b4fd update runc binary to v1.1.9
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
(cherry picked from commit b039bbc678)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-14 17:34:23 +02:00
Luboslav Pivarc
cc39fb9f6b Integration test for capabilities
Verify non-root containers are able to use file
capabilities.

Signed-off-by: Luboslav Pivarc <lpivarc@redhat.com>
Co-authored-by: Cory Snider <csnider@mirantis.com>
Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 42fa7a1951)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-13 22:28:00 +02:00
Luboslav Pivarc
bf2b8a05a0 Do not drop effective&permitted set
Currently moby drops ep sets before the entrypoint is executed.
This does mean that with combination of no-new-privileges the
file capabilities stops working with non-root containers.
This is undesired as the usability of such containers is harmed
comparing to running root containers.

This commit therefore sets the effective/permitted set in order
to allow use of file capabilities or libcap(3)/prctl(2) respectively
with combination of no-new-privileges and without respectively.

For no-new-privileges the container will be able to obtain capabilities
that are requested.

Signed-off-by: Luboslav Pivarc <lpivarc@redhat.com>
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 3aef732e61)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-13 22:26:45 +02:00
Bjorn Neergaard
e67f9dadc6 hack/make/.binary: use with-go-mod.sh
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit a972dbd682)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-13 22:21:31 +02:00
Kevin Alvarez
314b84b023 hack: enable Go modules when building dockerd and docker-proxy
This is a workaround to have buildinfo with deps embedded in the
binary. We need to create a go.mod file before building with
-modfile=vendor.mod, otherwise it fails with:
"-modfile cannot be used to set the module root directory."

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 7665feeb52)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-13 22:21:31 +02:00
Bjorn Neergaard
72947f5022 hack: use Git-free ROOTDIR convention
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 5563b09ac2)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-13 22:21:31 +02:00
Sebastiaan van Stijn
7e7bc0f1bc vendor: github.com/containerd/containerd v1.6.22
- full diff: https://github.com/containerd/containerd/compare/v1.6.21...v1.6.22
- release notes: https://github.com/containerd/containerd/releases/tag/v1.6.22

---

Notable Updates

- RunC: Update runc binary to v1.1.8
- CRI: Fix `additionalGids`: it should fallback to `imageConfig.User`
  when `securityContext.RunAsUser`, `RunAsUsername` are empty
- CRI: Write generated CNI config atomically
- Fix concurrent writes for `UpdateContainerStats`
- Make `checkContainerTimestamps` less strict on Windows
- Port-Forward: Correctly handle known errors
- Resolve `docker.NewResolver` race condition
- SecComp: Always allow `name_to_handle_at`
- Adding support to run hcsshim from local clone
- Pinned image support
- Runtime/V2/RunC: Handle early exits w/o big locks
- CRITool: Move up to CRI-TOOLS v1.27.0
- Fix cpu architecture detection issue on emulated ARM platform
- Task: Don't `close()` io before `cancel()`
- Fix panic when remote differ returns empty result
- Plugins: Notify readiness when registered plugins are ready
- Unwrap io errors in server connection receive error handling

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 4d674897f3)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-13 22:09:39 +02:00
Sebastiaan van Stijn
5f0df8c534 vendor github.com/containerd/ttrpc v1.1.2
full diff: https://github.com/containerd/ttrpc/compare/v1.1.1...v1.1.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-13 22:08:44 +02:00
Sebastiaan van Stijn
25b709df48 windows: fix --register-service when executed from within binary directory
Go 1.15.7 contained a security fix for CVE-2021-3115, which allowed arbitrary
code to be executed at build time when using cgo on Windows.

This issue was not limited to the go command itself, and could also affect binaries
that use `os.Command`, `os.LookPath`, etc.

From the related blogpost (https://blog.golang.org/path-security):

> Are your own programs affected?
>
> If you use exec.LookPath or exec.Command in your own programs, you only need to
> be concerned if you (or your users) run your program in a directory with untrusted
> contents. If so, then a subprocess could be started using an executable from dot
> instead of from a system directory. (Again, using an executable from dot happens
> always on Windows and only with uncommon PATH settings on Unix.)
>
> If you are concerned, then we’ve published the more restricted variant of os/exec
> as golang.org/x/sys/execabs. You can use it in your program by simply replacing

At time of the go1.15 release, the Go team considered changing the behavior of
`os.LookPath()` and `exec.LookPath()` to be a breaking change, and made the
behavior "opt-in" by providing the `golang.org/x/sys/execabs` package as a
replacement.

However, for the go1.19 release, this changed, and the default behavior of
`os.LookPath()` and `exec.LookPath()` was changed. From the release notes:
https://go.dev/doc/go1.19#os-exec-path

> Command and LookPath no longer allow results from a PATH search to be found
> relative to the current directory. This removes a common source of security
> problems but may also break existing programs that depend on using, say,
> exec.Command("prog") to run a binary named prog (or, on Windows, prog.exe)
> in the current directory. See the os/exec package documentation for information
> about how best to update such programs.
>
> On Windows, Command and LookPath now respect the NoDefaultCurrentDirectoryInExePath
> environment variable, making it possible to disable the default implicit search
> of “.” in PATH lookups on Windows systems.

A result of this change was that registering the daemon as a Windows service
no longer worked when done from within the directory of the binary itself:

    C:\> cd "Program Files\Docker\Docker\resources"
    C:\Program Files\Docker\Docker\resources> dockerd --register-service
    exec: "dockerd": cannot run executable found relative to current directory

Note that using an absolute path would work around the issue:

    C:\Program Files\Docker\Docker>resources\dockerd.exe --register-service

This patch changes `registerService()` to use `os.Executable()`, instead of
depending on `os.Args[0]` and `exec.LookPath()` for resolving the absolute
path of the binary.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 3e8fda0a70)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-13 21:58:08 +02:00
Albin Kerouanton
b7d1e98ae7 libnet/d/bridge: Allow IPv6 ICC from any IP address
IPv6 ipt rules are exactly the same as IPv4 rules, although both
protocol don't use the same networking model. This has bad consequences,
for instance: 1. the current v6 rules disallow Neighbor
Solication/Advertisement ; 2. multicast addresses can't be used ; 3.
link-local addresses are blocked too.

To solve this, this commit changes the following rules:

```
-A DOCKER-ISOLATION-STAGE-1 ! -s fdf1:a844:380c:b247::/64 -o br-21502e5b2c6c -j DROP
-A DOCKER-ISOLATION-STAGE-1 ! -d fdf1:a844:380c:b247::/64 -i br-21502e5b2c6c -j DROP
```

into:

```
-A DOCKER-ISOLATION-STAGE-1 ! -s fdf1:a844:380c:b247::/64 ! -i br-21502e5b2c6c   -o br-21502e5b2c6c -j DROP
-A DOCKER-ISOLATION-STAGE-1 ! -d fdf1:a844:380c:b247::/64   -i br-21502e5b2c6c ! -o br-21502e5b2c6c -j DROP
```

These rules only limit the traffic ingressing/egressing the bridge, but
not traffic between veth on the same bridge.

Note that, the Kernel takes care of dropping invalid IPv6 packets, eg.
loopback spoofing, thus these rules don't need to be more specific.

Solve #45460.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
(cherry picked from commit da9e44a620)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-13 21:53:40 +02:00
Sebastiaan van Stijn
c370341900 Merge pull request #46179 from vvoland/windows-unskip-kill-tests-24
[24.0 backport] integration/windows: Unskip some kill tests
2023-08-09 18:12:08 +02:00
Sebastiaan van Stijn
ea0a6f7c33 Merge pull request #46177 from vvoland/hack-integrationcli-dont-failfast-24
[24.0 backport] hack/test: Don't fail-fast before integration-cli
2023-08-09 17:39:29 +02:00
Paweł Gronowski
749e687e1b integration/windows: Unskip some kill tests
Unskip:
- TestKillWithStopSignalAndRestartPolicies
- TestKillStoppedContainer

integration tests on Windows.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit dd1c95edcd)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-08-09 14:29:06 +02:00
Paweł Gronowski
128838227e hack/test: Don't fail-fast before integration-cli
If TEST_INTEGRATION_FAIL_FAST is not set, run the integration-cli tests
even if integration tests failed.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 6841a53d17)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-08-09 14:22:09 +02:00
Sebastiaan van Stijn
8895c32ba9 Merge pull request #46134 from thaJeztah/24.0_backport_fix_daemon_integration_test
[24.0 backport] Improve test daemon logging, and fix TestDaemonProxy integration tests
2023-08-04 18:06:26 +02:00
Akihiro Suda
00e46f85f6 Merge pull request #46140 from thaJeztah/24.0_backport_update_go1.20.7
[24.0 backport] update to go1.20.7
2023-08-02 14:49:45 +09:00
Sebastiaan van Stijn
b7c5385b81 update to go1.20.7
Includes a fix for CVE-2023-29409

go1.20.7 (released 2023-08-01) includes a security fix to the crypto/tls
package, as well as bug fixes to the assembler and the compiler. See the
Go 1.20.7 milestone on our issue tracker for details:

- https://github.com/golang/go/issues?q=milestone%3AGo1.20.7+label%3ACherryPickApproved
- full diff: https://github.com/golang/go/compare/go1.20.6...go1.20.7

From the mailing list announcement:

[security] Go 1.20.7 and Go 1.19.12 are released

Hello gophers,

We have just released Go versions 1.20.7 and 1.19.12, minor point releases.

These minor releases include 1 security fixes following the security policy:

- crypto/tls: restrict RSA keys in certificates to <= 8192 bits

  Extremely large RSA keys in certificate chains can cause a client/server
  to expend significant CPU time verifying signatures. Limit this by
  restricting the size of RSA keys transmitted during handshakes to <=
  8192 bits.

  Based on a survey of publicly trusted RSA keys, there are currently only
  three certificates in circulation with keys larger than this, and all
  three appear to be test certificates that are not actively deployed. It
  is possible there are larger keys in use in private PKIs, but we target
  the web PKI, so causing breakage here in the interests of increasing the
  default safety of users of crypto/tls seems reasonable.

  Thanks to Mateusz Poliwczak for reporting this issue.

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

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit d5cb7cdeae)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-01 23:47:48 +02:00
Sebastiaan van Stijn
ba9875c2f5 Merge pull request #46120 from thaJeztah/24.0_backport_bump_gotest_tools
[24.0 backport] vendor: gotest.tools/v3 v3.5.0
2023-08-01 16:27:57 +02:00
Brian Goff
4cd50eb1ed TestDaemonProxy: use new scanners to check logs
Also fixes up some cleanup issues.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 1a51898d2e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-01 13:24:22 +02:00
Brian Goff
a49bca97df Fix daemon proxy test for "reload sanitized"
I noticed this was always being skipped because of race conditions
checking the logs.

This change adds a log scanner which will look through the logs line by
line rather than allocating a big buffer.
Additionally it adds a `poll.Check` which we can use to actually wait
for the desired log entry.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 476e788090)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-01 13:24:21 +02:00
Brian Goff
d6536d44e9 TestDaemonProxy: check proxy settings early
Allows tests to report their proxy settings for easier troubleshooting
on failures.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit 8197752d68)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-01 13:24:21 +02:00
Brian Goff
a6f8e97342 Improve test daemon logging
1. On failed start tail the daemon logs
2. Exposes generic tailing functions to make test debugging simpler

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit 914888cf8b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-01 13:23:58 +02:00
Sebastiaan van Stijn
2ef88a3cbf Merge pull request #46115 from thaJeztah/24.0_backport_fix_filter_errors
[24.0 backport] api/types/filters: fix errors not being matched by errors.Is()
2023-08-01 10:22:48 +02:00
Akihiro Suda
e426ae045b Merge pull request #46103 from thaJeztah/24.0_backport_update_containerd_binary_1.7.3
[24.0 backport] update containerd binary to v1.7.3
2023-07-30 11:05:33 +09:00
Sebastiaan van Stijn
6be708aa7d vendor: gotest.tools/v3 v3.5.0
- go.mod: update dependencies and go version by
- Use Go1.20
- Fix couple of typos
- Added `WithStdout` and `WithStderr` helpers
- Moved `cmdOperators` handling from `RunCmd` to `StartCmd`
- Deprecate `assert.ErrorType`
- Remove outdated Dockerfile
- add godoc links

full diff: https://github.com/gotestyourself/gotest.tools/compare/v3.4.0...v3.5.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit ce053a14aa)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-29 20:53:54 +02:00
Sebastiaan van Stijn
b6568d2dd5 api/types/filters: fix errors not being matched by errors.Is()
I found that the errors returned weren't matched with `errors.Is()` when
wrapped.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 490fee7d45)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-29 16:25:07 +02:00
Sebastiaan van Stijn
02241b05fc update containerd binary to v1.7.3
- full diff: https://github.com/containerd/containerd/compare/v1.7.2...v1.7.3
- release notes: https://github.com/containerd/containerd/releases/tag/v1.7.3

----

Welcome to the v1.7.3 release of containerd!

The third patch release for containerd 1.7 contains various fixes and updates.

Notable Updates

- RunC: Update runc binary to v1.1.8
- CRI: Fix `additionalGids`: it should fallback to `imageConfig.User`
  when `securityContext.RunAsUser`,`RunAsUsername` are empty
- CRI: write generated CNI config atomically
- Port-Forward: Correctly handle known errors
- Resolve docker.NewResolver race condition
- Fix `net.ipv4.ping_group_range` with userns
- Runtime/V2/RunC: handle early exits w/o big locks
- SecComp: always allow `name_to_handle_at`
- CRI: Windows Pod Stats: Add a check to skip stats for containers that
  are not running
- Task: don't `close()` io before cancel()
- Remove CNI conf_template deprecation
- Fix issue for HPC pod metrics

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit bf48d3ec29)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-28 13:24:19 +02:00
Sebastiaan van Stijn
3a6899c6fd update containerd binary to v1.7.2
- full diff: https://github.com/containerd/containerd/compare/v1.7.1...v1.7.2
- release notes: https://github.com/containerd/containerd/releases/tag/v1.7.2

----

Welcome to the v1.7.2 release of containerd!

The second patch release for containerd 1.7 includes enhancements to CRI
sandbox mode, Windows snapshot mounting support, and CRI and container IO
bug fixes.

CRI/Sandbox Updates

- Publish sandbox events
- Make stats respect sandbox's platform

Other Notable Updates

- Mount snapshots on Windows
- Notify readiness when registered plugins are ready
- Fix `cio.Cancel()` should close pipes
- CDI: Use CRI `Config.CDIDevices` field for CDI injection

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a78381c399)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-28 13:24:18 +02:00
Sebastiaan van Stijn
77e2d29b8a Merge pull request #46095 from vvoland/c8d-refreshimage-refactor-24
[24.0 backport] daemon/list: Refactor refreshImage and make `readConfig` return errdefs
2023-07-28 13:11:43 +02:00
Sebastiaan van Stijn
9e5726d3de Merge pull request #46097 from vvoland/c8d-missing-config-24
[24.0 backport] c8d/container: Follow snapshot parents for size calculation
2023-07-28 11:50:19 +02:00
Paweł Gronowski
7927cae910 c8d/container: Follow snapshot parents for size calculation
Refactor GetContainerLayerSize to calculate unpacked image size only by
following the snapshot parent tree directly instead of following it by
using diff ids from image config.

This works even if the original manifest/config used to create that
container is no longer present in the content store.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 4d8e3f54cc)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-07-28 10:30:54 +02:00
Paweł Gronowski
45ba926c6d daemon/list: Drop unused arg from containerReducer
refreshImage is the only function used as a reducer and it doesn't use
the `filter *listContext`.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 13180c1c49)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-07-28 10:21:04 +02:00
Paweł Gronowski
6c4121a943 daemon/list: Refactor refreshImage
Add context comments and make it a bit more readable.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 68991ae240)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-07-28 10:21:00 +02:00
Paweł Gronowski
fcb68e55fa daemon/list: Replace ErrImageDoesNotExist check
Check for generic `errdefs.NotFound` rather than specific error helper
struct when checking if the error is caused by the image not being
present.
It still works for `ErrImageDoesNotExist` because it
implements the NotFound errdefs interface too.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 5a39bee635)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-07-28 09:49:06 +02:00
Paweł Gronowski
3029f554cc c8d/readConfig: Translate c8d NotFound to errdefs
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 7379d18018)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-07-28 09:49:02 +02:00
Sebastiaan van Stijn
b76ffecee8 Merge pull request #46061 from vvoland/integration-no-fail-fast-24
[24.0 backport] hack/integration: Add TEST_INTEGRATION_FAIL_FAST
2023-07-24 20:54:12 +02:00
Bjorn Neergaard
96a2b214cb Merge pull request #46045 from thaJeztah/24.0_backport_bump_buildkit_0.11
[24.0 backport] vendor: github.com/moby/buildkit v0.11.7-dev
2023-07-24 09:27:46 -06:00
Paweł Gronowski
35a8b00b18 hack/integration: Add TEST_INTEGRATION_FAIL_FAST
Before this change, integration test would fail fast and not execute all
test suites when one suite fails.
Change this behavior into opt-in enabled by TEST_INTEGRATION_FAIL_FAST
variable.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 48cc28e4ef)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-07-24 17:05:44 +02:00
Sebastiaan van Stijn
fed26d5b3c vendor: github.com/moby/buildkit v0.11.7-dev
full diff: 0a15675913...616c3f613b

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 0ec73a7892)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-24 16:14:03 +02:00
Bjorn Neergaard
a61e2b4c9c Merge pull request #46044 from neersighted/init_cleanup_24.0
[24.0 backport] Upstart & sysvinit cleanup
2023-07-21 12:06:26 -06:00
Tianon Gravi
eede7f09c7 Remove Upstart scripts
Upstart has been EOL for 8 years and isn't used by any distributions we support any more.

Signed-off-by: Tianon Gravi <admwiggin@gmail.com>
(cherry picked from commit 0d8087fbbc)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-07-21 11:00:50 -06:00
Tianon Gravi
907f838603 Remove Upstart and cgroups bits from Debian sysvinit script
Upstart has been EOL for 8 years and isn't used by any distributions we support any more.

Additionally, this removes the "cgroups v1" setup code because it's more reasonable now for us to expect something _else_ to have set up cgroups appropriately (especially cgroups v2).

Signed-off-by: Tianon Gravi <admwiggin@gmail.com>
(cherry picked from commit ae737656f9)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-07-21 11:00:40 -06:00
Sebastiaan van Stijn
52c92be4c5 Merge pull request #46029 from thaJeztah/24.0_backport_bump_runc_binary_1.1.8
[24.0 backport] Dockerfile: update runc binary to v1.1.8
2023-07-19 19:18:38 +02:00
Sebastiaan van Stijn
f022632503 Dockerfile: update runc binary to v1.1.8
release notes: https://github.com/opencontainers/runc/releases/tag/v1.1.8
full diff: https://github.com/opencontainers/runc/compare/v1.1.7...v1.1.9

This is the eighth patch release of the 1.1.z release branch of runc.
The most notable change is the addition of RISC-V support, along with a
few bug fixes.

- Support riscv64.
- init: do not print environment variable value.
- libct: fix a race with systemd removal.
- tests/int: increase num retries for oom tests.
- man/runc: fixes.
- Fix tmpfs mode opts when dir already exists.
- docs/systemd: fix a broken link.
- ci/cirrus: enable some rootless tests on cs9.
- runc delete: call systemd's reset-failed.
- libct/cg/sd/v1: do not update non-frozen cgroup after frozen failed.
- CI: bump Fedora, Vagrant, bats.
- .codespellrc: update for 2.2.5.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit df86d855f5)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-19 18:22:48 +02:00
Sebastiaan van Stijn
bd41493132 Merge pull request #46023 from thaJeztah/24.0_backport_bump_buildx
[24.0 backport] Dockerfile: update buildx to v0.11.2
2023-07-19 16:58:47 +02:00
Sebastiaan van Stijn
5164e5f6d6 Merge pull request #46025 from vvoland/c8d-inspect-variant-24
[24.0 backport] c8d/inspect: Include platform Variant
2023-07-19 15:33:46 +02:00
Sebastiaan van Stijn
2b2a72cc65 Merge pull request #46021 from thaJeztah/24.0_backport_c8d-image-save-lease
[24.0 backport] c8d: Make sure the content isn't removed while we export
2023-07-19 13:06:14 +02:00
Paweł Gronowski
98a6422cbc c8d/inspect: Include platform Variant
Variant was mistakenly omitted in the returned V1Image.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 2659f7f740)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-07-19 13:06:11 +02:00
Sebastiaan van Stijn
aab94fb340 Dockerfile: update buildx to v0.11.2
Update the BUILDX_VERSION :)

release notes:

- https://github.com/docker/buildx/releases/tag/v0.11.1
- https://github.com/docker/buildx/releases/tag/v0.11.2

full diff: https://github.com/docker/buildx/compare/v0.11.0...v0.11.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit d78893921a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-19 13:04:31 +02:00
Djordje Lukic
1be48ec553 c8d: Make sure the content isn't removed while we export
This change add leases for all the content that will be exported, once
the image(s) are exported the lease is removed, thus letting
containerd's GC to do its job if needed. This fixes the case where
someone would remove an image that is still being exported.

This fixes the TestAPIImagesSaveAndLoad cli integration test.

Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
(cherry picked from commit f3a6b0fd08)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-19 11:57:49 +02:00
Sebastiaan van Stijn
d4a26c1530 Merge pull request #46013 from vvoland/c8d-resolve-fix-digested-and-named-24
[24.0 backport] c8d/resolveImage: Fix Digested and Named reference
2023-07-19 00:12:49 +02:00
Bjorn Neergaard
d63f7fb201 Merge pull request #46010 from thaJeztah/24.0_backport_buildkit_ref_replace
[24.0 backport] ci: extract buildkit version correctly with replace-d modules
2023-07-18 13:14:04 -06:00
Sebastiaan van Stijn
4f0747b0df Merge pull request #46014 from vvoland/c8d-inspect-fix-duplicate-digested-24
[backport 24.0] c8d/inspect: Don't duplicate digested ref
2023-07-18 20:19:57 +02:00
Bjorn Neergaard
ff0144de3b ci(buildkit): remove early-return from buildkit-ref
This doesn't really make sense now that this script returns a
$GITHUB_ENV snippet.

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 7310a7cd0c)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-07-18 12:11:56 -06:00
Bjorn Neergaard
a936ae7e98 ci(buildkit): remove misleading code from buildkit-ref
Post-f8c0d92a22bad004cb9cbb4db704495527521c42, BUILDKIT_REPO doesn't
really do what it claims to. Instead, don't allow overloading since the
import path for BuildKit is always the same, and make clear the
provenance of values when generating the final variable definitions.

We also better document the script, and follow some best practices for
both POSIX sh and Bash.

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 4ecc01f3ad)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-07-18 12:11:55 -06:00
Bjorn Neergaard
4c29864b02 hack/with-go-mod.sh: warn on stderr
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 48ff8a95cc)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-07-18 12:11:54 -06:00
Paweł Gronowski
3c5c192baf c8d/resolveImage: Fix Digested and Named reference
When resolving a reference that is both a Named and Digested, it could
be resolved to an image that has the same digest, but completely
different repository name.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 48fc306764fc5c39d4284021520a0337ef7e0cb0)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-07-18 18:02:36 +02:00
Paweł Gronowski
572de8764e c8d/inspect: Don't duplicate digested ref
If image name is already an untagged digested reference, don't produce
additional digested ref.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 028eab9ebb)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-07-18 17:48:35 +02:00
Justin Chadwell
5dded3340c ci: extract buildkit version correctly with replace-d modules
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit f8c0d92a22)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-18 15:23:57 +02:00
Sebastiaan van Stijn
8b24eea65e Merge pull request #45990 from thaJeztah/24.0_backport_hijack_share_request_builder
[24.0 backport] client: Client.postHijacked: use Client.buildRequest
2023-07-18 15:05:20 +02:00
Sebastiaan van Stijn
8ab6d025f6 Merge pull request #46001 from thaJeztah/24.0_backport_notestyourself
[24.0 backport] quota: remove gotest.tools from testhelpers
2023-07-18 10:24:21 +02:00
Sebastiaan van Stijn
bd1ae65aab quota: remove gotest.tools from testhelpers
gotest.tools has an init() which registers a '-update' flag;
a80f057529/internal/source/update.go (L21-L23)

The quota helper contains a testhelpers file, which is meant for usage
in (integration) tests, but as it's in the same pacakge as production
code, would also trigger the gotest.tools init.

This patch removes the gotest.tools code from this file.

Before this patch:

    $ (exec -a libnetwork-setkey "$(which dockerd)" -help)
    Usage of libnetwork-setkey:
      -exec-root string
            docker exec root (default "/run/docker")
      -update
            update golden values

With this patch applied:

    $ (exec -a libnetwork-setkey "$(which dockerd)" -help)
    Usage of libnetwork-setkey:
      -exec-root string
            docker exec root (default "/run/docker")

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 1aa17222e7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-17 23:12:28 +02:00
Sebastiaan van Stijn
2e3f3fd1e0 Merge pull request #45998 from neersighted/backport/45997/24.0
[24.0 backport] Build system grab-bag
2023-07-17 20:19:50 +02:00
Bjorn Neergaard
544032f7a4 hack/d/cli.sh: properly handle errors in curl
Add `-f` to output nothing to tar if the curl fails, and `-S` to report
errors if they happen.

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 780e8b2332)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-07-17 11:23:13 -06:00
Bjorn Neergaard
0df2e1bdd8 Dockerfile: improve CLI/rootlesskit caching
Use bind-mounts instead of a `COPY` for cli.sh, and use `COPY --link`
for rootlesskit's build stage.

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 12a19dcd84)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-07-17 11:23:12 -06:00
Bjorn Neergaard
05f82fdd00 Dockerfile(.simple): align APT_MIRROR support
Use a non-slash escape sequence to support mirrors with a path
component, and do not unconditionally replace the mirror in
Dockerfile.simple.

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 235cd6c6b2)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-07-17 11:23:11 -06:00
Bjorn Neergaard
151686a5c8 Makefile: pass through APT_MIRROR
This aligns `docker build` as invoked by the Makefile with both `docker
buildx bake` as invoked by the Makefile and directly by the user.

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit bcea83ab9b)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-07-17 11:23:10 -06:00
CrazyMax
31567e0973 Dockerfile: use default apt mirrors
Use default apt mirrors and also check APT_MIRROR
is set before updating mirrors.

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit a1d2132bf6)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-07-17 11:23:05 -06:00
Sebastiaan van Stijn
d94f2dcab2 client: Client.postHijacked: use Client.buildRequest
Use Client.buildRequest instead of a local copy of the same logic so
that we're using the same logic, and there's less chance of diverging.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c219b09d4a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-17 09:41:41 +02:00
Sebastiaan van Stijn
bff68bf2cc client: Client.setupHijackConn: explicitly ignore errors
Just making my IDE and some linters slightly happier.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit e11555218b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-17 09:41:41 +02:00
Sebastiaan van Stijn
8443a06149 Merge pull request #45974 from thaJeztah/24.0_backport_create-overlay-on-non-manager
[24.0 backport] libnet: Return proper error when overlay network can't be created
2023-07-17 09:20:55 +02:00
Sebastiaan van Stijn
36e9e796c6 Merge pull request #45976 from thaJeztah/24.0_backport_moby-bin-tags
[24.0 backport] gha: assorted fixes for bin-image
2023-07-15 01:57:25 +02:00
Sebastiaan van Stijn
e916ec1584 Merge pull request #45975 from thaJeztah/24.0_backport_hack-make-run-disable-tls
[24.0 backport] Disable tls when launching dockerd through hack/make.sh
2023-07-15 01:54:01 +02:00
Bjorn Neergaard
eb34c0b6d2 Merge pull request #45970 from thaJeztah/24.0_backport_update_go_1.20.6
[24.0 backport] update go to go1.20.6
2023-07-14 17:32:07 -06:00
Bjorn Neergaard
8bdf6d1baf ci(bin-image): add SHA-based tags
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit ecfa4f5866)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 01:05:28 +02:00
Kevin Alvarez
26a457e7a3 ci(bin-image): fix meta step
We can't upload the same file in a matrix so generate
metadata in prepare job instead. Also fixes wrong bake meta
file in merge job.

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 0a126a85a4)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 01:04:43 +02:00
CrazyMax
b9904ba319 ci(bin-image): fix typo
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 749d7449f9)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 01:04:33 +02:00
CrazyMax
e7c333cb6e ci(bin-image): don't set tags when pushing by digest
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 1686540594)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 01:03:17 +02:00
CrazyMax
fcb87e8ae1 ci: push bin image to Docker Hub
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 41261ea4ec)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 01:02:55 +02:00
Albin Kerouanton
68c0cec772 Disable tls when launching dockerd through hack/make.sh
The daemon sleeps for 15 seconds at start up when the API binds to a TCP
socket with no TLS certificate set. That's what the hack/make/run script
does, but it doesn't explicitly disable tls, thus we're experiencing
this annoying delay every time we use this script.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
(cherry picked from commit 6b1b71ced4)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:58:32 +02:00
Albin Kerouanton
738d8417e0 libnet: Return a 403 when overlay network isn't allowed
With this change, the API will now return a 403 instead of a 500 when
trying to create an overlay network on a non-manager node.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
(cherry picked from commit d29240d9eb)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:51:58 +02:00
Albin Kerouanton
a5c0fda157 libnet: Return proper error when overlay network can't be created
The commit befff0e13f inadvertendly
disabled the error returned when trying to create an overlay network on
a node which is not part of a Swarm cluster.

Since commit e3708a89cc the overlay
netdriver returns the error: `no VNI provided`.

This commit reinstate the original error message by checking if the node
is a manager before calling libnetwork's `controller.NewNetwork()`.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
(cherry picked from commit 21dcbada2d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:51:50 +02:00
Sebastiaan van Stijn
deea880581 pkg/jsonmessage: use string-literals for easier grep'ing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit ec11aea880)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:51:38 +02:00
Sebastiaan van Stijn
962a4f434f pkg/ioutils: use string-literals for easier grep'ing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit fded42c3bd)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:51:28 +02:00
Sebastiaan van Stijn
cea5829402 pkg/idtools: use string-literals for easier grep'ing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 1da079f211)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:51:19 +02:00
Sebastiaan van Stijn
69d77bc150 opts: use string-literals for easier grep'ing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 84000190d3)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:51:09 +02:00
Sebastiaan van Stijn
ff667ed932 integration: use string-literals for easier grep'ing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit ddec605aef)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:50:57 +02:00
Sebastiaan van Stijn
efe9e90ef5 libnetwork: use string-literals for easier grep'ing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 96a1c444cc)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:50:47 +02:00
Sebastiaan van Stijn
2d2df4376b daemon/cluster: use string-literals for easier grep'ing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 0db4a32b9c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:50:37 +02:00
Sebastiaan van Stijn
ae8e3294dd client: use string-literals for easier grep'ing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 4e69e16fde)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:50:25 +02:00
Sebastiaan van Stijn
892857179a cli/debug: use string-literals for easier grep'ing
Also removed some newlines from t.Fatal() as they shouldn't be needed.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c3d533f37f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:49:55 +02:00
Sebastiaan van Stijn
147b87a03e daemon: use string-literals for easier grep'ing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 02815416bb)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:49:46 +02:00
Sebastiaan van Stijn
a3f1f4eeb0 integration-cli: use string-literals for easier grep'ing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 6331a3a346)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:49:35 +02:00
Sebastiaan van Stijn
5bba60b1bb builder/builder-next: use string-literals for easier grep'ing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 2f61620339)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:49:08 +02:00
Sebastiaan van Stijn
632fc235d6 builder/dockerfile: use string-literals for easier grep'ing
Use string-literal for reduce escaped quotes, which makes for easier grepping.
While at it, also changed http -> https to keep some linters at bay.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 202907b14c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-15 00:48:58 +02:00
Sebastiaan van Stijn
75a90f85ad gha: add note about buildkit using older go version
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 41f235a2f8)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-14 22:46:03 +02:00
Sebastiaan van Stijn
fa909dfaf4 update go to go1.20.6
go1.20.6 (released 2023-07-11) includes a security fix to the net/http package,
as well as bug fixes to the compiler, cgo, the cover tool, the go command,
the runtime, and the crypto/ecdsa, go/build, go/printer, net/mail, and text/template
packages. See the Go 1.20.6 milestone on our issue tracker for details.

https://github.com/golang/go/issues?q=milestone%3AGo1.20.6+label%3ACherryPickApproved

Full diff: https://github.com/golang/go/compare/go1.20.5...go1.20.6

These minor releases include 1 security fixes following the security policy:

net/http: insufficient sanitization of Host header

The HTTP/1 client did not fully validate the contents of the Host header.
A maliciously crafted Host header could inject additional headers or entire
requests. The HTTP/1 client now refuses to send requests containing an
invalid Request.Host or Request.URL.Host value.

Thanks to Bartek Nowotarski for reporting this issue.

Includes security fixes for [CVE-2023-29406 ][1] and Go issue https://go.dev/issue/60374

[1]: https://github.com/advisories/GHSA-f8f7-69v5-w4vx

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 1ead2dd35d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-14 22:45:41 +02:00
Sebastiaan van Stijn
d09fe00d36 Merge pull request #45962 from thaJeztah/24.0_backport_fix_host_header
[24.0 backport] client: define a "dummy" hostname to use for local connections
2023-07-14 22:43:28 +02:00
Sebastiaan van Stijn
bdaadec788 testutil: use dummyhost for non-tcp connections
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit e1db9e9848)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-14 20:36:52 +02:00
Sebastiaan van Stijn
547ea18fbb pkg/plugins: use a dummy hostname for local connections
For local communications (npipe://, unix://), the hostname is not used,
but we need valid and meaningful hostname.

The current code used the socket path as hostname, which gets rejected by
go1.20.6 and go1.19.11 because of a security fix for [CVE-2023-29406 ][1],
which was implemented in  https://go.dev/issue/60374.

Prior versions go Go would clean the host header, and strip slashes in the
process, but go1.20.6 and go1.19.11 no longer do, and reject the host
header.

Before this patch, tests would fail on go1.20.6:

    === FAIL: pkg/authorization TestAuthZRequestPlugin (15.01s)
    time="2023-07-12T12:53:45Z" level=warning msg="Unable to connect to plugin: //tmp/authz2422457390/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz2422457390%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 1s"
    time="2023-07-12T12:53:46Z" level=warning msg="Unable to connect to plugin: //tmp/authz2422457390/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz2422457390%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 2s"
    time="2023-07-12T12:53:48Z" level=warning msg="Unable to connect to plugin: //tmp/authz2422457390/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz2422457390%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 4s"
    time="2023-07-12T12:53:52Z" level=warning msg="Unable to connect to plugin: //tmp/authz2422457390/authz-test-plugin.sock/AuthZPlugin.AuthZReq: Post \"http://%2F%2Ftmp%2Fauthz2422457390%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq\": http: invalid Host header, retrying in 8s"
        authz_unix_test.go:82: Failed to authorize request Post "http://%2F%2Ftmp%2Fauthz2422457390%2Fauthz-test-plugin.sock/AuthZPlugin.AuthZReq": http: invalid Host header

[1]: https://github.com/advisories/GHSA-f8f7-69v5-w4vx

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 6b7705d5b2)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-14 20:36:44 +02:00
Sebastiaan van Stijn
597a5f9794 client: define a "dummy" hostname to use for local connections
For local communications (npipe://, unix://), the hostname is not used,
but we need valid and meaningful hostname.

The current code used the client's `addr` as hostname in some cases, which
could contain the path for the unix-socket (`/var/run/docker.sock`), which
gets rejected by go1.20.6 and go1.19.11 because of a security fix for
[CVE-2023-29406 ][1], which was implemented in  https://go.dev/issue/60374.

Prior versions go Go would clean the host header, and strip slashes in the
process, but go1.20.6 and go1.19.11 no longer do, and reject the host
header.

This patch introduces a `DummyHost` const, and uses this dummy host for
cases where we don't need an actual hostname.

Before this patch (using go1.20.6):

    make GO_VERSION=1.20.6 TEST_FILTER=TestAttach test-integration
    === RUN   TestAttachWithTTY
        attach_test.go:46: assertion failed: error is not nil: http: invalid Host header
    --- FAIL: TestAttachWithTTY (0.11s)
    === RUN   TestAttachWithoutTTy
        attach_test.go:46: assertion failed: error is not nil: http: invalid Host header
    --- FAIL: TestAttachWithoutTTy (0.02s)
    FAIL

With this patch applied:

    make GO_VERSION=1.20.6 TEST_FILTER=TestAttach test-integration
    INFO: Testing against a local daemon
    === RUN   TestAttachWithTTY
    --- PASS: TestAttachWithTTY (0.12s)
    === RUN   TestAttachWithoutTTy
    --- PASS: TestAttachWithoutTTy (0.02s)
    PASS

[1]: https://github.com/advisories/GHSA-f8f7-69v5-w4vx

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 92975f0c11)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-14 20:36:33 +02:00
Sebastiaan van Stijn
fee4db80a0 client: TestSetHostHeader: don't use un-keyed literals
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 2a59188760)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-14 20:35:01 +02:00
Sebastiaan van Stijn
3fe7652ad9 Merge pull request #45959 from vvoland/tests-fix-setuptest-24
[backport 24.0] integration: Don't env cleanup before parallel subtests
2023-07-13 18:20:21 +02:00
Sebastiaan van Stijn
08321a0994 Merge pull request #45958 from rumpl/24.0_backport_cli-test-helper
[24.0 backport] integration-cli: Add t.Helper() to the cli test helper functions
2023-07-13 16:25:12 +02:00
Paweł Gronowski
959889efd9 integration: Don't env cleanup before parallel subtests
Calling function returned from setupTest (which calls testEnv.Clean) in
a defer block inside a test that spawns parallel subtests caused the
cleanup function to be called before any of the subtest did anything.

Change the defer expressions to use `t.Cleanup` instead to call it only
after all subtests have also finished.
This only changes tests which have parallel subtests.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit f9e2eed55d)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-07-13 15:06:36 +02:00
Djordje Lukic
6c5144d3e5 Add t.Helper() to the cli test helper functions
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
2023-07-13 14:52:49 +02:00
Brian Goff
661fe9f3bb Merge pull request #45951 from crazy-max/24.0_backport_ci-buildkit-goversion 2023-07-12 12:24:38 -07:00
CrazyMax
9ff2c3918c ci(buildkit): match moby go version for buildkit tests
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit ee9fe2c838)
2023-07-12 19:45:44 +02:00
CrazyMax
a4b1a5aef4 vendor: github.com/moby/buildkit@v0.11 0a0807e
full diff 798ad6b...0a15675

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-07-12 19:45:44 +02:00
Sebastiaan van Stijn
71f749be8d Merge pull request #45921 from thaJeztah/24.0_backport_fix_expose_npe
[24.0 backport] daemon/containerd: fix assignment to entry in nil map during commit
2023-07-10 13:53:31 +02:00
Sebastiaan van Stijn
6c7f6c2d47 daemon/containerd: fix assignment to entry in nil map during commit
A panic would happen when converting an config that had ports exposed, because
the ExposedPorts map in the OCI-spec was not initialized. This could happen
when committing a container, or when using the classic builder and the
parent image had ports exposed, for example

    FROM busybox AS stage0
    EXPOSE 80

    FROM stage0 AS stage1
    RUN echo hello

Example of the panic:

    2023/07/07 15:13:02 http: panic serving @: assignment to entry in nil map
    goroutine 1944 [running]:
    net/http.(*conn).serve.func1()
    	/usr/local/go/src/net/http/server.go:1854 +0xbf
    panic({0x45f660, 0xb6a8d0})
    	/usr/local/go/src/runtime/panic.go:890 +0x263
    github.com/docker/docker/daemon/containerd.containerConfigToOciImageConfig(...)
    	/go/src/github.com/docker/docker/daemon/containerd/image_import.go:397
    github.com/docker/docker/daemon/containerd.generateCommitImageConfig({0xc001470498, {0x0, 0x0}, {0xc000c437d8, 0x5}, {0x0, 0x0}, {0xc000c43b27, 0x5}, {0x0, ...}, ...}, ...)
    	/go/src/github.com/docker/docker/daemon/containerd/image_commit.go:138 +0x40e
    github.com/docker/docker/daemon/containerd.(*ImageService).CommitImage(0xc0008853e0, {0xb8f660, 0xc000c4f7c0}, {{0x0, 0x0}, {0x0, 0x0}, 0xc00104b900, 0xc00104b180, {0xc0011a7640, ...}, ...})
    	/go/src/github.com/docker/docker/daemon/containerd/image_commit.go:82 +0x73b
    github.com/docker/docker/daemon/containerd.(*ImageService).CommitBuildStep(0xc0008853e0, {0xb8f660, 0xc000c4f7c0}, {{0x0, 0x0}, {0x0, 0x0}, 0xc00104b900, 0xc00104b180, {0xc0011a7640, ...}, ...})
    	/go/src/github.com/docker/docker/daemon/containerd/image_commit.go:308 +0x110
    github.com/docker/docker/builder/dockerfile.(*Builder).commitContainer(0xc0012b8cc0, {0xb8f660, 0xc000c4f7c0}, 0xc0010b2b60, {0xc0011a7640, 0x40}, 0xc00104b180)
    	/go/src/github.com/docker/docker/builder/dockerfile/internals.go:61 +0x168
    github.com/docker/docker/builder/dockerfile.(*Builder).commit(0xc0012b8cc0, {0xb8f660, 0xc000c4f7c0}, 0xc0010b2b60, {0xc0012a7d80?, 0xc001340060?})
    	/go/src/github.com/docker/docker/builder/dockerfile/internals.go:45 +0x1aa
    github.com/docker/docker/builder/dockerfile.dispatchLabel({0xb8f660, 0xc000c4f7c0}, {0xc0010b2b60, 0xc000c6b628, 0xc0012b8cc0, {0xb80f60, 0xc0011a46c0}, 0xc000bc2560}, 0x1e24a85?)
    	/go/src/github.com/docker/docker/builder/dockerfile/dispatchers.go:83 +0x258
    github.com/docker/docker/builder/dockerfile.dispatch({0xb8f660, 0xc000c4f7c0}, {0xc0010b2b60, 0xc000c6b628, 0xc0012b8cc0, {0xb80f60, 0xc0011a46c0}, 0xc000bc2560}, {0xb7be40, 0xc00111cde0})
    	/go/src/github.com/docker/docker/builder/dockerfile/evaluator.go:74 +0x529
    github.com/docker/docker/builder/dockerfile.(*Builder).dispatchDockerfileWithCancellation(0xc0012b8cc0, {0xb8f660, 0xc000c4f7c0}, {0xc000b1d380, 0x1, 0xc0011a4660?}, {0x0, 0x0, 0x0?}, 0x5c, ...)
    	/go/src/github.com/docker/docker/builder/dockerfile/builder.go:296 +0x8f2
    github.com/docker/docker/builder/dockerfile.(*Builder).build(0xc0012b8cc0, {0xb8f660, 0xc000c4f7c0}, {0xb80f60, 0xc0011a46c0}, 0xc0011a49f0)
    	/go/src/github.com/docker/docker/builder/dockerfile/builder.go:211 +0x2e5
    github.com/docker/docker/builder/dockerfile.(*BuildManager).Build(0xc0008868c0, {0xb8f708, 0xc0011a44b0}, {{0xb789c0, 0xc0011a4540}, {{0xb6b940, 0xc000c22a50}, {0xb6c5e0, 0xc000c22a68}, {0xb6c5e0, ...}, ...}, ...})
    	/go/src/github.com/docker/docker/builder/dockerfile/builder.go:98 +0x358
    github.com/docker/docker/api/server/backend/build.(*Backend).Build(0xc0007d0870, {0xb8f708, 0xc0011a44b0}, {{0xb789c0, 0xc0011a4540}, {{0xb6b940, 0xc000c22a50}, {0xb6c5e0, 0xc000c22a68}, {0xb6c5e0, ...}, ...}, ...})
    	/go/src/github.com/docker/docker/api/server/backend/build/backend.go:69 +0x186
    github.com/docker/docker/api/server/router/build.(*buildRouter).postBuild(0xc0008333c0, {0xb8f708, 0xc0011a44b0}, {0xb8e130, 0xc0000ed500}, 0xc0010d4800, 0xc0012df760?)
    	/go/src/github.com/docker/docker/api/server/router/build/build_routes.go:280 +0x7a6
    github.com/docker/docker/api/server/middleware.ExperimentalMiddleware.WrapHandler.func1({0xb8f708, 0xc0011a44b0}, {0xb8e130?, 0xc0000ed500?}, 0x36cf80?, 0xc0010ab550?)
    	/go/src/github.com/docker/docker/api/server/middleware/experimental.go:26 +0x15b
    github.com/docker/docker/api/server/middleware.VersionMiddleware.WrapHandler.func1({0xb8f708, 0xc0011a4480}, {0xb8e130, 0xc0000ed500}, 0xc000d787e8?, 0xc000d787a0?)
    	/go/src/github.com/docker/docker/api/server/middleware/version.go:62 +0x4d7
    github.com/docker/docker/pkg/authorization.(*Middleware).WrapHandler.func1({0xb8f708, 0xc0011a4480}, {0xb8e130?, 0xc0000ed500?}, 0xc0010d4800, 0xc0010ab500?)
    	/go/src/github.com/docker/docker/pkg/authorization/middleware.go:59 +0x649
    github.com/docker/docker/api/server.(*Server).makeHTTPHandler.func1({0xb8e130, 0xc0000ed500}, 0xc0010d4700)
    	/go/src/github.com/docker/docker/api/server/server.go:53 +0x1ce
    net/http.HandlerFunc.ServeHTTP(0xc0010d4600?, {0xb8e130?, 0xc0000ed500?}, 0xc000d789e8?)
    	/usr/local/go/src/net/http/server.go:2122 +0x2f
    github.com/docker/docker/vendor/github.com/gorilla/mux.(*Router).ServeHTTP(0xc0001a7e00, {0xb8e130, 0xc0000ed500}, 0xc000d37600)
    	/go/src/github.com/docker/docker/vendor/github.com/gorilla/mux/mux.go:210 +0x1cf
    net/http.serverHandler.ServeHTTP({0xb7ec58?}, {0xb8e130, 0xc0000ed500}, 0xc000d37600)
    	/usr/local/go/src/net/http/server.go:2936 +0x316
    net/http.(*conn).serve(0xc0012661b0, {0xb8f708, 0xc000fd0360})
    	/usr/local/go/src/net/http/server.go:1995 +0x612
    created by net/http.(*Server).Serve
    	/usr/local/go/src/net/http/server.go:3089 +0x5ed

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a0e1155b28)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-10 11:18:31 +02:00
Cory Snider
ecd494abf3 Merge pull request #45909 from corhere/backport-24.0/improve-test-flakiness
[24.0 backport] make tests less flaky
2023-07-07 17:03:03 -04:00
Cory Snider
0e88c57c47 integration: disable iptables in parallel tests
Multiple daemons starting/running concurrently can collide with each
other when editing iptables rules. Most integration tests which opt into
parallelism and start daemons work around this problem by starting the
daemon with the --iptables=false option. However, some of the tests
neglect to pass the option when starting or restarting the daemon,
resulting in those tests being flaky.

Audit the integration tests which call t.Parallel() and (*Daemon).Stop()
and add --iptables=false arguments where needed.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit cdcb7c28c5)
Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-07-07 15:43:08 -04:00
Cory Snider
a3049653c1 pkg/plugins: make unit test less time sensitive
TestClientWithRequestTimeout has been observed to flake in CI. The
timing in the test is quite tight, only giving the client a 10ms window
to time out, which could potentially be missed if the host is under
load and the goroutine scheduling is unlucky. Give the client a full
five seconds of grace to time out before failing the test.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 9cee34bc94)
Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-07-07 15:42:59 -04:00
Bjorn Neergaard
4ffc61430b Merge pull request #45903 from thaJeztah/24.0_backport_fix_volume_npe
[24.0 backport] daemon: daemon.prepareMountPoints(): fix panic if mount is not a volume
2023-07-07 08:42:26 -06:00
Sebastiaan van Stijn
d3893b58ff daemon: daemon.prepareMountPoints(): fix panic if mount is not a volume
The daemon.lazyInitializeVolume() function only handles restoring Volumes
if a Driver is specified. The Container's MountPoints field may also
contain other kind of mounts (e.g., bind-mounts). Those were ignored, and
don't return an error; 1d9c8619cd/daemon/volumes.go (L243-L252C2)

However, the prepareMountPoints() assumed each MountPoint was a volume,
and logged an informational message about the volume being restored;
1d9c8619cd/daemon/mounts.go (L18-L25)

This would panic if the MountPoint was not a volume;

    github.com/docker/docker/daemon.(*Daemon).prepareMountPoints(0xc00054b7b8?, 0xc0007c2500)
            /root/rpmbuild/BUILD/src/engine/.gopath/src/github.com/docker/docker/daemon/mounts.go:24 +0x1c0
    github.com/docker/docker/daemon.(*Daemon).restore.func5(0xc0007c2500, 0x0?)
            /root/rpmbuild/BUILD/src/engine/.gopath/src/github.com/docker/docker/daemon/daemon.go:552 +0x271
    created by github.com/docker/docker/daemon.(*Daemon).restore
            /root/rpmbuild/BUILD/src/engine/.gopath/src/github.com/docker/docker/daemon/daemon.go:530 +0x8d8
    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x30 pc=0x564e9be4c7c0]

This issue was introduced in 647c2a6cdd

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a490248f4d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-07 15:47:32 +02:00
Sebastiaan van Stijn
1d9c8619cd Merge pull request #45860 from thaJeztah/24.0_backport_update_cgroups
[24.0 backport] vendor: github.com/containerd/cgroups/v3 v3.0.2
2023-07-03 15:55:45 +02:00
Sebastiaan van Stijn
64f79562fb Merge pull request #45869 from thaJeztah/24.0_backport_docs_plugin_disable_force_carry
[24.0 backport] docs: api: add missing "force" query arg on plugin disable
2023-07-02 23:02:35 +02:00
Sebastiaan van Stijn
05cf8e8130 Merge pull request #45867 from thaJeztah/24.0_backport_api_remove_deprecated_swarm
[24.0 backport] docs: api: remove outdated information from ServerVersion
2023-07-02 21:57:20 +02:00
Sebastiaan van Stijn
5892aae60f docs: api v1.28 - v1.40: add missing "force" query arg on plugin disable
This option was added in 8cb2229cd1 for
API version 1.28, but forgot to update the documentation and version
history.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit f6258f70cb)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-02 13:08:43 +02:00
Sebastiaan van Stijn
7adb590e16 docs: api v1.41: add missing "force" query arg on plugin disable
This option was added in 8cb2229cd1 for
API version 1.28, but forgot to update the documentation and version
history.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 892e9f2c23)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-02 13:08:43 +02:00
Sebastiaan van Stijn
b5aacf8161 docs: api v1.42: add missing "force" query arg on plugin disable
This option was added in 8cb2229cd1 for
API version 1.28, but forgot to update the documentation and version
history.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a4bdfb963f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-02 13:08:43 +02:00
Sebastiaan van Stijn
b732cfd392 docs: api v1.43: add missing "force" query arg on plugin disable
This option was added in 8cb2229cd1 for
API version 1.28, but forgot to update the documentation and version
history.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 85ccb25eb8)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-02 13:08:43 +02:00
Sebastiaan van Stijn
50fb65f0f5 docs: api: amend changelog for API 1.28 for "force" option
This option was added in 8cb2229cd1 for
API version 1.28, but forgot to update the documentation and version
history.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit aba8e04ab1)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-02 13:08:43 +02:00
Milas Bowman
32bcbdfe65 api: swagger: add missing "force" query arg on plugin disable
This has been around for a long time - since v17.04 (API v1.28)
but was never documented.

It allows removing a plugin even if it's still in use.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
(cherry picked from commit eb0edeafdd)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-02 13:07:53 +02:00
Sebastiaan van Stijn
f66ef31605 docs: api v1.41: remove outdated information from ServerVersion
This field's documentation was still referring to the Swarm V1 API, which
is deprecated, and the link redirects to SwarmKit.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit ed0dbb8518)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-02 12:41:09 +02:00
Sebastiaan van Stijn
acb95e4544 docs: api v1.42: remove outdated information from ServerVersion
This field's documentation was still referring to the Swarm V1 API, which
is deprecated, and the link redirects to SwarmKit.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit b770a50dee)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-02 12:41:09 +02:00
Sebastiaan van Stijn
335ed29345 docs: api v1.43: remove outdated information from ServerVersion
This field's documentation was still referring to the Swarm V1 API, which
is deprecated, and the link redirects to SwarmKit.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 18d77ff455)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-02 12:41:08 +02:00
Sebastiaan van Stijn
0ef846ce2e api: remove outdated information from ServerVersion
This field's documentation was still referring to the Swarm V1 API, which
is deprecated, and the link redirects to SwarmKit.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 92f1ddaf0a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-02 12:41:08 +02:00
Bjorn Neergaard
4a1747d2e4 Merge pull request #45865 from thaJeztah/24.0_backport_api_remove_deprecated
[24.0 backport] docs: api: remove "ClusterStore" and "ClusterAdvertise" fields
2023-07-01 13:03:13 -06:00
Sebastiaan van Stijn
af25852baa docs: api v1.42: remove "ClusterStore" and "ClusterAdvertise" fields
The `ClusterStore` and `ClusterAdvertise` fields were deprecated in commit
616e64b42f (and would no longer be included in
the `/info` API response), and were fully removed in 24.0.0 through commit
68bf777ece

This patch removes the fields from the swagger file.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit e8f206972a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-01 16:42:12 +02:00
Sebastiaan van Stijn
7a9c831e6a docs: api v1.43: remove "ClusterStore" and "ClusterAdvertise" fields
The `ClusterStore` and `ClusterAdvertise` fields were deprecated in commit
616e64b42f (and would no longer be included in
the `/info` API response), and were fully removed in 24.0.0 through commit
68bf777ece

This patch removes the fields from the swagger file.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit e58a60902c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-01 16:42:12 +02:00
Sebastiaan van Stijn
649bb2b9b8 api: remove "ClusterStore" and "ClusterAdvertise" fields
The `ClusterStore` and `ClusterAdvertise` fields were deprecated in commit
616e64b42f (and would no longer be included in
the `/info` API response), and were fully removed in 24.0.0 through commit
68bf777ece

This patch removes the fields from the swagger file.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 3c905d0db9)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-01 16:42:12 +02:00
Sebastiaan van Stijn
457399013b vendor: github.com/containerd/cgroups/v3 v3.0.2
full diff: https://github.com/containerd/cgroups/compare/v3.0.1...v3.0.2

relevant changes:

- cgroup2: only enable the cpuset controller if cpus or mems is specified
- cgroup1 delete: proceed to the next subsystem when a cgroup is not found
- Cgroup2: Reduce allocations for manager.Stat
- Improve performance by for pid stats (cgroups1) re-using readuint
- Reduce allocs in ReadUint64 by pre-allocating byte buffer
- cgroup2: rm/simplify some code

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit f379af6d17)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-01 12:41:51 +02:00
Sebastiaan van Stijn
3bd0f582c9 Merge pull request #45857 from neersighted/backport/45839/24.0
[24.0 backport] c8d/prune: Fix images being deleted when they're still used with a different reference
2023-06-30 21:13:01 +02:00
Brian Goff
be50480621 Merge pull request #45856 from thaJeztah/24.0_backport_improve_fd_count
[24.0 backport] pkg/fileutils: GetTotalUsedFds: reduce allocations
2023-06-30 10:30:58 -07:00
Paweł Gronowski
016ad9b3e8 c8d/prune: Handle containers started from image id
If an image is only by id instead of its name, don't prune it
completely. but only untag it and create a dangling image for it.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit e638351ef9)
Resolved conflicts:
	daemon/containerd/image_prune.go
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-30 10:34:09 -06:00
Paweł Gronowski
87778af711 c8d/prune: Exclude dangling tag of the images used by containers
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit a93298d4db)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-30 10:31:47 -06:00
Paweł Gronowski
8bf037b246 c8d/softDelete: Deep copy Labels
So we don't override the original Labels in the passed image object.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit a6d5db3f9b)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-30 10:31:45 -06:00
Paweł Gronowski
8afe75ffa9 c8d/softDelete: Extract ensureDanglingImage
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 2b0655a71a)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-30 10:31:44 -06:00
Paweł Gronowski
e2bade43e7 testutil/environment: Add GetTestDanglingImageId
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit a96e6044cc)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-30 10:31:43 -06:00
Sebastiaan van Stijn
e0091d6616 c8d: ImageService.softImageDelete: rename var that collided with import
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit f17c9e4aeb)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-30 10:31:34 -06:00
Sebastiaan van Stijn
42f3f7ed86 c8d: ImageService.softImageDelete: use OCI and containerd constants
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit df5deab20b)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-30 10:31:33 -06:00
Sebastiaan van Stijn
aace62f6d3 pkg/fileutils: GetTotalUsedFds(): use fast-path for Kernel 6.2 and up
Linux 6.2 and up (commit [f1f1f2569901ec5b9d425f2e91c09a0e320768f3][1])
provides a fast path for the number of open files for the process.

From the [Linux docs][2]:

> The number of open files for the process is stored in 'size' member of
> `stat()` output for /proc/<pid>/fd for fast access.

[1]: f1f1f25699
[2]: https://docs.kernel.org/filesystems/proc.html#proc-pid-fd-list-of-symlinks-to-open-files

This patch adds a fast-path for Kernels that support this, and falls back
to the slow path if the Size fields is zero.

Comparing on a Fedora 38 (kernel 6.2.9-300.fc38.x86_64):

Before/After:

    go test -bench ^BenchmarkGetTotalUsedFds$ -run ^$ ./pkg/fileutils/
    BenchmarkGetTotalUsedFds        57264     18595 ns/op     408 B/op      10 allocs/op
    BenchmarkGetTotalUsedFds       370392      3271 ns/op      40 B/op       3 allocs/op

Note that the slow path has 1 more file-descriptor, due to the open
file-handle for /proc/<pid>/fd during the calculation.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit ec79d0fc05)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-30 18:30:34 +02:00
Sebastiaan van Stijn
bb50485dfd pkg/fileutils: GetTotalUsedFds: reduce allocations
Use File.Readdirnames instead of os.ReadDir, as we're only interested in
the number of files, and results don't have to be sorted.

Before:

    BenchmarkGetTotalUsedFds-5   	  149272	      7896 ns/op	     945 B/op	      20 allocs/op

After:

    BenchmarkGetTotalUsedFds-5   	  153517	      7644 ns/op	     408 B/op	      10 allocs/op

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit eaa9494b71)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-30 18:30:24 +02:00
Sebastiaan van Stijn
5dcea89ce1 pkg/fileutils: add BenchmarkGetTotalUsedFds
go test -bench ^BenchmarkGetTotalUsedFds$ -run ^$ ./pkg/fileutils/
    goos: linux
    goarch: arm64
    pkg: github.com/docker/docker/pkg/fileutils
    BenchmarkGetTotalUsedFds-5   	  149272	      7896 ns/op	     945 B/op	      20 allocs/op

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 03390be5fa)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-30 18:29:27 +02:00
Sebastiaan van Stijn
01eb4835c9 pkg/fileutils: GetTotalUsedFds(): don't pretend to support FreeBSD
Commit 8d56108ffb moved this function from
the generic (no build-tags) fileutils.go to a unix file, adding "freebsd"
to the build-tags.

This likely was a wrong assumption (as other files had freebsd build-tags).
FreeBSD's procfs does not mention `/proc/<pid>/fd` in the manpage, and
we don't test FreeBSD in CI, so let's drop it, and make this a Linux-only
file.

While updating also dropping the import-tag, as we're planning to move
this file internal to the daemon.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 252e94f499)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-30 18:29:17 +02:00
Sebastiaan van Stijn
cd44aba8db [24.0] pkg/fileutils: switch to use containerd log pkg
(very) partial backport of 74da6a6363
and ab35df454d

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-30 18:28:55 +02:00
Bjorn Neergaard
2435d75b89 Merge pull request #45849 from neersighted/backport/45816/24.0
[24.0 backport] c8d/images: handle images without manifests for default platform
2023-06-30 06:20:57 -06:00
Sebastiaan van Stijn
80d1e863f5 Merge pull request #45853 from thaJeztah/24.0_backport_gha_fix_missing_daemonjson
[24.0 backport] gha: don't fail if no daemon.json is present
2023-06-30 11:02:40 +02:00
Sebastiaan van Stijn
ee29fd944b gha: don't fail if no daemon.json is present
CI failed sometimes if no daemon.json was present:

    Run sudo rm /etc/docker/daemon.json
    sudo rm /etc/docker/daemon.json
    sudo service docker restart
    docker version
    docker info
    shell: /usr/bin/bash -e {0}
    env:
    DESTDIR: ./build
    BUILDKIT_REPO: moby/buildkit
    BUILDKIT_TEST_DISABLE_FEATURES: cache_backend_azblob,cache_backend_s3,merge_diff
    BUILDKIT_REF: 798ad6b0ce9f2fe86dfb2b0277e6770d0b545871
    rm: cannot remove '/etc/docker/daemon.json': No such file or directory
    Error: Process completed with exit code 1.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 264dbad43a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-30 01:52:49 +02:00
Laura Brehm
b8ee9a7829 c8d/images: handle images without manifests for default platform
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
(cherry picked from commit 6d3bcd8017)
Resolved conflicts:
	daemon/containerd/image.go
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-29 13:43:19 -06:00
Sebastiaan van Stijn
d9e097e328 vendor: github.com/opencontainers/image-spec v1.1.0-rc3
full diff: https://github.com/opencontainers/image-spec/compare/3a7f492d3f1b...v1.1.0-rc3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit b42e367045)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-29 13:43:18 -06:00
Brian Goff
2bef272269 Merge pull request #45824 from thaJeztah/24.0_backport_fix_live_restore_local_vol_mounts
[24.0 backport] Restore active mount counts on live-restore
2023-06-28 14:27:11 -07:00
Sebastiaan van Stijn
3f9d07570a Merge pull request #45833 from neersighted/backport/45766/24.0
[24.0 backport] seccomp: always allow name_to_handle_at(2)
2023-06-28 18:34:09 +02:00
Bjorn Neergaard
806849eb62 seccomp: add name_to_handle_at to allowlist
Based on the analysis on [the previous PR][1].

  [1]: https://github.com/moby/moby/pull/45766#pullrequestreview-1493908145

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit b335e3d305)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-28 05:46:56 -06:00
Brian Goff
c24c37bd8a Restore active mount counts on live-restore
When live-restoring a container the volume driver needs be notified that
there is an active mount for the volume.
Before this change the count is zero until the container stops and the
uint64 overflows pretty much making it so the volume can never be
removed until another daemon restart.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit 647c2a6cdd)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-28 09:45:07 +02:00
Vitor Anjos
c306276ab1 remove name_to_handle_at(2) from filtered syscalls
Signed-off-by: Vitor Anjos <bartier@users.noreply.github.com>
(cherry picked from commit fdc9b7cceb)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-27 13:20:23 -06:00
Sebastiaan van Stijn
6eb4d7f33b Merge pull request #45829 from thaJeztah/24.0_backport_sudo_tee
[24.0 backport] gha: Setup Runner: add missing sudo
2023-06-27 16:36:43 +02:00
Sebastiaan van Stijn
186eb805f6 Merge pull request #45827 from thaJeztah/24.0_backport_dockerfile_more_resilient
[24.0 backport] Dockerfile: make cli stages more resilient against unclean termination
2023-06-27 16:09:15 +02:00
Sebastiaan van Stijn
d5e31e03b6 gha: Setup Runner: add missing sudo
I think this may be missing a sudo (as all other operations do use
sudo to access daemon.json);

    Run if [ ! -e /etc/docker/daemon.json ]; then
      if [ ! -e /etc/docker/daemon.json ]; then
       echo '{}' | tee /etc/docker/daemon.json >/dev/null
      fi
      DOCKERD_CONFIG=$(jq '.+{"experimental":true,"live-restore":true,"ipv6":true,"fixed-cidr-v6":"2001:db8:1::/64"}' /etc/docker/daemon.json)
      sudo tee /etc/docker/daemon.json <<<"$DOCKERD_CONFIG" >/dev/null
      sudo service docker restart
      shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
      env:
        GO_VERSION: 1.20.5
        GOTESTLIST_VERSION: v0.3.1
        TESTSTAT_VERSION: v0.1.3
        ITG_CLI_MATRIX_SIZE: 6
        DOCKER_EXPERIMENTAL: 1
        DOCKER_GRAPHDRIVER: overlay2
    tee: /etc/docker/daemon.json: Permission denied
    Error: Process completed with exit code 1.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit d8bc5828cd)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-27 15:40:46 +02:00
Sebastiaan van Stijn
85ad299668 Dockerfile: make cli stages more resilient against unclean termination
The Dockerfile in this repository performs many stages in parallel. If any of
those stages fails to build (which could be due to networking congestion),
other stages are also (forcibly?) terminated, which can cause an unclean
shutdown.

In some case, this can cause `git` to be terminated, leaving a `.lock` file
behind in the cache mount. Retrying the build now will fail, and the only
workaround is to clean the build-cache (which causes many stages to be
built again, potentially triggering the problem again).

     > [dockercli-integration 3/3] RUN --mount=type=cache,id=dockercli-integration-git-linux/arm64/v8,target=./.git     --mount=type=cache,target=/root/.cache/go-build,id=dockercli-integration-build-linux/arm64/v8     /download-or-build-cli.sh v17.06.2-ce https://github.com/docker/cli.git /build:
    #0 1.575 fatal: Unable to create '/go/src/github.com/docker/cli/.git/shallow.lock': File exists.
    #0 1.575
    #0 1.575 Another git process seems to be running in this repository, e.g.
    #0 1.575 an editor opened by 'git commit'. Please make sure all processes
    #0 1.575 are terminated then try again. If it still fails, a git process
    #0 1.575 may have crashed in this repository earlier:
    #0 1.575 remove the file manually to continue.

This patch:

- Updates the Dockerfile to remove `.lock` files (`shallow.lock`, `index.lock`)
  that may have been left behind from previous builds. I put this code in the
  Dockerfile itself (not the script), as the script may be used in other
  situations outside of the Dockerfile (for which we cannot guarantee no other
  git session is active).
- Adds a `docker --version` step to the stage; this is mostly to verify the
  build was successful (and to be consistent with other stages).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 9f6dbbc7ea)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-27 14:48:39 +02:00
Sebastiaan van Stijn
4735ce7ff2 Merge pull request #45822 from thaJeztah/24.0_backport_containerd-from-scratch
[24.0 backport] Skip cache lookup for "FROM scratch" in containerd
2023-06-27 14:14:50 +02:00
Tianon Gravi
e84365f967 Skip cache lookup for "FROM scratch" in containerd
Ideally, this should actually do a lookup across images that have no parent, but I wasn't 100% sure how to accomplish that so I opted for the smaller change of having `FROM scratch` builds not be cached for now.

Signed-off-by: Tianon Gravi <admwiggin@gmail.com>
(cherry picked from commit 1741771b67)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-27 11:51:44 +02:00
Sebastiaan van Stijn
5899e935d4 Merge pull request #45813 from thaJeztah/24.0_backport_no_homedir
[24.0 backport] integration-cli: don't use pkg/homedir in test
2023-06-26 15:11:21 +02:00
Bjorn Neergaard
4d5f1d6bbc Merge pull request #45811 from thaJeztah/24.0_backport_update_buildx_0.11
[24.0 backport] Dockerfile: update buildx to v0.11.0
2023-06-26 06:05:58 -06:00
Sebastiaan van Stijn
96534f015d integration-cli: don't use pkg/homedir in test
I'm considering deprecating the "Key()" utility, as it was only
used in tests.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 0215a62d5b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-26 13:42:18 +02:00
Sebastiaan van Stijn
49e24566d0 Merge pull request #45810 from thaJeztah/24.0_backport_fix-missing-csi-topology
[24.0 backport] Fix missing Topology in NodeCSIInfo
2023-06-26 13:04:42 +02:00
Sebastiaan van Stijn
6424ae830b Dockerfile: update buildx to v0.11.0
Update the version of buildx we use in the dev-container to v0.11.0;
https://github.com/docker/buildx/releases/tag/v0.11.0

Full diff: https://github.com/docker/buildx/compare/v0.10.5..v0.11.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 4d831949a7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-26 12:10:59 +02:00
Drew Erny
6055b07292 Fix missing Topology in NodeCSIInfo
Added code to correctly retrieve and convert the Topology from the gRPC
Swarm Node.

Signed-off-by: Drew Erny <derny@mirantis.com>
(cherry picked from commit cdb1293eea)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-26 11:01:28 +02:00
Sebastiaan van Stijn
98518e0734 Merge pull request #45801 from thaJeztah/24.0_backport_fix-45788-restore-exit-status
[24.0 backport] daemon: fix restoring container with missing task
2023-06-23 22:20:53 +02:00
Cory Snider
2f379ecfd6 daemon: fix restoring container with missing task
Before 4bafaa00aa, if the daemon was
killed while a container was running and the container shim is killed
before the daemon is restarted, such as if the host system is
hard-rebooted, the daemon would restore the container to the stopped
state and set the exit code to 255. The aforementioned commit introduced
a regression where the container's exit code would instead be set to 0.
Fix the regression so that the exit code is once against set to 255 on
restore.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 165dfd6c3e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-23 18:21:29 +02:00
Sebastiaan van Stijn
8b61625a5e Merge pull request #45790 from crazy-max/24.0_backport_fix-host-gateway
[24.0 backport] builder: pass host-gateway IP as worker label
2023-06-23 09:34:21 +02:00
Bjorn Neergaard
575d03df66 Merge pull request #45798 from thaJeztah/24.0_backport_fix-health-probe-double-unlock
[24.0 backport] daemon: fix double-unlock in health check probe
2023-06-22 18:38:06 -06:00
Bjorn Neergaard
a13eea29fb Merge pull request #45794 from thaJeztah/24.0_backport_fix_45770_processevent_nil_check
[24.0 backport] daemon: fix panic on failed exec start
2023-06-22 18:17:59 -06:00
Cory Snider
136893e33b daemon: fix double-unlock in health check probe
Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 786c9adaa2)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-23 00:59:41 +02:00
Cory Snider
290fc0440c daemon: fix panic on failed exec start
If an exec fails to start in such a way that containerd publishes an
exit event for it, daemon.ProcessEvent will race
daemon.ContainerExecStart in handling the failure. This race has been a
long-standing bug, which was mostly harmless until
4bafaa00aa. After that change, the daemon
would dereference a nil pointer and crash if ProcessEvent won the race.
Restore the status quo buggy behaviour by adding a check to skip the
dereference if execConfig.Process is nil.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 3b28a24e97)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-22 23:25:44 +02:00
Sebastiaan van Stijn
0556ba23a4 daemon: handleContainerExit(): use logrus.WithFields
Use `WithFields()` instead of chaining multiple `WithField()` calls.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit de363f1404)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-22 23:25:38 +02:00
CrazyMax
35a29c7328 builder: pass host-gateway IP as worker label
We missed a case when parsing extra hosts from the dockerfile
frontend so the build fails.

To handle this case we need to set a dedicated worker label
that contains the host gateway IP so clients like Buildx
can just set the proper host:ip when parsing extra hosts
that contain the special string "host-gateway".

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 21e50b89c9)
2023-06-22 16:23:40 +02:00
Sebastiaan van Stijn
6bca2bf3bf Merge pull request #45746 from thaJeztah/24.0_backport_fix_zeroes_in_linux_resources
[24.0 backport] daemon: stop setting container resources to zero
2023-06-22 14:07:35 +02:00
Cory Snider
210c4d6f4b daemon: ensure OCI options play nicely together
Audit the OCI spec options used for Linux containers to ensure they are
less order-dependent. Ensure they don't assume that any pointer fields
are non-nil and that they don't unintentionally clobber mutations to the
spec applied by other options.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 8a094fe609)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-21 22:16:28 +02:00
Cory Snider
f50cb0c7bd daemon: stop setting container resources to zero
Many of the fields in LinuxResources struct are pointers to scalars for
some reason, presumably to differentiate between set-to-zero and unset
when unmarshaling from JSON, despite zero being outside the acceptable
range for the corresponding kernel tunables. When creating the OCI spec
for a container, the daemon sets the container's OCI spec CPUShares and
BlkioWeight parameters to zero when the corresponding Docker container
configuration values are zero, signifying unset, despite the minimum
acceptable value for CPUShares being two, and BlkioWeight ten. This has
gone unnoticed as runC does not distingiush set-to-zero from unset as it
also uses zero internally to represent unset for those fields. However,
kata-containers v3.2.0-alpha.3 tries to apply the explicit-zero resource
parameters to the container, exactly as instructed, and fails loudly.
The OCI runtime-spec is silent on how the runtime should handle the case
when those parameters are explicitly set to out-of-range values and
kata's behaviour is not unreasonable, so the daemon must therefore be in
the wrong.

Translate unset values in the Docker container's resources HostConfig to
omit the corresponding fields in the container's OCI spec when starting
and updating a container in order to maximize compatibility with
runtimes.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit dea870f4ea)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-21 22:16:22 +02:00
Cory Snider
0a6a5a9140 daemon: modernize oci_linux_test.go
Switch to using t.TempDir() instead of rolling our own.

Clean up mounts leaked by the tests as otherwise the tests fail due to
the leaked mounts because unlike the old cleanup code, t.TempDir()
cleanup does not ignore errors from os.RemoveAll.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 9ff169ccf4)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-21 22:14:47 +02:00
Sebastiaan van Stijn
f3743766e9 Merge pull request #45785 from vvoland/busybox-5007-24 2023-06-21 22:13:49 +02:00
Akihiro Suda
e6a7df0e00 Merge pull request #45786 from neersighted/backport/45781/24.0
[24.0 backport] c8d: mark stargz as requiring reference-counted mounts
2023-06-22 01:17:07 +09:00
Akihiro Suda
d3c5b613ac Merge pull request #45703 from thaJeztah/24.0_backport_bump_swarmkit
[24.0 backport] vendor: github.com/moby/swarmkit/v2 v2.0.0-20230531205928-01bb7a41396b
2023-06-22 00:38:40 +09:00
Bjorn Neergaard
7ed0771d20 Merge pull request #45774 from thaJeztah/24.0_backport_dont_cancel_stop
[24.0 backport] don't cancel container stop when cancelling context
2023-06-21 09:13:04 -06:00
Bjorn Neergaard
6285ec378c Merge pull request #45782 from thaJeztah/24.0_backport_reserve_once
[24.0 backport] daemon: registerName(): don't reserve name twice
2023-06-21 09:12:39 -06:00
Bjorn Neergaard
c92fd5220a c8d: mark stargz as requiring reference-counted mounts
The stargz snapshotter cannot be re-mounted, so the reference-counted
path must be used.

Co-authored-by: Djordje Lukic <djordje.lukic@docker.com>
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 21c0a54a6b)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-21 09:02:11 -06:00
Sebastiaan van Stijn
aaa8a90747 Merge pull request #45780 from neersighted/backport/45698/24.0 2023-06-21 17:00:44 +02:00
Paweł Gronowski
5e48bbd14c contrib/busybox: Update to FRP-5007-g82accfc19
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit e010223186)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-06-21 15:37:43 +02:00
Sebastiaan van Stijn
6776279896 daemon: registerName(): don't reserve name twice
daemon.generateNewName() already reserves the generated name, but its name
did not indicate it did. The daemon.registerName() assumed that the generated
name still had to be reserved, which could mean it would try to reserve the
same name again.

This patch renames daemon.generateNewName to daemon.generateAndReserveName
to make it clearer what it does, and updates registerName() to return early
if it successfully generated (and registered) the container name.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 3ba67ee214)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-20 23:48:45 +02:00
Sebastiaan van Stijn
7db3243e34 don't cancel container stop when cancelling context
Commit 90de570cfa passed through the request
context to daemon.ContainerStop(). As a result, cancelling the context would
cancel the "graceful" stop of the container, and would proceed with forcefully
killing the container.

This patch partially reverts the changes from 90de570cfa
and breaks the context to prevent cancelling the context from cancelling the stop.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit fc94ed0a86)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-20 23:40:57 +02:00
Djordje Lukic
aec7a80c6f c8d: Use reference counting while mounting a snapshot
Some snapshotters (like overlayfs or zfs) can't mount the same
directories twice. For example if the same directroy is used as an upper
directory in two mounts the kernel will output this warning:

    overlayfs: upperdir is in-use as upperdir/workdir of another mount, accessing files from both mounts will result in undefined behavior.

And indeed accessing the files from both mounts will result in an "No
such file or directory" error.

This change introduces reference counts for the mounts, if a directory
is already mounted the mount interface will only increment the mount
counter and return the mount target effectively making sure that the
filesystem doesn't end up in an undefined behavior.

Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
(cherry picked from commit 32d58144fd)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-20 12:54:03 -06:00
Sebastiaan van Stijn
d7aa1e14e5 Merge pull request #45771 from thaJeztah/24.0_backport_fix_docker_py
[24.0 backport] testing: temporarily pin docker-py tests to use "bullseye"
2023-06-20 18:20:00 +02:00
Sebastiaan van Stijn
5652c59647 testing: temporarily pin docker-py tests to use "bullseye"
The official Python images on Docker Hub switched to debian bookworm,
which is now the current stable version of Debian.

However, the location of the apt repository config file changed, which
causes the Dockerfile build to fail;

    Loaded image: emptyfs:latest
    Loaded image ID: sha256:0df1207206e5288f4a989a2f13d1f5b3c4e70467702c1d5d21dfc9f002b7bd43
    INFO: Building docker-sdk-python3:5.0.3...
    tests/Dockerfile:6
    --------------------
       5 |     ARG APT_MIRROR
       6 | >>> RUN sed -ri "s/(httpredir|deb).debian.org/${APT_MIRROR:-deb.debian.org}/g" /etc/apt/sources.list \
       7 | >>>     && sed -ri "s/(security).debian.org/${APT_MIRROR:-security.debian.org}/g" /etc/apt/sources.list
       8 |
    --------------------
    ERROR: failed to solve: process "/bin/sh -c sed -ri \"s/(httpredir|deb).debian.org/${APT_MIRROR:-deb.debian.org}/g\" /etc/apt/sources.list     && sed -ri \"s/(security).debian.org/${APT_MIRROR:-security.debian.org}/g\" /etc/apt/sources.list" did not complete successfully: exit code: 2

This needs to be fixed in docker-py, but in the meantime, we can pin to
the bullseye variant.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 19d860fa9d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-20 11:41:20 +02:00
Bjorn Neergaard
458af2b1e0 Merge pull request #45747 from thaJeztah/24.0_backport_rootlesskit_v1.1.1
[24.0 backport] Rootlesskit v1.1.1
2023-06-15 09:52:27 -06:00
Sebastiaan van Stijn
58729344aa Merge pull request #45745 from thaJeztah/24.0_backport_update_go_1.20.5
[24.0 backport] update go to go1.20.5
2023-06-14 22:20:22 +02:00
Bjorn Neergaard
3d96894184 Merge pull request #45748 from thaJeztah/24.0_backport_copy_uidgid
[24.0 backport] fix docker cp -a failing to access / in container (run `getent` with a noop stdin)
2023-06-14 10:09:30 -06:00
Nicolas De Loof
789a8755b8 run getent with a noop stdin
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
(cherry picked from commit 3cc5d62f8a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-14 13:12:00 +02:00
Jan Garcia
f7298b326e vendor: github.com/sirupsen/logrus v1.9.3
Signed-off-by: Jan Garcia <github-public@n-garcia.com>
(cherry picked from commit 197b0b16e3)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-14 13:08:58 +02:00
Jan Garcia
1c18ad6ca6 vendor: github.com/rootless-containers/rootlesskit v1.1.1
Signed-off-by: Jan Garcia <github-public@n-garcia.com>
(cherry picked from commit 8c4dfc9e6a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-14 13:07:32 +02:00
Jan Garcia
ae4a10df67 update RootlessKit to v1.1.1
Signed-off-by: Jan Garcia <github-public@n-garcia.com>
(cherry picked from commit 0b1c1877c5)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-14 13:05:04 +02:00
Sebastiaan van Stijn
24c882c3e0 update go to go1.20.5
go1.20.5 (released 2023-06-06) includes four security fixes to the cmd/go and
runtime packages, as well as bug fixes to the compiler, the go command, the
runtime, and the crypto/rsa, net, and os packages. See the Go 1.20.5 milestone
on our issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.20.5+label%3ACherryPickApproved

full diff: https://github.com/golang/go/compare/go1.20.4...go1.20.5

These minor releases include 3 security fixes following the security policy:

- cmd/go: cgo code injection
  The go command may generate unexpected code at build time when using cgo. This
  may result in unexpected behavior when running a go program which uses cgo.

  This may occur when running an untrusted module which contains directories with
  newline characters in their names. Modules which are retrieved using the go command,
  i.e. via "go get", are not affected (modules retrieved using GOPATH-mode, i.e.
  GO111MODULE=off, may be affected).

  Thanks to Juho Nurminen of Mattermost for reporting this issue.

  This is CVE-2023-29402 and Go issue https://go.dev/issue/60167.

- runtime: unexpected behavior of setuid/setgid binaries

  The Go runtime didn't act any differently when a binary had the setuid/setgid
  bit set. On Unix platforms, if a setuid/setgid binary was executed with standard
  I/O file descriptors closed, opening any files could result in unexpected
  content being read/written with elevated prilieges. Similarly if a setuid/setgid
  program was terminated, either via panic or signal, it could leak the contents
  of its registers.

  Thanks to Vincent Dehors from Synacktiv for reporting this issue.

  This is CVE-2023-29403 and Go issue https://go.dev/issue/60272.

- cmd/go: improper sanitization of LDFLAGS

  The go command may execute arbitrary code at build time when using cgo. This may
  occur when running "go get" on a malicious module, or when running any other
  command which builds untrusted code. This is can by triggered by linker flags,
  specified via a "#cgo LDFLAGS" directive.

  Thanks to Juho Nurminen of Mattermost for reporting this issue.

  This is CVE-2023-29404 and CVE-2023-29405 and Go issues https://go.dev/issue/60305 and https://go.dev/issue/60306.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 98a44bb18e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-14 12:48:57 +02:00
Akihiro Suda
03a0ee4202 Merge pull request #45699 from vvoland/dockerfile-separate-cli-2-24
[24.0 backport] Dockerfile: Use separate cli for shell and integration-cli
2023-06-12 21:53:14 +09:00
Sebastiaan van Stijn
df620567eb Merge pull request #45708 from neersighted/check_config_bpf/24.0
[24.0 backport] contrib/check-config: require xt_bpf for encrypted overlay
2023-06-07 13:54:38 +02:00
Bjorn Neergaard
b3133d7471 contrib/check-config: move xt_bpf check to overlay section
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 800ea039ec)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-06 16:48:55 -06:00
Bjorn Neergaard
8c552012ae contrib/check-config: check for xt_bpf
We omit xt_u32 as it's optional; since we will remove support for this
module in the future, it's simpler to check for xt_bpf, which will
become the new baseline.

Related issues:
* https://github.com/microsoft/WSL/issues/10029#issuecomment-1574440255
* https://github.com/docker/for-win/issues/13450#issuecomment-1574443139

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 1910fdde81)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-06-06 16:48:50 -06:00
Sebastiaan van Stijn
aa47b29dbc vendor: github.com/moby/swarmkit/v2 v2.0.0-20230531205928-01bb7a41396b
- Fix timeouts from very long raft messages
- fix: code optimization
- update dependencies

full diff: 75e92ce14f...01bb7a4139

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 06aaf87aab)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-05 22:02:53 +02:00
Paweł Gronowski
61d547fd06 Dockerfile: Move dockercli to base-dev
Avoids invalidation of dev-systemd-true and dev-base when changing the
CLI version/repository.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 0f9c8e684a)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-06-05 17:03:27 +02:00
Paweł Gronowski
e5fbc3f75a hack/cli.sh: Quiet origin cleanup
Don't show `error: No such remote: 'origin'` error when building for the
first time and the cached git repository doesn't a remote yet.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 5433b88e2d)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-06-05 17:03:25 +02:00
Paweł Gronowski
1a078977e1 Dockerfile/shell: Install buildx cli plugin
Installs the buildx cli plugin in the container shell by default.
Previously user had to manually download the buildx binary to use
buildkit.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 49f76a34b5)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-06-05 16:47:18 +02:00
Paweł Gronowski
c4198e6053 Dockerfile: Use separate cli for shell and integration-cli
Use separate cli for integration-cli to allow use newer CLI for
interactive dev shell usage.

Both versions can be overriden with DOCKERCLI_VERSION or
DOCKERCLI_INTEGRATION_VERSION. Binary is downloaded from
download.docker.com if it's available, otherwise it's built from the
source.

For backwards compatibility DOCKER_CLI_PATH overrides BOTH clis.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 17c99f7164)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-06-05 16:47:16 +02:00
Bjorn Neergaard
8e70a1b23e Merge pull request #45692 from vvoland/builder-use-moby-exporter-by-default-24
[backport 24.0] builder-next: Set moby exporter as default
2023-06-02 09:22:02 -06:00
Bjorn Neergaard
c671434cd2 Merge pull request #45688 from vvoland/c8d-load-unpack-attestation-24
[24.0 backport] c8d/load: Don't unpack pseudo images
2023-06-02 08:28:20 -06:00
Paweł Gronowski
647ba03224 builder-next: Set moby exporter as default
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit d63569c73d)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-06-02 16:06:11 +02:00
Sebastiaan van Stijn
2f65bb7bb5 Merge pull request #45685 from thaJeztah/24.0_backport_dockerfile_more_link
[24.0 backport] Dockerfile: use COPY --link for source code as well
2023-06-02 15:12:05 +02:00
Paweł Gronowski
961fe27408 c8d/handlers: Handle error in walkPresentChildren
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 4295806736)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-06-02 15:09:28 +02:00
Paweł Gronowski
087cf6f238 c8d/load: Don't unpack pseudo images
Don't unpack image manifests which are not a real images that can't be
unpacked.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 4d3238dc0b)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-06-02 15:09:25 +02:00
Paweł Gronowski
0b9d68f59d c8d/load: Use walkImageManifests
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit b08bff8ba3)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-06-02 15:09:24 +02:00
Paweł Gronowski
cbf0779bfc c8d/list: Use walkImageManifests
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 5210f48bfc)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-06-02 15:09:22 +02:00
Paweł Gronowski
0139309fef c8d: Add walkImageManifests and ImageManifest wrapper
The default implementation of the containerd.Image interface provided by
the containerd operates on the parent index/manifest list of the image
and the platform matcher.

This isn't convenient when a specific manifest is already known and it's
redundant to search the whole index for a manifest that matches the
given platform matcher. It can also result in a different manifest
picked up than expected when multiple manifests with the same platform
are present.

This introduces a walkImageManifests which walks the provided image and
calls a handler with a ImageManifest, which is a simple wrapper that
implements containerd.Image interfaces and performs all containerd.Image
operations against a platform specific manifest instead of the root
manifest list/index.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit fabc1d5bef)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-06-02 15:09:20 +02:00
Sebastiaan van Stijn
18278d3dc1 Merge pull request #45684 from thaJeztah/24.0_backport_c8d_useragent_more_details
[24.0 backport] containerd: add c8d version and storage-driver to User-Agent
2023-06-02 14:35:21 +02:00
Sebastiaan van Stijn
e1c7956764 Dockerfile: use COPY --link for source code as well
I missed the most important COPY in 637ca59375

Copying the source code into the dev-container does not depend on the parent
layers, so can use the --link option as well.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit ff2342154b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-02 13:22:05 +02:00
Sebastiaan van Stijn
4b3329d3dd Merge pull request #45678 from thaJeztah/24.0_backport_fix_snapshotter_change
[24.0 backport] Make sure the image is unpacked for the current snapshotter
2023-06-02 13:17:54 +02:00
Sebastiaan van Stijn
32d442aee1 Merge pull request #45672 from thaJeztah/24.0_backport_bump_zfs
[24.0 backport] vendor: github.com/mistifyio/go-zfs/v3 v3.0.1
2023-06-02 11:48:36 +02:00
Sebastiaan van Stijn
75afe3201b containerd: add c8d version and storage-driver to User-Agent
With this patch, the user-agent has information about the containerd-client
version and the storage-driver that's used when using the containerd-integration;

    time="2023-06-01T11:27:07.959822887Z" level=info msg="listening on [::]:5000" go.version=go1.19.9 instance.id=53590f34-096a-4fd1-9c58-d3b8eb7e5092 service=registry version=2.8.2
    ...
    172.18.0.1 - - [01/Jun/2023:11:30:12 +0000] "HEAD /v2/multifoo/blobs/sha256:c7ec7661263e5e597156f2281d97b160b91af56fa1fd2cc045061c7adac4babd HTTP/1.1" 404 157 "" "docker/dev go/go1.20.4 git-commit/8d67d0c1a8 kernel/5.15.49-linuxkit-pr os/linux arch/arm64 containerd-client/1.6.21+unknown storage-driver/overlayfs UpstreamClient(Docker-Client/24.0.2 \\(linux\\))"

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit d099e47e00)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-02 11:41:10 +02:00
Sebastiaan van Stijn
8018ee4689 dockerversion: DockerUserAgent(): allow custom versions to be passed
Allow additional metadata to be passed as part of the generated User-Agent.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a6da1480b5)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-02 11:41:09 +02:00
Sebastiaan van Stijn
ed376a603f dockerversion: remove insertUpstreamUserAgent()
It was not really "inserting" anything, just formatting and appending.
Simplify this by changing this in to a `getUpstreamUserAgent()` function
which returns the upstream User-Agent (if any) into a `UpstreamClient()`.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 9a1f2e6d7c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-02 11:41:09 +02:00
Sebastiaan van Stijn
1d45ea52f4 dockerversion: simplify escapeStr()
Use a const for the characters to escape, instead of implementing
this as a generic escaping function.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit ff40d2d787)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-02 11:41:09 +02:00
Sebastiaan van Stijn
a27b0381a6 dockerversion: add a basic unit-test
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit eb9a5392bc)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-02 11:41:09 +02:00
Djordje Lukic
1fc19772e0 Make sure the image is unpacked for the current snapshotter
Switching snapshotter implementations would result in an error when
preparing a snapshot, check that the image is indeed unpacked for the
current snapshot before trying to prepare a snapshot.

Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
(cherry picked from commit ed32f5e241)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-01 22:50:53 +02:00
Brian Goff
9bdb6adf92 Merge pull request #45673 from thaJeztah/24.0_backport_consistent_alias
[24.0 backport] fixing consistent aliases for OCI spec imports
2023-06-01 12:34:00 -07:00
Sebastiaan van Stijn
7dbab75fec Merge pull request #45674 from thaJeztah/24.0_backport_dockerfile_copy_link
[24.0 backport] Dockerfile: use COPY --link to copy artifacts from build-stages
2023-06-01 18:37:14 +02:00
Sebastiaan van Stijn
e7b1501832 Merge pull request #45671 from thaJeztah/24.0_backport_c8d_useragent
[24.0 backport] containerd: set user-agent when pushing/pulling images
2023-06-01 18:36:46 +02:00
Sebastiaan van Stijn
4217d9ea0a Dockerfile: use COPY --link to copy artifacts from build-stages
Build-cache for the build-stages themselves are already invalidated if the
base-images they're using is updated, and the COPY operations don't depend
on previous steps (as there's no overlap between artifacts copied).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 637ca59375)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-01 17:29:46 +02:00
Jeyanthinath Muthuram
4c6b8e737f added alias validation
Signed-off-by: Jeyanthinath Muthuram <jeyanthinath10@gmail.com>
(cherry picked from commit 71d7908656)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-01 17:23:07 +02:00
Jeyanthinath Muthuram
e370f224ae fixing consistent aliases for OCI spec imports
Signed-off-by: Jeyanthinath Muthuram <jeyanthinath10@gmail.com>
(cherry picked from commit 307b09e7eb)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-01 17:22:49 +02:00
Sebastiaan van Stijn
ac1a867282 vendor: github.com/mistifyio/go-zfs/v3 v3.0.1
Switching to the v3 version, which was renamed to be compatible with
go modules.

Full diff: https://github.com/mistifyio/go-zfs/compare/f784269be439...v3.0.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 86108812b8)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-01 17:14:33 +02:00
Sebastiaan van Stijn
2949fee1d3 containerd: set user-agent when pushing/pulling images
Before this, the client would report itself as containerd, and the containerd
version from the containerd go module:

    time="2023-06-01T09:43:21.907359755Z" level=info msg="listening on [::]:5000" go.version=go1.19.9 instance.id=67b89d83-eac0-4f85-b36b-b1b18e80bde1 service=registry version=2.8.2
    ...
    172.18.0.1 - - [01/Jun/2023:09:43:33 +0000] "HEAD /v2/multifoo/blobs/sha256:cb269d7c0c1ca22fb5a70342c3ed2196c57a825f94b3f0e5ce3aa8c55baee829 HTTP/1.1" 404 157 "" "containerd/1.6.21+unknown"

With this patch, the user-agent has the docker daemon information;

    time="2023-06-01T11:27:07.959822887Z" level=info msg="listening on [::]:5000" go.version=go1.19.9 instance.id=53590f34-096a-4fd1-9c58-d3b8eb7e5092 service=registry version=2.8.2
    ...
    172.18.0.1 - - [01/Jun/2023:11:27:20 +0000] "HEAD /v2/multifoo/blobs/sha256:c7ec7661263e5e597156f2281d97b160b91af56fa1fd2cc045061c7adac4babd HTTP/1.1" 404 157 "" "docker/dev go/go1.20.4 git-commit/8d67d0c1a8 kernel/5.15.49-linuxkit-pr os/linux arch/arm64 UpstreamClient(Docker-Client/24.0.2 \\(linux\\))"

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 66137ae429)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-01 17:10:08 +02:00
Bjorn Neergaard
7861aa7e80 Merge pull request #45659 from corhere/backport-24.0/libn/setup-resolver-with-verbose-iptables
[24.0 backport] libnetwork: fix resolver restore w/ chatty 'iptables -C'
2023-05-30 15:31:12 -06:00
Bjorn Neergaard
ebe29481ec Merge pull request #45658 from corhere/backport-24.0/libn/fix-embedded-resolver-live-reload
[24.0 backport] libnetwork: fix sandbox restore
2023-05-30 15:30:39 -06:00
Cory Snider
f9c68e5fbc libn: fix resolver restore w/ chatty 'iptables -C'
Resolver.setupIPTable() checks whether it needs to flush or create the
user chains used for NATing container DNS requests by testing for the
existence of the rules which jump to said user chains. Unfortunately it
does so using the IPTable.RawCombinedOutputNative() method, which
returns a non-nil error if the iptables command returns any output even
if the command exits with a zero status code. While that is fine with
iptables-legacy as it prints no output if the rule exists, iptables-nft
v1.8.7 prints some information about the rule. Consequently,
Resolver.setupIPTable() would incorrectly think that the rule does not
exist during container restore and attempt to create it. This happened
work work by coincidence before 8f5a9a741b
because the failure to create the already-existing table would be
ignored and the new NAT rules would be inserted before the stale rules
left in the table from when the container was last started/restored. Now
that failing to create the table is treated as a fatal error, the
incompatibility with iptables-nft is no longer hidden.

Switch to using IPTable.ExistsNative() to test for the existence of the
jump rules as it correctly only checks the iptables command's exit
status without regard for whether it outputs anything.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 1178319313)
Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-05-30 15:49:17 -04:00
Cory Snider
3452a76589 libnetwork: fix sandbox restore
The method to restore a network namespace takes a collection of
interfaces to restore with the options to apply. The interface names are
structured data, tuples of (SrcName, DstPrefix) but for whatever reason
are being passed into Restore() serialized to strings. A refactor,
f0be4d126d, accidentally broke the
serialization by dropping the delimiter. Rather than fix the
serialization and leave the time-bomb for someone else to trip over,
pass the interface names as structured data.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 50eb2d2782)
Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-05-30 15:47:20 -04:00
Cory Snider
fec801a103 libnetwork: log why osl sandbox restore failed
Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 18bf3aa442)
Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-05-30 15:47:20 -04:00
Akihiro Suda
143a25144a Merge pull request #45643 from thaJeztah/24.0_backport_exec_npe
[24.0 backport] Fix npe in exec resize when exec errored
2023-05-29 09:54:07 +09:00
Akihiro Suda
f5899cc1f6 Merge pull request #45633 from thaJeztah/24.0_backport_deprecate_builder_streaming
[24.0 backport] builder/remotecontext: deprecate CachableSource, NewCachableSource
2023-05-29 09:53:47 +09:00
Brian Goff
d9e39914a7 Fix npe in exec resize when exec errored
In cases where an exec start failed the exec process will be nil even
though the channel to signal that the exec started was closed.

Ideally ExecConfig would get a nice refactor to handle this case better
(ie. it's not started so don't close that channel).
This is a minimal fix to prevent NPE. Luckilly this would only get
called by a client and only the http request goroutine gets the panic
(http lib recovers the panic).

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit 487ea81316)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-28 19:06:35 +02:00
Sebastiaan van Stijn
0a59892a88 Merge pull request #45637 from corhere/backport-24.0/libn/fix-encrypted-overlay-nonstandard-port
[24.0 backport] libnetwork/d/overlay: support encryption on any port
2023-05-27 00:45:32 +02:00
Cory Snider
042f0799db libn/d/overlay: support encryption on any port
While the VXLAN interface and the iptables rules to mark outgoing VXLAN
packets for encryption are configured to use the Swarm data path port,
the XFRM policies for actually applying the encryption are hardcoded to
match packets with destination port 4789/udp. Consequently, encrypted
overlay networks do not pass traffic when the Swarm is configured with
any other data path port: encryption is not applied to the outgoing
VXLAN packets and the destination host drops the received cleartext
packets. Use the configured data path port instead of hardcoding port
4789 in the XFRM policies.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 9a692a3802)
Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-05-26 16:41:42 -04:00
Sebastiaan van Stijn
ec8ec9056c builder/remotecontext: deprecate CachableSource, NewCachableSource
This type (as well as TarsumBackup), was used for the experimental --stream
support for the classic builder. This feature was removed in commit
6ca3ec88ae, which also removed uses of
the CachableSource type.

As far as I could find, there's no external consumers of these types,
but let's deprecated it, to give potential users a heads-up that it
will be removed.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 37d4b0bee9)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-26 15:13:27 +02:00
Sebastiaan van Stijn
659604f9ee Merge pull request #45625 from thaJeztah/24.0_backport_serialize_exec_starts_workaround
[24.0 backport] libcontainerd: work around exec start bug in c8d
2023-05-25 23:22:22 +02:00
Sebastiaan van Stijn
6660133ffb Merge pull request #45582 from thaJeztah/24.0_backport_vendor_buildkit_0.11.7_dev
[24.0 backport] vendor: github.com/moby/buildkit v0.11.7-0.20230525183624-798ad6b0ce9f
2023-05-25 23:03:09 +02:00
Sebastiaan van Stijn
67b3563d09 Merge pull request #45623 from vvoland/c8d-inspect-created-time-24
[24.0 backport] c8d/inspect: Fill `Created` time if available
2023-05-25 22:22:34 +02:00
Cory Snider
7a4ea19803 libcontainerd: work around exec start bug in c8d
It turns out that the unnecessary serialization removed in
b75246202a happened to work around a bug
in containerd. When many exec processes are started concurrently in the
same containerd task, it takes seconds to minutes for them all to start.
Add the workaround back in, only deliberately this time.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit fb7ec1555c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-25 22:18:14 +02:00
Sebastiaan van Stijn
ae6e9333c0 vendor: github.com/moby/buildkit v0.11.7-0.20230525183624-798ad6b0ce9f
full diff: https://github.com/moby/buildkit/compare/v0.11.6...798ad6b0ce9f2fe86dfb2b0277e6770d0b545871

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 79ca6630d4)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-25 21:45:42 +02:00
Paweł Gronowski
0d9acd24fe c8d/inspect: Fill Created time if available
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit b9b8b6597a)
2023-05-25 21:28:22 +02:00
Bjorn Neergaard
37bc639704 Merge pull request #45620 from thaJeztah/24.0_backport_update_go_runc_v1.1.0
[24.0 backport] vendor: github.com/containerd/go-runc v1.1.0
2023-05-25 13:14:38 -06:00
Sebastiaan van Stijn
04eccf8165 vendor: github.com/containerd/go-runc v1.1.0
full diff: https://github.com/containerd/go-runc/compare/v1.0.0...v1.1.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 3512b04093)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-25 19:01:26 +02:00
Sebastiaan van Stijn
24722779ff Merge pull request #45616 from thaJeztah/24.0_backport_lock_in_snapshotter_setting
[24.0 backport] daemon: lock in snapshotter setting at daemon init
2023-05-25 15:49:53 +02:00
Sebastiaan van Stijn
9d8acb7bd1 Merge pull request #45612 from vvoland/dangling-image-repotagsdigests-test-24
[24.0 backport] integration: Add TestImageInspectEmptyTagsAndDigests
2023-05-25 15:09:50 +02:00
Bjorn Neergaard
4b78458e4b Merge pull request #45613 from thaJeztah/24.0_backport_skip_criu
[24.0 backport] Dockerfile: temporarily skip CRIU stage
2023-05-25 07:03:50 -06:00
Cory Snider
d64bab35ee daemon: lock in snapshotter setting at daemon init
Feature flags are one of the configuration items which can be reloaded
without restarting the daemon. Whether the daemon uses the containerd
snapshotter service or the legacy graph drivers is controlled by a
feature flag. However, much of the code which checks the snapshotter
feature flag assumes that the flag cannot change at runtime. Make it so
that the snapshotter setting can only be changed by restarting the
daemon, even if the flag state changes after a live configuration
reload.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 9b9c5242eb)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-25 12:47:59 +02:00
Sebastiaan van Stijn
329d671aef Dockerfile: temporarily skip CRIU stage
The package repository currently has issues;

    => ERROR https://download.opensuse.org/repositories/devel:/tools:/criu/Debian_11/Release.key

The only test currently using this binary is currently skipped, as the test
was broken;
6e98a7f2c9/integration/container/checkpoint_test.go (L32-L33)

So let's disable this stage for the time being.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit d3d2823edf)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-25 12:20:05 +02:00
Paweł Gronowski
4cc2081119 integration: Add TestImageInspectEmptyTagsAndDigests
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 6506579e18)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-05-25 09:49:01 +02:00
Paweł Gronowski
27df42255c hack: Rename .ensure-emptyfs to .build-empty-images
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit a93aadc2e6)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-05-25 09:48:58 +02:00
Paweł Gronowski
9ee7d30aef hack/ensure-emptyfs: Create dangling image
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 3a31f81838)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-05-25 09:48:56 +02:00
Sebastiaan van Stijn
8a4b7c5af8 Add testenv.UsingSnapshotter utility
To allow skipping integration tests that don't apply to the
containerd snapshotter.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 4373547857)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-05-25 09:48:54 +02:00
Sebastiaan van Stijn
7d50989467 Merge pull request #45604 from neersighted/backport/45603/24.0
[24.0 backport] hack/make/.binary: don't use "netgo" when building Windows binaries
2023-05-24 21:28:06 +02:00
Sebastiaan van Stijn
a753ca64e2 hack/make/.binary: don't use "netgo" when building Windows binaries
Starting with go1.19, the Go runtime on Windows now supports the `netgo` build-
flag to use a native Go DNS resolver. Prior to that version, the build-flag
only had an effect on non-Windows platforms. When using the `netgo` build-flag,
the Windows's host resolver is not used, and as a result, custom entries in
`etc/hosts` are ignored, which is a change in behavior from binaries compiled
with older versions of the Go runtime.

From the go1.19 release notes: https://go.dev/doc/go1.19#net

> Resolver.PreferGo is now implemented on Windows and Plan 9. It previously
> only worked on Unix platforms. Combined with Dialer.Resolver and Resolver.Dial,
> it's now possible to write portable programs and be in control of all DNS name
> lookups when dialing.
>
> The net package now has initial support for the netgo build tag on Windows.
> When used, the package uses the Go DNS client (as used by Resolver.PreferGo)
> instead of asking Windows for DNS results. The upstream DNS server it discovers
> from Windows may not yet be correct with complex system network configurations,
> however.

Our Windows binaries are compiled with the "static" (`make/binary-daemon`)
script, which has the `netgo` option set by default. This patch unsets the
`netgo` option when cross-compiling for Windows.

Co-authored-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
(cherry picked from commit 53d1b12bc0)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-05-24 10:47:59 -06:00
Sebastiaan van Stijn
ac1c329245 Merge pull request #45602 from vvoland/c8d-exists-24
[backport 24.0] c8d/pull: Use same progress action as distribution
2023-05-24 15:46:15 +02:00
Paweł Gronowski
5276c2b6e0 c8d/pull: Use same progress action as distribution
Docker with containerd integration emits "Exists" progress action when a
layer of the currently pulled image already exists. This is different
from the non-c8d Docker which emits "Already exists".

This makes both implementations consistent by emitting backwards
compatible "Already exists" action.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit a7bc65fbd8)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-05-24 13:03:15 +02:00
Sebastiaan van Stijn
1b0d37bdc2 Merge pull request #45598 from corhere/backport-24.0/fix-flaky-resolver-test
[24.0 backport] libnetwork/osl: restore the right thread's netns
2023-05-23 19:15:38 +02:00
Cory Snider
baf1fd1c3f libnetwork: check for netns leaks from prior tests
TestProxyNXDOMAIN has proven to be susceptible to failing as a
consequence of unlocked threads being set to the wrong network
namespace. As the failure mode looks a lot like a bug in the test
itself, it seems prudent to add a check for mismatched namespaces to the
test so we will know for next time that the root cause lies elsewhere.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 871cf72363)
Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-05-23 11:31:28 -04:00
Cory Snider
992dc33fc5 libnetwork/osl: restore the right thread's netns
osl.setIPv6 mistakenly captured the calling goroutine's thread's network
namespace instead of the network namespace of the thread getting its
namespace temporarily changed. As this function appears to only be
called from contexts in the process's initial network namespace, this
mistake would be of little consequence at runtime. The libnetwork unit
tests, on the other hand, unshare network namespaces so as not to
interfere with each other or the host's network namespace. But due to
this bug, the isolation backfires and the network namespace of
goroutines used by a test which are expected to be in the initial
network namespace can randomly become the isolated network namespace of
some other test. Symptoms include a loopback network server running in
one goroutine being inexplicably and randomly being unreachable by a
client in another goroutine.

Capture the original network namespace of the thread from the thread to
be tampered with, after locking the goroutine to the thread.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 6d79864135)
Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-05-23 11:31:28 -04:00
Cory Snider
ef1545ed4a libnetwork: leave global logger alone in tests
Swapping out the global logger on the fly is causing tests to flake out
by logging to a test's log output after the test function has returned.
Refactor Resolver to use a dependency-injected logger and the resolver
unit tests to inject a private logger instance into the Resolver under
test.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit d4f3858a40)
Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-05-23 11:31:28 -04:00
Cory Snider
876f5eda51 libnetwork: make resolver tests less confusing
tstwriter mocks the server-side connection between the resolver and the
container, not the resolver and the external DNS server, so returning
the external DNS server's address as w.LocalAddr() is technically
incorrect and misleading. Only the protocols need to match as the
resolver uses the client's choice of protocol to determine which
protocol to use when forwarding the query to the external DNS server.
While this change has no material impact on the tests, it makes the
tests slightly more comprehensible for the next person.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 0cc6e445d7)
Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-05-23 11:31:28 -04:00
Bjorn Neergaard
463850e59e Merge pull request #45588 from vvoland/c8d-layerless-24
[24.0 backport] c8d/list: Show layerless images
2023-05-19 11:18:19 -06:00
Paweł Gronowski
47a3dad256 c8d/list: Show layerless images
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 34964c2454)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-05-19 18:23:14 +02:00
Sebastiaan van Stijn
a0bc3ebae4 Merge pull request #45571 from thaJeztah/24.0_backport_fix_insecure_registries_reload
[24.0 backport] Fix insecure registries reload
2023-05-19 10:51:27 +02:00
Sebastiaan van Stijn
922b6aa672 Merge pull request #45568 from corhere/backport-24.0/fix-empty-container-decode
[24.0 backport] api/server: allow empty body for POST /commit again
2023-05-19 01:44:04 +02:00
Sebastiaan van Stijn
0e605cf972 Merge pull request #45573 from thaJeztah/24.0_backport_fix_dns_servfail
[24.0 backport] libnetwork: just forward the external DNS response
2023-05-19 00:18:25 +02:00
Sebastiaan van Stijn
878c41791b Merge pull request #45560 from crazy-max/24.0_backport_fix-worker-id
[24.0 backport] build: use daemon id as worker id for the graph driver controller
2023-05-18 23:59:55 +02:00
Bjorn Neergaard
654e80abc2 Merge pull request #45570 from crazy-max/24.0_backport_ci-bin-image-distribute
[24.0 backport] ci(bin-image): distribute build across runners
2023-05-18 22:36:49 +01:00
Cory Snider
0869b089e4 libnetwork: just forward the external DNS response
Our resolver is just a forwarder for external DNS so it should act like
it. Unless it's a server failure or refusal, take the response at face
value and forward it along to the client. RFC 8020 is only applicable to
caching recursive name servers and our resolver is neither caching nor
recursive.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 41356227f2)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-18 23:10:21 +02:00
Nolan Miles
3467ba6451 reorder load funcs to match newServiceConfig()'s order
Signed-off-by: Nolan Miles <nolanpmiles@gmail.com>
(cherry picked from commit f3645a2aa3)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-18 23:03:47 +02:00
Nolan Miles
f9b886c01b add mirror to daemon reload test for insecure registries
Signed-off-by: Nolan Miles <nolanpmiles@gmail.com>
(cherry picked from commit 3b15156e4d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-18 23:03:44 +02:00
Kevin Alvarez
07140c0eca build: use daemon id as worker id for the graph driver controller
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 6d139e5e95)
2023-05-18 22:29:45 +02:00
Kevin Alvarez
d5ad186d49 ci(bin-image): distribute build across runners
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 668af4be82)
2023-05-18 22:25:52 +02:00
Cory Snider
4d924c35f7 api/server: allow empty body for POST /commit again
The error returned by DecodeConfig was changed in
b6d58d749c and caused this to regress.
Allow empty request bodies for this endpoint once again.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 967c7bc5d3)
Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-05-18 16:06:57 -04:00
Brian Goff
ea662c5c8a Merge pull request #45564 from vvoland/fix-45556-24
[24.0 backport] api/inspect: Fix nil RepoTags and RepoDigests
2023-05-18 11:32:14 -07:00
Paweł Gronowski
68b7ba0d03 api/inspect: Fix nil RepoTags and RepoDigests
Make RepoTags and RepoDigests empty arrays instead of nil.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 1be26e9f0c)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-05-18 16:00:13 +02:00
Sebastiaan van Stijn
821e4ec4c7 Merge pull request #45562 from laurazard/fix-pull-platform-backport
[24.0 backport] fix: `docker pull` with platform checks wrong image tag
2023-05-18 15:42:01 +02:00
Laura Brehm
5ea7b8d091 fix: docker pull with platform checks wrong image tag
This fixes a bug where, if a user pulls an image with a tag != `latest` and
a specific platform, we return an NotFound error for the wrong (`latest`) tag.
see: https://github.com/moby/moby/issues/45558

This bug was introduced in 779a5b3029
in the changes to `daemon/images/image_pull.go`, when we started returning the error from the call to
`GetImage` after the pull. We do this call, if pulling with a specified platform, to check if the platform
of the pulled image matches the requested platform (for cases with single-arch images).
However, when we call `GetImage` we're not passing the image tag, only name, so `GetImage` assumes `latest`
which breaks when the user has requested a different tag, since there might not be such an image in the store.

Signed-off-by: Laura Brehm <laurabrehm@hey.com>
(cherry picked from commit f450ea64e6)
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2023-05-18 13:40:07 +01:00
Sebastiaan van Stijn
1331b8c39a Merge pull request #45537 from thaJeztah/24.0_backport_containerd_binary_1.7.1
[24.0 backport] update containerd binary to v1.7.1
2023-05-15 15:40:33 +01:00
Sebastiaan van Stijn
907f037141 update containerd binary to v1.7.1
full diff: https://github.com/containerd/containerd/compare/v1.7.0...v1.7.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 484785456c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-15 12:53:28 +01:00
Akihiro Suda
a5b597ea51 Merge pull request #45531 from rumpl/24.0_backport_fix-empty-auth-pull
[24.0 backport] c8d: The authorizer needs to be set even if AuthConfig is empty
2023-05-12 19:02:16 +09:00
Djordje Lukic
8bbfa32741 c8d: The authorizer needs to be set even if AuthConfig is empty
Without the authorizer pulling will fail if the user is not logged-in

Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
2023-05-12 09:47:32 +02:00
Sebastiaan van Stijn
807e415260 Merge pull request #45526 from laurazard/backport-classic-builder
[24.0 backport] c8d: implement classic builder
2023-05-11 21:12:01 +02:00
Laura Brehm
8587a1c617 c8d/builder: implement cache
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
(cherry picked from commit bd6868557d)
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2023-05-11 19:13:51 +01:00
Laura Brehm
9717369913 c8d: implement classic builder
Co-authored-by: Djordje Lukic <djordje.lukic@docker.com>
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
(cherry picked from commit e46674b6a7)
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2023-05-11 19:13:13 +01:00
Sebastiaan van Stijn
ed0c147c8f Merge pull request #45523 from thaJeztah/24.0_backport_cleanup_reexec_inits
[24.0 backport] [chore] clean up reexec.Init() calls
2023-05-11 19:00:48 +02:00
Sebastiaan van Stijn
90be9ab802 Merge pull request #45525 from thaJeztah/24.0_backport_c8d_authconfig_default
[24.0 backport] c8d: Better handling of partially filled AuthConfig
2023-05-11 18:59:44 +02:00
Sebastiaan van Stijn
d73f7031e0 Merge pull request #45521 from thaJeztah/24.0_backport_vendor_distribution_v2.8.2
[24.0 backport] vendor: github.com/docker/distribution v2.8.2
2023-05-11 18:54:21 +02:00
Sebastiaan van Stijn
ea7f7f168e Merge pull request #45522 from crazy-max/24.0_backport_bin-image
[24.0 backport] bin-image bake target
2023-05-11 18:07:56 +02:00
Paweł Gronowski
233c49438b c8d: Don't create authorizer for empty AuthConfig
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 3309e45ca1)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-11 17:44:06 +02:00
Paweł Gronowski
2b7424512a c8d/authorizer: Default to docker.io
When the `ServerAddress` in the `AuthConfig` provided by the client is
empty, default to the default registry (registry-1.docker.io).

This makes the behaviour the same as with the containerd image store
integration disabled.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 2ad499f93e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-11 17:43:46 +02:00
Cory Snider
f77a3274b4 [chore] clean up reexec.Init() calls
Now that most uses of reexec have been replaced with non-reexec
solutions, most of the reexec.Init() calls peppered throughout the test
suites are unnecessary. Furthermore, most of the reexec.Init() calls in
test code neglects to check the return value to determine whether to
exit, which would result in the reexec'ed subprocesses proceeding to run
the tests, which would reexec another subprocess which would proceed to
run the tests, recursively. (That would explain why every reexec
callback used to unconditionally call os.Exit() instead of returning...)

Remove unneeded reexec.Init() calls from test and example code which no
longer needs it, and fix the reexec.Init() calls which are not inert to
exit after a reexec callback is invoked.

Signed-off-by: Cory Snider <csnider@mirantis.com>
(cherry picked from commit 4e0319c878)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-11 16:31:41 +02:00
CrazyMax
c76bb6a3a3 ci: bin-image workflow
This workflow will just build the bin-image bake target.

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 135d8f04f9)
2023-05-11 16:30:53 +02:00
Kevin Alvarez
71846e82c1 bin-image bake target
Allows to build a non-runnable image that contains bundles.

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit ae1ca67178)
2023-05-11 16:30:53 +02:00
Sebastiaan van Stijn
ecbc27aa22 vendor: github.com/docker/distribution v2.8.2
CI

- Dockerfile: fix filenames of artifacts

Bugfixes

-  Fix panic in inmemory driver
-  Add code to handle pagination of parts. Fixes max layer size of 10GB bug
-  Parse http forbidden as denied
-  Revert "registry/client: set Accept: identity header when getting layers

Runtime

- Update to go1.19.9
- Dockerfile: update xx to v1.2.1 ([#3907](https://github.com/distribution/distribution/pull/3907))

Security

- Fix [CVE-2022-28391](https://www.cve.org/CVERecord?id=CVE-2022-28391) by bumping alpine from 3.14 to 3.16
- Fix [CVE-2023-2253](https://www.cve.org/CVERecord?id=CVE-2023-2253) runaway allocation on /v2/_catalog [`521ea3d9`](521ea3d973)

full diff: https://github.com/docker/distribution/compare/v2.8.1...v2.8.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

bump to release/2.8

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 7821d2d788)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-11 16:26:51 +02:00
Sebastiaan van Stijn
c01f02cfcb Merge pull request #45515 from laurazard/cherry-pick-image-delete
[24.0 backport] c8d: implement missing image delete logic
2023-05-10 22:16:18 +02:00
Sebastiaan van Stijn
ce79cd19f6 Merge pull request #45514 from laurazard/cherry-pick-dangling-history
[24.0 backport] c8d: image history – handle dangling images
2023-05-10 21:29:20 +02:00
Laura Brehm
1235338836 c8d: implement missing image delete logic
Ports over all the previous image delete logic, such as:
- Introduce `prune` and `force` flags
- Introduce the concept of hard and soft image delete conflics, which represent:
  - image referenced in multiple tags (soft conflict)
  - image being used by a stopped container (soft conflict)
  - image being used by a running container (hard conflict)
- Implement delete logic such as:
  - if deleting by reference, and there are other references to the same image, just
    delete the passed reference
  - if deleting by reference, and there is only 1 reference and the image is being used
    by a running container, throw an error if !force, or delete the reference and create
    a dangling reference otherwise
  - if deleting by imageID, and force is true, remove all tags (otherwise soft conflict)
  - if imageID, check if stopped container is using the image (soft conflict), and
    delete anyway if force
  - if imageID was passed in, check if running container is using the image (hard conflict)
  - if `prune` is true, and the image being deleted has dangling parents, remove them

This commit also implements logic to get image parents in c8d by comparing shared layers.

Signed-off-by: Laura Brehm <laurabrehm@hey.com>
(cherry picked from commit cad97135b3)
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2023-05-10 17:52:42 +01:00
Laura Brehm
763d2b7996 c8d: fix image history for dangling images
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
(cherry picked from commit 4603b6d6b6)
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2023-05-10 15:03:26 +01:00
Sebastiaan van Stijn
e9eff01dca Merge pull request #45500 from thaJeztah/24.0_backport_apparmore_cleanups
[24.0 backport] remove remaining uses of apparmor_parser version in apparmor packages
2023-05-10 09:06:28 +02:00
Sebastiaan van Stijn
69ef9a7f90 Merge pull request #45502 from laurazard/backport-c8d-image-history
[24.0 backport] Backport c8d image history
2023-05-09 23:39:32 +02:00
Laura Brehm
86770904be c8d: fix missing image history
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
(cherry picked from commit e8be792130)
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2023-05-09 18:10:06 +01:00
Sebastiaan van Stijn
31b98f9502 Merge pull request #45494 from thaJeztah/24.0_backport_execDuration_in_containerExit
[24.0 backport] daemon: handleContainerExit(): add execDuration in attributes
2023-05-09 17:00:29 +02:00
Sebastiaan van Stijn
bfffb0974e pkg/aaparser: deprecate GetVersion, as it's no longer used
Our templates no longer contain version-specific rules, so this function
is no longer used. This patch deprecates it.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit e3e715666f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-09 16:49:45 +02:00
Sebastiaan van Stijn
e28bc0d271 profiles/apparmor: remove use of aaparser.GetVersion()
commit 7008a51449 removed version-conditional
rules from the template, so we no longer need the apparmor_parser Version.

This patch removes the call to `aaparser.GetVersion()`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit ecaab085db)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-09 16:48:58 +02:00
Sebastiaan van Stijn
d169a57306 contrib/apparmor: remove remaining version-conditionals (< 2.9) from template
Commit 2e19a4d56b removed all other version-
conditional statements from the AppArmor template, but left this one in place.

These conditions were added in 8cf89245f5
to account for old versions of debian/ubuntu (apparmor_parser < 2.9)
that lacked some options;

> This allows us to use the apparmor profile we have in contrib/apparmor/
> and solves the problems where certain functions are not apparent on older
> versions of apparmor_parser on debian/ubuntu.

Those patches were from 2015/2016, and all currently supported distro
versions should now have more current versions than that. Looking at the
oldest supported versions;

Ubuntu 18.04 "Bionic":

    apparmor_parser --version
    AppArmor parser version 2.12
    Copyright (C) 1999-2008 Novell Inc.
    Copyright 2009-2012 Canonical Ltd.

Debian 10 "Buster"

    apparmor_parser --version
    AppArmor parser version 2.13.2
    Copyright (C) 1999-2008 Novell Inc.
    Copyright 2009-2018 Canonical Ltd.

This patch removes the remaining conditionals.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit f445ee1e6c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-09 16:48:45 +02:00
Dorin Geman
63640838ba daemon: handleContainerExit(): add execDuration in attributes
Add `execDuration` field to the event attributes map. This is useful for tracking how long the container ran.

Signed-off-by: Dorin Geman <dorin.geman@docker.com>
(cherry picked from commit 2ad37e1832)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-08 13:45:01 +02:00
Sebastiaan van Stijn
269e55a915 Merge pull request #45483 from thaJeztah/24.0_backport_docs_api_fix_missing_endpoint
[24.0 backport] docs/api: version-history: also mention /system/df for VirtualSize
2023-05-08 11:04:22 +02:00
Sebastiaan van Stijn
012dd239ce docs/api: version-history: also mention /system/df for VirtualSize
Commit 1261fe69a3 deprecated the VirtualSize
field, but forgot to mention that it's also included in the /system/df
endpoint.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit fdc7a78652)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-06 16:31:44 +02:00
660 changed files with 28792 additions and 9232 deletions

View File

@@ -13,7 +13,7 @@ runs:
shell: bash
- run: |
if [ ! -e /etc/docker/daemon.json ]; then
echo '{}' | tee /etc/docker/daemon.json >/dev/null
echo '{}' | sudo tee /etc/docker/daemon.json >/dev/null
fi
DOCKERD_CONFIG=$(jq '.+{"experimental":true,"live-restore":true,"ipv6":true,"fixed-cidr-v6":"2001:db8:1::/64"}' /etc/docker/daemon.json)
sudo tee /etc/docker/daemon.json <<<"$DOCKERD_CONFIG" >/dev/null

View File

@@ -15,7 +15,7 @@ on:
default: false
env:
GO_VERSION: "1.20.4"
GO_VERSION: "1.20.10"
GOTESTLIST_VERSION: v0.3.1
TESTSTAT_VERSION: v0.1.3
WINDOWS_BASE_IMAGE: mcr.microsoft.com/windows/servercore

181
.github/workflows/bin-image.yml vendored Normal file
View File

@@ -0,0 +1,181 @@
name: bin-image
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
workflow_dispatch:
push:
branches:
- 'master'
- '[0-9]+.[0-9]+'
tags:
- 'v*'
pull_request:
env:
MOBYBIN_REPO_SLUG: moby/moby-bin
DOCKER_GITCOMMIT: ${{ github.sha }}
VERSION: ${{ github.ref }}
PLATFORM: Moby Engine - Nightly
PRODUCT: moby-bin
PACKAGER_NAME: The Moby Project
jobs:
validate-dco:
uses: ./.github/workflows/.dco.yml
prepare:
runs-on: ubuntu-20.04
outputs:
platforms: ${{ steps.platforms.outputs.matrix }}
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: |
${{ env.MOBYBIN_REPO_SLUG }}
### versioning strategy
## push semver tag v23.0.0
# moby/moby-bin:23.0.0
# moby/moby-bin:latest
## push semver prelease tag v23.0.0-beta.1
# moby/moby-bin:23.0.0-beta.1
## push on master
# moby/moby-bin:master
## push on 23.0 branch
# moby/moby-bin:23.0
## any push
# moby/moby-bin:sha-ad132f5
tags: |
type=semver,pattern={{version}}
type=ref,event=branch
type=ref,event=pr
type=sha
-
name: Rename meta bake definition file
run: |
mv "${{ steps.meta.outputs.bake-file }}" "/tmp/bake-meta.json"
-
name: Upload meta bake definition
uses: actions/upload-artifact@v3
with:
name: bake-meta
path: /tmp/bake-meta.json
if-no-files-found: error
retention-days: 1
-
name: Create platforms matrix
id: platforms
run: |
echo "matrix=$(docker buildx bake bin-image-cross --print | jq -cr '.target."bin-image-cross".platforms')" >>${GITHUB_OUTPUT}
build:
runs-on: ubuntu-20.04
needs:
- validate-dco
- prepare
strategy:
fail-fast: false
matrix:
platform: ${{ fromJson(needs.prepare.outputs.platforms) }}
steps:
-
name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
-
name: Download meta bake definition
uses: actions/download-artifact@v3
with:
name: bake-meta
path: /tmp
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
if: github.event_name != 'pull_request' && github.repository == 'moby/moby'
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_MOBYBIN_USERNAME }}
password: ${{ secrets.DOCKERHUB_MOBYBIN_TOKEN }}
-
name: Build
id: bake
uses: docker/bake-action@v3
with:
files: |
./docker-bake.hcl
/tmp/bake-meta.json
targets: bin-image
set: |
*.platform=${{ matrix.platform }}
*.output=type=image,name=${{ env.MOBYBIN_REPO_SLUG }},push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' && github.repository == 'moby/moby' }}
*.tags=
-
name: Export digest
if: github.event_name != 'pull_request' && github.repository == 'moby/moby'
run: |
mkdir -p /tmp/digests
digest="${{ fromJSON(steps.bake.outputs.metadata)['bin-image']['containerimage.digest'] }}"
touch "/tmp/digests/${digest#sha256:}"
-
name: Upload digest
if: github.event_name != 'pull_request' && github.repository == 'moby/moby'
uses: actions/upload-artifact@v3
with:
name: digests
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
runs-on: ubuntu-20.04
if: github.event_name != 'pull_request' && github.repository == 'moby/moby'
needs:
- build
steps:
-
name: Download meta bake definition
uses: actions/download-artifact@v3
with:
name: bake-meta
path: /tmp
-
name: Download digests
uses: actions/download-artifact@v3
with:
name: digests
path: /tmp/digests
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_MOBYBIN_USERNAME }}
password: ${{ secrets.DOCKERHUB_MOBYBIN_TOKEN }}
-
name: Create manifest list and push
working-directory: /tmp/digests
run: |
set -x
docker buildx imagetools create $(jq -cr '.target."docker-metadata-action".tags | map("-t " + .) | join(" ")' /tmp/bake-meta.json) \
$(printf '${{ env.MOBYBIN_REPO_SLUG }}@sha256:%s ' *)
-
name: Inspect image
run: |
set -x
docker buildx imagetools inspect ${{ env.MOBYBIN_REPO_SLUG }}:$(jq -cr '.target."docker-metadata-action".args.DOCKER_META_VERSION' /tmp/bake-meta.json)

View File

@@ -13,6 +13,7 @@ on:
pull_request:
env:
GO_VERSION: "1.20.10"
DESTDIR: ./build
jobs:
@@ -47,8 +48,6 @@ jobs:
test:
runs-on: ubuntu-20.04
timeout-minutes: 120
env:
BUILDKIT_REPO: moby/buildkit
needs:
- build
strategy:
@@ -82,7 +81,7 @@ jobs:
-
name: BuildKit ref
run: |
echo "BUILDKIT_REF=$(./hack/buildkit-ref)" >> $GITHUB_ENV
echo "$(./hack/buildkit-ref)" >> $GITHUB_ENV
working-directory: moby
-
name: Checkout BuildKit ${{ env.BUILDKIT_REF }}
@@ -106,7 +105,7 @@ jobs:
-
name: Update daemon.json
run: |
sudo rm /etc/docker/daemon.json
sudo rm -f /etc/docker/daemon.json
sudo service docker restart
docker version
docker info

View File

@@ -15,7 +15,7 @@ on:
pull_request:
env:
GO_VERSION: "1.20.4"
GO_VERSION: "1.20.10"
GOTESTLIST_VERSION: v0.3.1
TESTSTAT_VERSION: v0.1.3
ITG_CLI_MATRIX_SIZE: 6
@@ -166,6 +166,7 @@ jobs:
unit-report:
runs-on: ubuntu-20.04
timeout-minutes: 10
if: always()
needs:
- unit
@@ -354,6 +355,7 @@ jobs:
integration-report:
runs-on: ubuntu-20.04
timeout-minutes: 10
if: always()
needs:
- integration
@@ -482,6 +484,7 @@ jobs:
integration-cli-report:
runs-on: ubuntu-20.04
timeout-minutes: 10
if: always()
needs:
- integration-cli

View File

@@ -422,6 +422,6 @@ The rules:
guidelines. Since you've read all the rules, you now know that.
If you are having trouble getting into the mood of idiomatic Go, we recommend
reading through [Effective Go](https://golang.org/doc/effective_go.html). The
[Go Blog](https://blog.golang.org) is also a great resource. Drinking the
reading through [Effective Go](https://go.dev/doc/effective_go). The
[Go Blog](https://go.dev/blog/) is also a great resource. Drinking the
kool-aid is a lot easier than going thirsty.

View File

@@ -1,12 +1,18 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.20.4
ARG GO_VERSION=1.20.10
ARG BASE_DEBIAN_DISTRO="bullseye"
ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}"
ARG XX_VERSION=1.2.1
ARG VPNKIT_VERSION=0.5.0
ARG DOCKERCLI_VERSION=v17.06.2-ce
ARG DOCKERCLI_REPOSITORY="https://github.com/docker/cli.git"
ARG DOCKERCLI_VERSION=v24.0.2
# cli version used for integration-cli tests
ARG DOCKERCLI_INTEGRATION_REPOSITORY="https://github.com/docker/cli.git"
ARG DOCKERCLI_INTEGRATION_VERSION=v17.06.2-ce
ARG BUILDX_VERSION=0.11.2
ARG SYSTEMD="false"
ARG DEBIAN_FRONTEND=noninteractive
@@ -27,8 +33,7 @@ FROM --platform=$BUILDPLATFORM ${GOLANG_IMAGE} AS base
COPY --from=xx / /
RUN echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
ARG APT_MIRROR
RUN sed -ri "s/(httpredir|deb).debian.org/${APT_MIRROR:-deb.debian.org}/g" /etc/apt/sources.list \
&& sed -ri "s/(security).debian.org/${APT_MIRROR:-security.debian.org}/g" /etc/apt/sources.list
RUN test -n "$APT_MIRROR" && sed -ri "s#(httpredir|deb|security).debian.org#${APT_MIRROR}#g" /etc/apt/sources.list || true
ARG DEBIAN_FRONTEND
RUN apt-get update && apt-get install --no-install-recommends -y file
ENV GO111MODULE=off
@@ -192,7 +197,7 @@ RUN git init . && git remote add origin "https://github.com/containerd/container
# When updating the binary version you may also need to update the vendor
# version to pick up bug fixes or new APIs, however, usually the Go packages
# are built from a commit from the master branch.
ARG CONTAINERD_VERSION=v1.7.0
ARG CONTAINERD_VERSION=v1.7.6
RUN git fetch -q --depth 1 origin "${CONTAINERD_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD
FROM base AS containerd-build
@@ -223,7 +228,7 @@ FROM binary-dummy AS containerd-windows
FROM containerd-${TARGETOS} AS containerd
FROM base AS golangci_lint
ARG GOLANGCI_LINT_VERSION=v1.51.2
ARG GOLANGCI_LINT_VERSION=v1.54.2
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
GOBIN=/build/ GO111MODULE=on go install "github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCI_LINT_VERSION}" \
@@ -243,34 +248,29 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
GOBIN=/build/ GO111MODULE=on go install "mvdan.cc/sh/v3/cmd/shfmt@${SHFMT_VERSION}" \
&& /build/shfmt --version
# dockercli
FROM base AS dockercli-src
WORKDIR /tmp/dockercli
RUN git init . && git remote add origin "https://github.com/docker/cli.git"
ARG DOCKERCLI_VERSION
RUN git fetch -q --depth 1 origin "${DOCKERCLI_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD
RUN [ -d ./components/cli ] && mv ./components/cli /usr/src/dockercli || mv /tmp/dockercli /usr/src/dockercli
WORKDIR /usr/src/dockercli
FROM base AS dockercli
WORKDIR /go/src/github.com/docker/cli
ARG DOCKERCLI_REPOSITORY
ARG DOCKERCLI_VERSION
ARG DOCKERCLI_CHANNEL=stable
ARG TARGETPLATFORM
RUN xx-apt-get install -y --no-install-recommends gcc libc6-dev
RUN --mount=from=dockercli-src,src=/usr/src/dockercli,rw \
--mount=type=cache,target=/root/.cache/go-build,id=dockercli-build-$TARGETPLATFORM <<EOT
set -e
DOWNLOAD_URL="https://download.docker.com/linux/static/${DOCKERCLI_CHANNEL}/$(xx-info march)/docker-${DOCKERCLI_VERSION#v}.tgz"
if curl --head --silent --fail "${DOWNLOAD_URL}" 1>/dev/null 2>&1; then
mkdir /build
curl -Ls "${DOWNLOAD_URL}" | tar -xz docker/docker
mv docker/docker /build/docker
else
CGO_ENABLED=0 xx-go build -o /build/docker ./cmd/docker
fi
xx-verify /build/docker
EOT
RUN --mount=source=hack/dockerfile/cli.sh,target=/download-or-build-cli.sh \
--mount=type=cache,id=dockercli-git-$TARGETPLATFORM,sharing=locked,target=./.git \
--mount=type=cache,target=/root/.cache/go-build,id=dockercli-build-$TARGETPLATFORM \
rm -f ./.git/*.lock \
&& /download-or-build-cli.sh ${DOCKERCLI_VERSION} ${DOCKERCLI_REPOSITORY} /build \
&& /build/docker --version
FROM base AS dockercli-integration
WORKDIR /go/src/github.com/docker/cli
ARG DOCKERCLI_INTEGRATION_REPOSITORY
ARG DOCKERCLI_INTEGRATION_VERSION
ARG TARGETPLATFORM
RUN --mount=source=hack/dockerfile/cli.sh,target=/download-or-build-cli.sh \
--mount=type=cache,id=dockercli-git-$TARGETPLATFORM,sharing=locked,target=./.git \
--mount=type=cache,target=/root/.cache/go-build,id=dockercli-build-$TARGETPLATFORM \
rm -f ./.git/*.lock \
&& /download-or-build-cli.sh ${DOCKERCLI_INTEGRATION_VERSION} ${DOCKERCLI_INTEGRATION_REPOSITORY} /build \
&& /build/docker --version
# runc
FROM base AS runc-src
@@ -280,7 +280,7 @@ RUN git init . && git remote add origin "https://github.com/opencontainers/runc.
# 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. When updating RUNC_VERSION,
# consider updating runc in vendor.mod accordingly.
ARG RUNC_VERSION=v1.1.7
ARG RUNC_VERSION=v1.1.9
RUN git fetch -q --depth 1 origin "${RUNC_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD
FROM base AS runc-build
@@ -368,8 +368,8 @@ RUN --mount=from=rootlesskit-src,src=/usr/src/rootlesskit,rw \
xx-go build -o /build/rootlesskit-docker-proxy -ldflags="$([ "$DOCKER_STATIC" != "1" ] && echo "-linkmode=external")" ./cmd/rootlesskit-docker-proxy
xx-verify $([ "$DOCKER_STATIC" = "1" ] && echo "--static") /build/rootlesskit-docker-proxy
EOT
COPY ./contrib/dockerd-rootless.sh /build/
COPY ./contrib/dockerd-rootless-setuptool.sh /build/
COPY --link ./contrib/dockerd-rootless.sh /build/
COPY --link ./contrib/dockerd-rootless-setuptool.sh /build/
FROM rootlesskit-build AS rootlesskit-linux
FROM binary-dummy AS rootlesskit-windows
@@ -437,28 +437,36 @@ FROM binary-dummy AS containerutil-linux
FROM containerutil-build AS containerutil-windows-amd64
FROM containerutil-windows-${TARGETARCH} AS containerutil-windows
FROM containerutil-${TARGETOS} AS containerutil
FROM docker/buildx-bin:${BUILDX_VERSION} as buildx
FROM base AS dev-systemd-false
COPY --from=dockercli /build/ /usr/local/cli
COPY --from=frozen-images /build/ /docker-frozen-images
COPY --from=swagger /build/ /usr/local/bin/
COPY --from=delve /build/ /usr/local/bin/
COPY --from=tomll /build/ /usr/local/bin/
COPY --from=gowinres /build/ /usr/local/bin/
COPY --from=tini /build/ /usr/local/bin/
COPY --from=registry /build/ /usr/local/bin/
COPY --from=criu /build/ /usr/local/bin/
COPY --from=gotestsum /build/ /usr/local/bin/
COPY --from=golangci_lint /build/ /usr/local/bin/
COPY --from=shfmt /build/ /usr/local/bin/
COPY --from=runc /build/ /usr/local/bin/
COPY --from=containerd /build/ /usr/local/bin/
COPY --from=rootlesskit /build/ /usr/local/bin/
COPY --from=vpnkit / /usr/local/bin/
COPY --from=containerutil /build/ /usr/local/bin/
COPY --from=crun /build/ /usr/local/bin/
COPY hack/dockerfile/etc/docker/ /etc/docker/
COPY --link --from=frozen-images /build/ /docker-frozen-images
COPY --link --from=swagger /build/ /usr/local/bin/
COPY --link --from=delve /build/ /usr/local/bin/
COPY --link --from=tomll /build/ /usr/local/bin/
COPY --link --from=gowinres /build/ /usr/local/bin/
COPY --link --from=tini /build/ /usr/local/bin/
COPY --link --from=registry /build/ /usr/local/bin/
# Skip the CRIU stage for now, as the opensuse package repository is sometimes
# unstable, and we're currently not using it in CI.
#
# FIXME(thaJeztah): re-enable this stage when https://github.com/moby/moby/issues/38963 is resolved (see https://github.com/moby/moby/pull/38984)
# COPY --link --from=criu /build/ /usr/local/bin/
COPY --link --from=gotestsum /build/ /usr/local/bin/
COPY --link --from=golangci_lint /build/ /usr/local/bin/
COPY --link --from=shfmt /build/ /usr/local/bin/
COPY --link --from=runc /build/ /usr/local/bin/
COPY --link --from=containerd /build/ /usr/local/bin/
COPY --link --from=rootlesskit /build/ /usr/local/bin/
COPY --link --from=vpnkit / /usr/local/bin/
COPY --link --from=containerutil /build/ /usr/local/bin/
COPY --link --from=crun /build/ /usr/local/bin/
COPY --link hack/dockerfile/etc/docker/ /etc/docker/
COPY --link --from=buildx /buildx /usr/local/libexec/docker/cli-plugins/docker-buildx
ENV PATH=/usr/local/cli:$PATH
ENV TEST_CLIENT_BINARY=/usr/local/cli-integration/docker
ENV CONTAINERD_ADDRESS=/run/docker/containerd/containerd.sock
ENV CONTAINERD_NAMESPACE=moby
WORKDIR /go/src/github.com/docker/docker
@@ -544,6 +552,8 @@ RUN --mount=type=cache,sharing=locked,id=moby-dev-aptlib,target=/var/lib/apt \
libsecret-1-dev \
libsystemd-dev \
libudev-dev
COPY --link --from=dockercli /build/ /usr/local/cli
COPY --link --from=dockercli-integration /build/ /usr/local/cli-integration
FROM base AS build
COPY --from=gowinres /build/ /usr/local/bin/
@@ -589,7 +599,7 @@ RUN <<EOT
XX_CC_PREFER_LINKER=ld xx-clang --setup-target-triple
fi
EOT
RUN --mount=type=bind,target=. \
RUN --mount=type=bind,target=.,rw \
--mount=type=tmpfs,target=cli/winresources/dockerd \
--mount=type=tmpfs,target=cli/winresources/docker-proxy \
--mount=type=cache,target=/root/.cache/go-build,id=moby-build-$TARGETPLATFORM <<EOT
@@ -615,13 +625,13 @@ COPY --from=build /build/ /
# usage:
# > docker buildx bake all
FROM scratch AS all
COPY --from=tini /build/ /
COPY --from=runc /build/ /
COPY --from=containerd /build/ /
COPY --from=rootlesskit /build/ /
COPY --from=containerutil /build/ /
COPY --from=vpnkit / /
COPY --from=build /build /
COPY --link --from=tini /build/ /
COPY --link --from=runc /build/ /
COPY --link --from=containerd /build/ /
COPY --link --from=rootlesskit /build/ /
COPY --link --from=containerutil /build/ /
COPY --link --from=vpnkit / /
COPY --link --from=build /build /
# smoke tests
# usage:
@@ -641,4 +651,4 @@ EOT
# > make shell
# > SYSTEMD=true make shell
FROM dev-base AS dev
COPY . .
COPY --link . .

View File

@@ -1,84 +0,0 @@
ARG GO_VERSION=1.20.4
FROM golang:${GO_VERSION}-alpine AS base
ENV GO111MODULE=off
RUN apk --no-cache add \
bash \
build-base \
curl \
lvm2-dev \
jq
RUN mkdir -p /build/
RUN mkdir -p /go/src/github.com/docker/docker/
WORKDIR /go/src/github.com/docker/docker/
FROM base AS frozen-images
# Get useful and necessary Hub images so we can "docker load" locally instead of pulling
COPY contrib/download-frozen-image-v2.sh /
RUN /download-frozen-image-v2.sh /build \
busybox:latest@sha256:95cf004f559831017cdf4628aaf1bb30133677be8702a8c5f2994629f637a209 \
busybox:latest@sha256:95cf004f559831017cdf4628aaf1bb30133677be8702a8c5f2994629f637a209 \
debian:bullseye-slim@sha256:dacf278785a4daa9de07596ec739dbc07131e189942772210709c5c0777e8437 \
hello-world:latest@sha256:d58e752213a51785838f9eed2b7a498ffa1cb3aa7f946dda11af39286c3db9a9 \
arm32v7/hello-world:latest@sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1
# See also frozenImages in "testutil/environment/protect.go" (which needs to be updated when adding images to this list)
FROM base AS dockercli
COPY hack/dockerfile/install/install.sh ./install.sh
COPY hack/dockerfile/install/dockercli.installer ./
RUN PREFIX=/build ./install.sh dockercli
# TestDockerCLIBuildSuite dependency
FROM base AS contrib
COPY contrib/syscall-test /build/syscall-test
COPY contrib/httpserver/Dockerfile /build/httpserver/Dockerfile
COPY contrib/httpserver contrib/httpserver
RUN CGO_ENABLED=0 go build -buildmode=pie -o /build/httpserver/httpserver github.com/docker/docker/contrib/httpserver
# Build the integration tests and copy the resulting binaries to /build/tests
FROM base AS builder
# Set tag and add sources
COPY . .
# Copy test sources tests that use assert can print errors
RUN mkdir -p /build${PWD} && find integration integration-cli -name \*_test.go -exec cp --parents '{}' /build${PWD} \;
# Build and install test binaries
ARG DOCKER_GITCOMMIT=undefined
RUN hack/make.sh build-integration-test-binary
RUN mkdir -p /build/tests && find . -name test.main -exec cp --parents '{}' /build/tests \;
## Generate testing image
FROM alpine:3.10 as runner
ENV DOCKER_REMOTE_DAEMON=1
ENV DOCKER_INTEGRATION_DAEMON_DEST=/
ENTRYPOINT ["/scripts/run.sh"]
# Add an unprivileged user to be used for tests which need it
RUN addgroup docker && adduser -D -G docker unprivilegeduser -s /bin/ash
# GNU tar is used for generating the emptyfs image
RUN apk --no-cache add \
bash \
ca-certificates \
g++ \
git \
inetutils-ping \
iptables \
libcap2-bin \
pigz \
tar \
xz
COPY hack/test/e2e-run.sh /scripts/run.sh
COPY hack/make/.ensure-emptyfs /scripts/ensure-emptyfs.sh
COPY integration/testdata /tests/integration/testdata
COPY integration/build/testdata /tests/integration/build/testdata
COPY integration-cli/fixtures /tests/integration-cli/fixtures
COPY --from=frozen-images /build/ /docker-frozen-images
COPY --from=dockercli /build/ /usr/bin/
COPY --from=contrib /build/ /tests/contrib/
COPY --from=builder /build/ /

View File

@@ -5,7 +5,7 @@
# This represents the bare minimum required to build and test Docker.
ARG GO_VERSION=1.20.4
ARG GO_VERSION=1.20.10
ARG BASE_DEBIAN_DISTRO="bullseye"
ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}"
@@ -13,9 +13,9 @@ ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}"
FROM ${GOLANG_IMAGE}
ENV GO111MODULE=off
# allow replacing httpredir or deb mirror
ARG APT_MIRROR=deb.debian.org
RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
# allow replacing debian mirror
ARG APT_MIRROR
RUN test -n "$APT_MIRROR" && sed -ri "s#(httpredir|deb|security).debian.org#${APT_MIRROR}#g" /etc/apt/sources.list || true
# Compile and runtime deps
# https://github.com/docker/docker/blob/master/project/PACKAGERS.md#build-dependencies

View File

@@ -165,10 +165,10 @@ FROM microsoft/windowsservercore
# Use PowerShell as the default shell
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
ARG GO_VERSION=1.20.4
ARG GO_VERSION=1.20.10
ARG GOTESTSUM_VERSION=v1.8.2
ARG GOWINRES_VERSION=v0.3.0
ARG CONTAINERD_VERSION=v1.7.0
ARG CONTAINERD_VERSION=v1.7.6
# Environment variable notes:
# - GO_VERSION must be consistent with 'Dockerfile' used by Linux.
@@ -224,7 +224,7 @@ RUN `
`
Write-Host INFO: Downloading go...; `
$dlGoVersion=$Env:GO_VERSION -replace '\.0$',''; `
Download-File "https://golang.org/dl/go${dlGoVersion}.windows-amd64.zip" C:\go.zip; `
Download-File "https://go.dev/dl/go${dlGoVersion}.windows-amd64.zip" C:\go.zip; `
`
Write-Host INFO: Downloading compiler 1 of 3...; `
Download-File https://raw.githubusercontent.com/moby/docker-tdmgcc/master/gcc.zip C:\gcc.zip; `

405
Jenkinsfile vendored
View File

@@ -9,15 +9,12 @@ pipeline {
}
parameters {
booleanParam(name: 'arm64', defaultValue: true, description: 'ARM (arm64) Build/Test')
booleanParam(name: 's390x', defaultValue: false, description: 'IBM Z (s390x) Build/Test')
booleanParam(name: 'ppc64le', defaultValue: false, description: 'PowerPC (ppc64le) Build/Test')
booleanParam(name: 'dco', defaultValue: true, description: 'Run the DCO check')
}
environment {
DOCKER_BUILDKIT = '1'
DOCKER_EXPERIMENTAL = '1'
DOCKER_GRAPHDRIVER = 'overlay2'
APT_MIRROR = 'cdn-fastly.deb.debian.org'
CHECK_CONFIG_COMMIT = '33a3680e08d1007e72c3b3f1454f823d8e9948ee'
TESTDEBUG = '0'
TIMEOUT = '120m'
@@ -52,406 +49,6 @@ pipeline {
}
stage('Build') {
parallel {
stage('s390x') {
when {
beforeAgent true
// Skip this stage on PRs unless the checkbox is selected
anyOf {
not { changeRequest() }
expression { params.s390x }
}
}
agent { label 's390x-ubuntu-2004' }
stages {
stage("Print info") {
steps {
sh 'docker version'
sh 'docker info'
sh '''
echo "check-config.sh version: ${CHECK_CONFIG_COMMIT}"
curl -fsSL -o ${WORKSPACE}/check-config.sh "https://raw.githubusercontent.com/moby/moby/${CHECK_CONFIG_COMMIT}/contrib/check-config.sh" \
&& bash ${WORKSPACE}/check-config.sh || true
'''
}
}
stage("Build dev image") {
steps {
sh '''
docker build --force-rm --build-arg APT_MIRROR -t docker:${GIT_COMMIT} .
'''
}
}
stage("Unit tests") {
steps {
sh '''
sudo modprobe ip6table_filter
'''
sh '''
docker run --rm -t --privileged \
-v "$WORKSPACE/bundles:/go/src/github.com/docker/docker/bundles" \
--name docker-pr$BUILD_NUMBER \
-e DOCKER_EXPERIMENTAL \
-e DOCKER_GITCOMMIT=${GIT_COMMIT} \
-e DOCKER_GRAPHDRIVER \
-e VALIDATE_REPO=${GIT_URL} \
-e VALIDATE_BRANCH=${CHANGE_TARGET} \
docker:${GIT_COMMIT} \
hack/test/unit
'''
}
post {
always {
junit testResults: 'bundles/junit-report*.xml', allowEmptyResults: true
}
}
}
stage("Integration tests") {
environment { TEST_SKIP_INTEGRATION_CLI = '1' }
steps {
sh '''
docker run --rm -t --privileged \
-v "$WORKSPACE/bundles:/go/src/github.com/docker/docker/bundles" \
--name docker-pr$BUILD_NUMBER \
-e DOCKER_EXPERIMENTAL \
-e DOCKER_GITCOMMIT=${GIT_COMMIT} \
-e DOCKER_GRAPHDRIVER \
-e TESTDEBUG \
-e TEST_INTEGRATION_USE_SNAPSHOTTER \
-e TEST_SKIP_INTEGRATION_CLI \
-e TIMEOUT \
-e VALIDATE_REPO=${GIT_URL} \
-e VALIDATE_BRANCH=${CHANGE_TARGET} \
docker:${GIT_COMMIT} \
hack/make.sh \
dynbinary \
test-integration
'''
}
post {
always {
junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true
}
}
}
}
post {
always {
sh '''
echo "Ensuring container killed."
docker rm -vf docker-pr$BUILD_NUMBER || true
'''
sh '''
echo "Chowning /workspace to jenkins user"
docker run --rm -v "$WORKSPACE:/workspace" busybox chown -R "$(id -u):$(id -g)" /workspace
'''
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE', message: 'Failed to create bundles.tar.gz') {
sh '''
bundleName=s390x-integration
echo "Creating ${bundleName}-bundles.tar.gz"
# exclude overlay2 directories
find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
'''
archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true
}
}
cleanup {
sh 'make clean'
deleteDir()
}
}
}
stage('s390x integration-cli') {
when {
beforeAgent true
// Skip this stage on PRs unless the checkbox is selected
anyOf {
not { changeRequest() }
expression { params.s390x }
}
}
agent { label 's390x-ubuntu-2004' }
stages {
stage("Print info") {
steps {
sh 'docker version'
sh 'docker info'
sh '''
echo "check-config.sh version: ${CHECK_CONFIG_COMMIT}"
curl -fsSL -o ${WORKSPACE}/check-config.sh "https://raw.githubusercontent.com/moby/moby/${CHECK_CONFIG_COMMIT}/contrib/check-config.sh" \
&& bash ${WORKSPACE}/check-config.sh || true
'''
}
}
stage("Build dev image") {
steps {
sh '''
docker build --force-rm --build-arg APT_MIRROR -t docker:${GIT_COMMIT} .
'''
}
}
stage("Integration-cli tests") {
environment { TEST_SKIP_INTEGRATION = '1' }
steps {
sh '''
docker run --rm -t --privileged \
-v "$WORKSPACE/bundles:/go/src/github.com/docker/docker/bundles" \
--name docker-pr$BUILD_NUMBER \
-e DOCKER_GITCOMMIT=${GIT_COMMIT} \
-e DOCKER_GRAPHDRIVER \
-e TEST_INTEGRATION_USE_SNAPSHOTTER \
-e TEST_SKIP_INTEGRATION \
-e TIMEOUT \
-e VALIDATE_REPO=${GIT_URL} \
-e VALIDATE_BRANCH=${CHANGE_TARGET} \
docker:${GIT_COMMIT} \
hack/make.sh \
dynbinary \
test-integration
'''
}
post {
always {
junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true
}
}
}
}
post {
always {
sh '''
echo "Ensuring container killed."
docker rm -vf docker-pr$BUILD_NUMBER || true
'''
sh '''
echo "Chowning /workspace to jenkins user"
docker run --rm -v "$WORKSPACE:/workspace" busybox chown -R "$(id -u):$(id -g)" /workspace
'''
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE', message: 'Failed to create bundles.tar.gz') {
sh '''
bundleName=s390x-integration-cli
echo "Creating ${bundleName}-bundles.tar.gz"
# exclude overlay2 directories
find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
'''
archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true
}
}
cleanup {
sh 'make clean'
deleteDir()
}
}
}
stage('ppc64le') {
when {
beforeAgent true
// Skip this stage on PRs unless the checkbox is selected
anyOf {
not { changeRequest() }
expression { params.ppc64le }
}
}
agent { label 'ppc64le-ubuntu-1604' }
stages {
stage("Print info") {
steps {
sh 'docker version'
sh 'docker info'
sh '''
echo "check-config.sh version: ${CHECK_CONFIG_COMMIT}"
curl -fsSL -o ${WORKSPACE}/check-config.sh "https://raw.githubusercontent.com/moby/moby/${CHECK_CONFIG_COMMIT}/contrib/check-config.sh" \
&& bash ${WORKSPACE}/check-config.sh || true
'''
}
}
stage("Build dev image") {
steps {
sh '''
docker buildx build --load --force-rm --build-arg APT_MIRROR -t docker:${GIT_COMMIT} .
'''
}
}
stage("Unit tests") {
steps {
sh '''
sudo modprobe ip6table_filter
'''
sh '''
docker run --rm -t --privileged \
-v "$WORKSPACE/bundles:/go/src/github.com/docker/docker/bundles" \
--name docker-pr$BUILD_NUMBER \
-e DOCKER_EXPERIMENTAL \
-e DOCKER_GITCOMMIT=${GIT_COMMIT} \
-e DOCKER_GRAPHDRIVER \
-e VALIDATE_REPO=${GIT_URL} \
-e VALIDATE_BRANCH=${CHANGE_TARGET} \
docker:${GIT_COMMIT} \
hack/test/unit
'''
}
post {
always {
junit testResults: 'bundles/junit-report*.xml', allowEmptyResults: true
}
}
}
stage("Integration tests") {
environment { TEST_SKIP_INTEGRATION_CLI = '1' }
steps {
sh '''
docker run --rm -t --privileged \
-v "$WORKSPACE/bundles:/go/src/github.com/docker/docker/bundles" \
--name docker-pr$BUILD_NUMBER \
-e DOCKER_EXPERIMENTAL \
-e DOCKER_GITCOMMIT=${GIT_COMMIT} \
-e DOCKER_GRAPHDRIVER \
-e TESTDEBUG \
-e TEST_INTEGRATION_USE_SNAPSHOTTER \
-e TEST_SKIP_INTEGRATION_CLI \
-e TIMEOUT \
-e VALIDATE_REPO=${GIT_URL} \
-e VALIDATE_BRANCH=${CHANGE_TARGET} \
docker:${GIT_COMMIT} \
hack/make.sh \
dynbinary \
test-integration
'''
}
post {
always {
junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true
}
}
}
}
post {
always {
sh '''
echo "Ensuring container killed."
docker rm -vf docker-pr$BUILD_NUMBER || true
'''
sh '''
echo "Chowning /workspace to jenkins user"
docker run --rm -v "$WORKSPACE:/workspace" busybox chown -R "$(id -u):$(id -g)" /workspace
'''
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE', message: 'Failed to create bundles.tar.gz') {
sh '''
bundleName=ppc64le-integration
echo "Creating ${bundleName}-bundles.tar.gz"
# exclude overlay2 directories
find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
'''
archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true
}
}
cleanup {
sh 'make clean'
deleteDir()
}
}
}
stage('ppc64le integration-cli') {
when {
beforeAgent true
// Skip this stage on PRs unless the checkbox is selected
anyOf {
not { changeRequest() }
expression { params.ppc64le }
}
}
agent { label 'ppc64le-ubuntu-1604' }
stages {
stage("Print info") {
steps {
sh 'docker version'
sh 'docker info'
sh '''
echo "check-config.sh version: ${CHECK_CONFIG_COMMIT}"
curl -fsSL -o ${WORKSPACE}/check-config.sh "https://raw.githubusercontent.com/moby/moby/${CHECK_CONFIG_COMMIT}/contrib/check-config.sh" \
&& bash ${WORKSPACE}/check-config.sh || true
'''
}
}
stage("Build dev image") {
steps {
sh '''
docker buildx build --load --force-rm --build-arg APT_MIRROR -t docker:${GIT_COMMIT} .
'''
}
}
stage("Integration-cli tests") {
environment { TEST_SKIP_INTEGRATION = '1' }
steps {
sh '''
docker run --rm -t --privileged \
-v "$WORKSPACE/bundles:/go/src/github.com/docker/docker/bundles" \
--name docker-pr$BUILD_NUMBER \
-e DOCKER_GITCOMMIT=${GIT_COMMIT} \
-e DOCKER_GRAPHDRIVER \
-e TEST_INTEGRATION_USE_SNAPSHOTTER \
-e TEST_SKIP_INTEGRATION \
-e TIMEOUT \
-e VALIDATE_REPO=${GIT_URL} \
-e VALIDATE_BRANCH=${CHANGE_TARGET} \
docker:${GIT_COMMIT} \
hack/make.sh \
dynbinary \
test-integration
'''
}
post {
always {
junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true
}
}
}
}
post {
always {
sh '''
echo "Ensuring container killed."
docker rm -vf docker-pr$BUILD_NUMBER || true
'''
sh '''
echo "Chowning /workspace to jenkins user"
docker run --rm -v "$WORKSPACE:/workspace" busybox chown -R "$(id -u):$(id -g)" /workspace
'''
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE', message: 'Failed to create bundles.tar.gz') {
sh '''
bundleName=ppc64le-integration-cli
echo "Creating ${bundleName}-bundles.tar.gz"
# exclude overlay2 directories
find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
'''
archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true
}
}
cleanup {
sh 'make clean'
deleteDir()
}
}
}
stage('arm64') {
when {
beforeAgent true
@@ -476,7 +73,7 @@ pipeline {
}
stage("Build dev image") {
steps {
sh 'docker build --force-rm --build-arg APT_MIRROR -t docker:${GIT_COMMIT} .'
sh 'docker build --force-rm -t docker:${GIT_COMMIT} .'
}
}
stage("Unit tests") {

View File

@@ -7,11 +7,7 @@ BUILDX ?= $(DOCKER) buildx
DOCKER_GRAPHDRIVER := $(if $(DOCKER_GRAPHDRIVER),$(DOCKER_GRAPHDRIVER),$(shell docker info 2>&1 | grep "Storage Driver" | sed 's/.*: //'))
export DOCKER_GRAPHDRIVER
# get OS/Arch of docker engine
DOCKER_OSARCH := $(shell bash -c 'source hack/make/.detect-daemon-osarch && echo $${DOCKER_ENGINE_OSARCH}')
DOCKERFILE := $(shell bash -c 'source hack/make/.detect-daemon-osarch && echo $${DOCKERFILE}')
DOCKER_GITCOMMIT := $(shell git rev-parse --short HEAD || echo unsupported)
DOCKER_GITCOMMIT := $(shell git rev-parse HEAD)
export DOCKER_GITCOMMIT
# allow overriding the repository and branch that validation scripts are running
@@ -41,6 +37,10 @@ DOCKER_ENVS := \
-e DOCKER_BUILDKIT \
-e DOCKER_BASH_COMPLETION_PATH \
-e DOCKER_CLI_PATH \
-e DOCKERCLI_VERSION \
-e DOCKERCLI_REPOSITORY \
-e DOCKERCLI_INTEGRATION_VERSION \
-e DOCKERCLI_INTEGRATION_REPOSITORY \
-e DOCKER_DEBUG \
-e DOCKER_EXPERIMENTAL \
-e DOCKER_GITCOMMIT \
@@ -58,6 +58,7 @@ DOCKER_ENVS := \
-e TEST_FORCE_VALIDATE \
-e TEST_INTEGRATION_DIR \
-e TEST_INTEGRATION_USE_SNAPSHOTTER \
-e TEST_INTEGRATION_FAIL_FAST \
-e TEST_SKIP_INTEGRATION \
-e TEST_SKIP_INTEGRATION_CLI \
-e TESTCOVERAGE \
@@ -136,11 +137,16 @@ endif
DOCKER_RUN_DOCKER := $(DOCKER_FLAGS) "$(DOCKER_IMAGE)"
DOCKER_BUILD_ARGS += --build-arg=GO_VERSION
DOCKER_BUILD_ARGS += --build-arg=APT_MIRROR
DOCKER_BUILD_ARGS += --build-arg=DOCKERCLI_VERSION
DOCKER_BUILD_ARGS += --build-arg=DOCKERCLI_REPOSITORY
DOCKER_BUILD_ARGS += --build-arg=DOCKERCLI_INTEGRATION_VERSION
DOCKER_BUILD_ARGS += --build-arg=DOCKERCLI_INTEGRATION_REPOSITORY
ifdef DOCKER_SYSTEMD
DOCKER_BUILD_ARGS += --build-arg=SYSTEMD=true
endif
BUILD_OPTS := ${BUILD_APT_MIRROR} ${DOCKER_BUILD_ARGS} ${DOCKER_BUILD_OPTS} -f "$(DOCKERFILE)"
BUILD_OPTS := ${BUILD_APT_MIRROR} ${DOCKER_BUILD_ARGS} ${DOCKER_BUILD_OPTS}
BUILD_CMD := $(BUILDX) build
BAKE_CMD := $(BUILDX) bake

View File

@@ -21,7 +21,7 @@ import (
containerpkg "github.com/docker/docker/container"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/ioutils"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/websocket"
@@ -44,7 +44,7 @@ func (s *containerRouter) postCommit(ctx context.Context, w http.ResponseWriter,
}
config, _, _, err := s.decoder.DecodeConfig(r.Body)
if err != nil && err != io.EOF { // Do not fail if body is empty.
if err != nil && !errors.Is(err, io.EOF) { // Do not fail if body is empty.
return err
}
@@ -486,6 +486,9 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
config, hostConfig, networkingConfig, err := s.decoder.DecodeConfig(r.Body)
if err != nil {
if errors.Is(err, io.EOF) {
return errdefs.InvalidParameter(errors.New("invalid JSON: got EOF while reading request body"))
}
return err
}
version := httputils.VersionFromContext(ctx)
@@ -566,7 +569,7 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
hostConfig.Annotations = nil
}
var platform *specs.Platform
var platform *ocispec.Platform
if versions.GreaterThanOrEqualTo(version, "1.41") {
if v := r.Form.Get("platform"); v != "" {
p, err := platforms.Parse(v)

View File

@@ -12,7 +12,7 @@ import (
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
@@ -61,7 +61,7 @@ func (s *distributionRouter) getDistributionInfo(ctx context.Context, w http.Res
if err != nil {
return err
}
distributionInspect.Descriptor = v1.Descriptor{
distributionInspect.Descriptor = ocispec.Descriptor{
MediaType: descriptor.MediaType,
Digest: descriptor.Digest,
Size: descriptor.Size,
@@ -107,7 +107,7 @@ func (s *distributionRouter) getDistributionInfo(ctx context.Context, w http.Res
switch mnfstObj := mnfst.(type) {
case *manifestlist.DeserializedManifestList:
for _, m := range mnfstObj.Manifests {
distributionInspect.Platforms = append(distributionInspect.Platforms, v1.Platform{
distributionInspect.Platforms = append(distributionInspect.Platforms, ocispec.Platform{
Architecture: m.Platform.Architecture,
OS: m.Platform.OS,
OSVersion: m.Platform.OSVersion,
@@ -117,7 +117,7 @@ func (s *distributionRouter) getDistributionInfo(ctx context.Context, w http.Res
}
case *schema2.DeserializedManifest:
configJSON, err := blobsrvc.Get(ctx, mnfstObj.Config.Digest)
var platform v1.Platform
var platform ocispec.Platform
if err == nil {
err := json.Unmarshal(configJSON, &platform)
if err == nil && (platform.OS != "" || platform.Architecture != "") {
@@ -125,7 +125,7 @@ func (s *distributionRouter) getDistributionInfo(ctx context.Context, w http.Res
}
}
case *schema1.SignedManifest:
platform := v1.Platform{
platform := ocispec.Platform{
Architecture: mnfstObj.Architecture,
OS: "linux",
}

View File

@@ -10,7 +10,7 @@ import (
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/registry"
dockerimage "github.com/docker/docker/image"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// Backend is all the methods that need to be implemented
@@ -32,12 +32,12 @@ type imageBackend interface {
type importExportBackend interface {
LoadImage(ctx context.Context, inTar io.ReadCloser, outStream io.Writer, quiet bool) error
ImportImage(ctx context.Context, ref reference.Named, platform *specs.Platform, msg string, layerReader io.Reader, changes []string) (dockerimage.ID, error)
ImportImage(ctx context.Context, ref reference.Named, platform *ocispec.Platform, msg string, layerReader io.Reader, changes []string) (dockerimage.ID, error)
ExportImage(ctx context.Context, names []string, outStream io.Writer) error
}
type registryBackend interface {
PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
PullImage(ctx context.Context, image, tag string, platform *ocispec.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
PushImage(ctx context.Context, ref reference.Named, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
}

View File

@@ -24,7 +24,7 @@ import (
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/streamformatter"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
@@ -41,7 +41,7 @@ func (ir *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrit
comment = r.Form.Get("message")
progressErr error
output = ioutils.NewWriteFlusher(w)
platform *specs.Platform
platform *ocispec.Platform
)
defer output.Close()
@@ -282,6 +282,14 @@ func (ir *imageRouter) toImageInspect(img *image.Image) (*types.ImageInspect, er
comment = img.History[len(img.History)-1].Comment
}
// Make sure we output empty arrays instead of nil.
if repoTags == nil {
repoTags = []string{}
}
if repoDigests == nil {
repoDigests = []string{}
}
return &types.ImageInspect{
ID: img.ID().String(),
RepoTags: repoTags,

View File

@@ -5068,7 +5068,7 @@ definitions:
Go runtime (`GOOS`).
Currently returned values are "linux" and "windows". A full list of
possible values can be found in the [Go documentation](https://golang.org/doc/install/source#environment).
possible values can be found in the [Go documentation](https://go.dev/doc/install/source#environment).
type: "string"
example: "linux"
Architecture:
@@ -5076,7 +5076,7 @@ definitions:
Hardware architecture of the host, as returned by the Go runtime
(`GOARCH`).
A full list of possible values can be found in the [Go documentation](https://golang.org/doc/install/source#environment).
A full list of possible values can be found in the [Go documentation](https://go.dev/doc/install/source#environment).
type: "string"
example: "x86_64"
NCPU:
@@ -5162,42 +5162,8 @@ definitions:
ServerVersion:
description: |
Version string of the daemon.
> **Note**: the [standalone Swarm API](https://docs.docker.com/swarm/swarm-api/)
> returns the Swarm version instead of the daemon version, for example
> `swarm/1.2.8`.
type: "string"
example: "17.06.0-ce"
ClusterStore:
description: |
URL of the distributed storage backend.
The storage backend is used for multihost networking (to store
network and endpoint information) and by the node discovery mechanism.
<p><br /></p>
> **Deprecated**: This field is only propagated when using standalone Swarm
> mode, and overlay networking using an external k/v store. Overlay
> networks with Swarm mode enabled use the built-in raft store, and
> this field will be empty.
type: "string"
example: "consul://consul.corp.example.com:8600/some/path"
ClusterAdvertise:
description: |
The network endpoint that the Engine advertises for the purpose of
node discovery. ClusterAdvertise is a `host:port` combination on which
the daemon is reachable by other hosts.
<p><br /></p>
> **Deprecated**: This field is only propagated when using standalone Swarm
> mode, and overlay networking using an external k/v store. Overlay
> networks with Swarm mode enabled use the built-in raft store, and
> this field will be empty.
type: "string"
example: "node5.corp.example.com:8000"
example: "24.0.2"
Runtimes:
description: |
List of [OCI compliant](https://github.com/opencontainers/runtime-spec)
@@ -9930,7 +9896,9 @@ paths:
Id: "22be93d5babb089c5aab8dbc369042fad48ff791584ca2da2100db837a1c7c30"
Warning: ""
403:
description: "operation not supported for pre-defined networks"
description: |
Forbidden operation. This happens when trying to create a network named after a pre-defined network,
or when trying to create an overlay network on a daemon which is not part of a Swarm cluster.
schema:
$ref: "#/definitions/ErrorResponse"
404:
@@ -10393,6 +10361,12 @@ paths:
default if omitted.
required: true
type: "string"
- name: "force"
in: "query"
description: |
Force disable a plugin even if still in use.
required: false
type: "boolean"
tags: ["Plugin"]
/plugins/{name}/upgrade:
post:

View File

@@ -6,7 +6,7 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/pkg/streamformatter"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// PullOption defines different modes for accessing images
@@ -42,5 +42,5 @@ type GetImageAndLayerOptions struct {
PullOption PullOption
AuthConfig map[string]registry.AuthConfig
Output io.Writer
Platform *specs.Platform
Platform *ocispec.Platform
}

View File

@@ -3,7 +3,7 @@ package types // import "github.com/docker/docker/api/types"
import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// configs holds structs used for internal communication between the
@@ -16,7 +16,7 @@ type ContainerCreateConfig struct {
Config *container.Config
HostConfig *container.HostConfig
NetworkingConfig *network.NetworkingConfig
Platform *specs.Platform
Platform *ocispec.Platform
AdjustCPUShares bool
}

View File

@@ -98,7 +98,7 @@ func FromJSON(p string) (Args, error) {
// Fallback to parsing arguments in the legacy slice format
deprecated := map[string][]string{}
if legacyErr := json.Unmarshal(raw, &deprecated); legacyErr != nil {
return args, invalidFilter{}
return args, &invalidFilter{}
}
args.fields = deprecatedArgs(deprecated)
@@ -206,7 +206,7 @@ func (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) {
}
if len(fieldValues) == 0 {
return defaultValue, invalidFilter{key, nil}
return defaultValue, &invalidFilter{key, nil}
}
isFalse := fieldValues["0"] || fieldValues["false"]
@@ -216,7 +216,7 @@ func (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) {
invalid := !isFalse && !isTrue
if conflicting || invalid {
return defaultValue, invalidFilter{key, args.Get(key)}
return defaultValue, &invalidFilter{key, args.Get(key)}
} else if isFalse {
return false, nil
} else if isTrue {
@@ -224,7 +224,7 @@ func (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) {
}
// This code shouldn't be reached.
return defaultValue, unreachableCode{Filter: key, Value: args.Get(key)}
return defaultValue, &unreachableCode{Filter: key, Value: args.Get(key)}
}
// ExactMatch returns true if the source matches exactly one of the values.
@@ -282,7 +282,7 @@ func (args Args) Contains(field string) bool {
func (args Args) Validate(accepted map[string]bool) error {
for name := range args.fields {
if !accepted[name] {
return invalidFilter{name, nil}
return &invalidFilter{name, nil}
}
}
return nil

View File

@@ -3,6 +3,7 @@ package filters // import "github.com/docker/docker/api/types/filters"
import (
"encoding/json"
"errors"
"fmt"
"sort"
"testing"
@@ -95,15 +96,19 @@ func TestFromJSON(t *testing.T) {
if err == nil {
t.Fatalf("Expected an error with %v, got nothing", invalid)
}
var invalidFilterError invalidFilter
var invalidFilterError *invalidFilter
if !errors.As(err, &invalidFilterError) {
t.Fatalf("Expected an invalidFilter error, got %T", err)
}
wrappedErr := fmt.Errorf("something went wrong: %w", err)
if !errors.Is(wrappedErr, err) {
t.Errorf("Expected a wrapped error to be detected as invalidFilter")
}
}
for expectedArgs, matchers := range valid {
for _, json := range matchers {
args, err := FromJSON(json)
for _, jsonString := range matchers {
args, err := FromJSON(jsonString)
if err != nil {
t.Fatal(err)
}
@@ -358,9 +363,13 @@ func TestValidate(t *testing.T) {
if err == nil {
t.Fatal("Expected to return an error, got nil")
}
var invalidFilterError invalidFilter
var invalidFilterError *invalidFilter
if !errors.As(err, &invalidFilterError) {
t.Fatalf("Expected an invalidFilter error, got %T", err)
t.Errorf("Expected an invalidFilter error, got %T", err)
}
wrappedErr := fmt.Errorf("something went wrong: %w", err)
if !errors.Is(wrappedErr, err) {
t.Errorf("Expected a wrapped error to be detected as invalidFilter")
}
}
@@ -421,7 +430,7 @@ func TestClone(t *testing.T) {
}
func TestGetBoolOrDefault(t *testing.T) {
for _, tC := range []struct {
for _, tc := range []struct {
name string
args map[string][]string
defValue bool
@@ -452,7 +461,7 @@ func TestGetBoolOrDefault(t *testing.T) {
"dangling": {"potato"},
},
defValue: true,
expectedErr: invalidFilter{Filter: "dangling", Value: []string{"potato"}},
expectedErr: &invalidFilter{Filter: "dangling", Value: []string{"potato"}},
expectedValue: true,
},
{
@@ -461,7 +470,7 @@ func TestGetBoolOrDefault(t *testing.T) {
"dangling": {"banana", "potato"},
},
defValue: true,
expectedErr: invalidFilter{Filter: "dangling", Value: []string{"banana", "potato"}},
expectedErr: &invalidFilter{Filter: "dangling", Value: []string{"banana", "potato"}},
expectedValue: true,
},
{
@@ -470,7 +479,7 @@ func TestGetBoolOrDefault(t *testing.T) {
"dangling": {"false", "true"},
},
defValue: false,
expectedErr: invalidFilter{Filter: "dangling", Value: []string{"false", "true"}},
expectedErr: &invalidFilter{Filter: "dangling", Value: []string{"false", "true"}},
expectedValue: false,
},
{
@@ -479,7 +488,7 @@ func TestGetBoolOrDefault(t *testing.T) {
"dangling": {"false", "true", "1"},
},
defValue: true,
expectedErr: invalidFilter{Filter: "dangling", Value: []string{"false", "true", "1"}},
expectedErr: &invalidFilter{Filter: "dangling", Value: []string{"false", "true", "1"}},
expectedValue: true,
},
{
@@ -501,35 +510,38 @@ func TestGetBoolOrDefault(t *testing.T) {
expectedValue: false,
},
} {
tC := tC
t.Run(tC.name, func(t *testing.T) {
tc := tc
t.Run(tc.name, func(t *testing.T) {
a := NewArgs()
for key, values := range tC.args {
for key, values := range tc.args {
for _, value := range values {
a.Add(key, value)
}
}
value, err := a.GetBoolOrDefault("dangling", tC.defValue)
value, err := a.GetBoolOrDefault("dangling", tc.defValue)
if tC.expectedErr == nil {
if tc.expectedErr == nil {
assert.Check(t, is.Nil(err))
} else {
assert.Check(t, is.ErrorType(err, tC.expectedErr))
assert.Check(t, is.ErrorType(err, tc.expectedErr))
// Check if error is the same.
expected := tC.expectedErr.(invalidFilter)
actual := err.(invalidFilter)
expected := tc.expectedErr.(*invalidFilter)
actual := err.(*invalidFilter)
assert.Check(t, is.Equal(expected.Filter, actual.Filter))
sort.Strings(expected.Value)
sort.Strings(actual.Value)
assert.Check(t, is.DeepEqual(expected.Value, actual.Value))
wrappedErr := fmt.Errorf("something went wrong: %w", err)
assert.Check(t, errors.Is(wrappedErr, err), "Expected a wrapped error to be detected as invalidFilter")
}
assert.Check(t, is.Equal(tC.expectedValue, value))
assert.Check(t, is.Equal(tc.expectedValue, value))
})
}

View File

@@ -1,9 +1,9 @@
package image
import specs "github.com/opencontainers/image-spec/specs-go/v1"
import ocispec "github.com/opencontainers/image-spec/specs-go/v1"
// GetImageOpts holds parameters to inspect an image.
type GetImageOpts struct {
Platform *specs.Platform
Platform *ocispec.Platform
Details bool
}

View File

@@ -4,7 +4,7 @@ import (
"encoding/json"
"net"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// ServiceConfig stores daemon registry services configuration.
@@ -113,8 +113,8 @@ type SearchResults struct {
type DistributionInspect struct {
// Descriptor contains information about the manifest, including
// the content addressable digest
Descriptor v1.Descriptor
Descriptor ocispec.Descriptor
// Platforms contains the list of platforms supported by the image,
// obtained by parsing the manifest
Platforms []v1.Platform
Platforms []ocispec.Platform
}

View File

@@ -16,11 +16,11 @@ func compare(v1, v2 string) int {
otherTab = strings.Split(v2, ".")
)
max := len(currTab)
if len(otherTab) > max {
max = len(otherTab)
maxVer := len(currTab)
if len(otherTab) > maxVer {
maxVer = len(otherTab)
}
for i := 0; i < max; i++ {
for i := 0; i < maxVer; i++ {
var currInt, otherInt int
if len(currTab) > i {

View File

@@ -18,7 +18,7 @@ import (
"github.com/moby/buildkit/solver"
"github.com/moby/buildkit/worker"
"github.com/opencontainers/go-digest"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
@@ -26,9 +26,9 @@ import (
func ResolveCacheImporterFunc(sm *session.Manager, resolverFunc docker.RegistryHosts, cs content.Store, rs reference.Store, is imagestore.Store) remotecache.ResolveCacheImporterFunc {
upstream := registryremotecache.ResolveCacheImporterFunc(sm, cs, resolverFunc)
return func(ctx context.Context, group session.Group, attrs map[string]string) (remotecache.Importer, specs.Descriptor, error) {
return func(ctx context.Context, group session.Group, attrs map[string]string) (remotecache.Importer, ocispec.Descriptor, error) {
if dt, err := tryImportLocal(rs, is, attrs["ref"]); err == nil {
return newLocalImporter(dt), specs.Descriptor{}, nil
return newLocalImporter(dt), ocispec.Descriptor{}, nil
}
return upstream(ctx, group, attrs)
}
@@ -59,7 +59,7 @@ type localImporter struct {
dt []byte
}
func (li *localImporter) Resolve(ctx context.Context, _ specs.Descriptor, id string, w worker.Worker) (solver.CacheManager, error) {
func (li *localImporter) Resolve(ctx context.Context, _ ocispec.Descriptor, id string, w worker.Worker) (solver.CacheManager, error) {
cc := v1.NewCacheChains()
if err := li.importInlineCache(ctx, li.dt, cc); err != nil {
return nil, err
@@ -96,7 +96,7 @@ func (li *localImporter) importInlineCache(ctx context.Context, dt []byte, cc so
layers := v1.DescriptorProvider{}
for i, diffID := range img.Rootfs.DiffIDs {
dgst := digest.Digest(diffID.String())
desc := specs.Descriptor{
desc := ocispec.Descriptor{
Digest: dgst,
Size: -1,
MediaType: images.MediaTypeDockerSchema2Layer,
@@ -157,6 +157,6 @@ func parseCreatedLayerInfo(img image) ([]string, []string, error) {
type emptyProvider struct {
}
func (p *emptyProvider) ReaderAt(ctx context.Context, dec specs.Descriptor) (content.ReaderAt, error) {
func (p *emptyProvider) ReaderAt(ctx context.Context, dec ocispec.Descriptor) (content.ReaderAt, error) {
return nil, errors.Errorf("ReaderAt not implemented for empty provider")
}

View File

@@ -78,6 +78,7 @@ var cacheFields = map[string]bool{
type Opt struct {
SessionManager *session.Manager
Root string
EngineID string
Dist images.DistributionServices
ImageTagger mobyexporter.ImageTagger
NetworkController *libnetwork.Controller
@@ -354,11 +355,7 @@ func (b *Builder) Build(ctx context.Context, opt backend.BuildConfig) (*builder.
exporterName := ""
exporterAttrs := map[string]string{}
if len(opt.Options.Outputs) == 0 {
if b.useSnapshotter {
exporterName = client.ExporterImage
} else {
exporterName = exporter.Moby
}
exporterName = exporter.Moby
} else {
// cacheonly is a special type for triggering skipping all exporters
if opt.Options.Outputs[0].Type != "cacheonly" {

View File

@@ -16,10 +16,10 @@ import (
"github.com/docker/docker/builder/builder-next/adapters/containerimage"
"github.com/docker/docker/builder/builder-next/adapters/localinlinecache"
"github.com/docker/docker/builder/builder-next/adapters/snapshot"
"github.com/docker/docker/builder/builder-next/exporter"
"github.com/docker/docker/builder/builder-next/exporter/mobyexporter"
"github.com/docker/docker/builder/builder-next/imagerefchecker"
mobyworker "github.com/docker/docker/builder/builder-next/worker"
wlabel "github.com/docker/docker/builder/builder-next/worker/label"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/daemon/graphdriver"
units "github.com/docker/go-units"
@@ -96,6 +96,7 @@ func newSnapshotterController(ctx context.Context, rt http.RoundTripper, opt Opt
wo.GCPolicy = policy
wo.RegistryHosts = opt.RegistryHosts
wo.Labels = getLabels(opt, wo.Labels)
exec, err := newExecutor(opt.Root, opt.DefaultCgroupParent, opt.NetworkController, dns, opt.Rootless, opt.IdentityMapping, opt.ApparmorProfile)
if err != nil {
@@ -303,7 +304,7 @@ func newGraphDriverController(ctx context.Context, rt http.RoundTripper, opt Opt
return nil, errors.Errorf("snapshotter doesn't support differ")
}
leases, err := lm.List(ctx, "labels.\"buildkit/lease.temporary\"")
leases, err := lm.List(ctx, `labels."buildkit/lease.temporary"`)
if err != nil {
return nil, err
}
@@ -312,7 +313,7 @@ func newGraphDriverController(ctx context.Context, rt http.RoundTripper, opt Opt
}
wopt := mobyworker.Opt{
ID: exporter.Moby,
ID: opt.EngineID,
ContentStore: store,
CacheManager: cm,
GCPolicy: gcPolicy,
@@ -326,6 +327,7 @@ func newGraphDriverController(ctx context.Context, rt http.RoundTripper, opt Opt
Layers: layers,
Platforms: archutil.SupportedPlatforms(true),
LeaseManager: lm,
Labels: getLabels(opt, nil),
}
wc := &worker.Controller{}
@@ -412,3 +414,11 @@ func getEntitlements(conf config.BuilderConfig) []string {
}
return ents
}
func getLabels(opt Opt, labels map[string]string) map[string]string {
if labels == nil {
labels = make(map[string]string)
}
labels[wlabel.HostGatewayIP] = opt.DNSConfig.HostGatewayIP.String()
return labels
}

View File

@@ -0,0 +1,9 @@
package label
// Pre-defined label keys similar to BuildKit ones
// https://github.com/moby/buildkit/blob/v0.11.6/worker/label/label.go#L3-L16
const (
prefix = "org.mobyproject.buildkit.worker.moby."
HostGatewayIP = prefix + "host-gateway-ip"
)

View File

@@ -50,7 +50,7 @@ import (
)
func init() {
version.Version = "v0.11.6"
version.Version = "v0.11.7+d3e6c1360f6e"
}
const labelCreatedAt = "buildkit/createdat"

View File

@@ -14,6 +14,7 @@ import (
containerpkg "github.com/docker/docker/container"
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/opencontainers/go-digest"
)
const (
@@ -45,7 +46,7 @@ type Backend interface {
// ContainerCreateWorkdir creates the workdir
ContainerCreateWorkdir(containerID string) error
CreateImage(config []byte, parent string) (Image, error)
CreateImage(ctx context.Context, config []byte, parent string, contentStoreDigest digest.Digest) (Image, error)
ImageCacheBuilder
}
@@ -104,6 +105,7 @@ type ROLayer interface {
Release() error
NewRWLayer() (RWLayer, error)
DiffID() layer.DiffID
ContentStoreDigest() digest.Digest
}
// RWLayer is active layer that can be read/modified

View File

@@ -21,7 +21,7 @@ import (
"github.com/moby/buildkit/frontend/dockerfile/instructions"
"github.com/moby/buildkit/frontend/dockerfile/parser"
"github.com/moby/buildkit/frontend/dockerfile/shell"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sync/syncmap"
@@ -125,7 +125,7 @@ type Builder struct {
pathCache pathCache
containerManager *containerManager
imageProber ImageProber
platform *specs.Platform
platform *ocispec.Platform
}
// newBuilder creates a new Dockerfile builder from an optional dockerfile and a Options.

View File

@@ -24,7 +24,7 @@ import (
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/system"
"github.com/moby/buildkit/frontend/dockerfile/instructions"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
@@ -74,7 +74,7 @@ type copier struct {
source builder.Source
pathCache pathCache
download sourceDownloader
platform *specs.Platform
platform *ocispec.Platform
// for cleanup. TODO: having copier.cleanup() is error prone and hard to
// follow. Code calling performCopy should manage the lifecycle of its params.
// Copier should take override source as input, not imageMount.
@@ -86,7 +86,7 @@ func copierFromDispatchRequest(req dispatchRequest, download sourceDownloader, i
platform := req.builder.platform
if platform == nil {
// May be nil if not explicitly set in API/dockerfile
platform = &specs.Platform{}
platform = &ocispec.Platform{}
}
if platform.OS == "" {
// Default to the dispatch requests operating system if not explicit in API/dockerfile

View File

@@ -53,31 +53,31 @@ func TestGetFilenameForDownload(t *testing.T) {
expected string
}{
{
path: "http://www.example.com/",
path: "https://www.example.com/",
expected: "",
},
{
path: "http://www.example.com/xyz",
path: "https://www.example.com/xyz",
expected: "xyz",
},
{
path: "http://www.example.com/xyz.html",
path: "https://www.example.com/xyz.html",
expected: "xyz.html",
},
{
path: "http://www.example.com/xyz/",
path: "https://www.example.com/xyz/",
expected: "",
},
{
path: "http://www.example.com/xyz/uvw",
path: "https://www.example.com/xyz/uvw",
expected: "uvw",
},
{
path: "http://www.example.com/xyz/uvw.html",
path: "https://www.example.com/xyz/uvw.html",
expected: "uvw.html",
},
{
path: "http://www.example.com/xyz/uvw/",
path: "https://www.example.com/xyz/uvw/",
expected: "",
},
{
@@ -114,23 +114,23 @@ func TestGetFilenameForDownload(t *testing.T) {
expected: "xyz.html",
},
{
disposition: "attachment; filename=\"xyz\"",
disposition: `attachment; filename="xyz"`,
expected: "xyz",
},
{
disposition: "attachment; filename=\"xyz.html\"",
disposition: `attachment; filename="xyz.html"`,
expected: "xyz.html",
},
{
disposition: "attachment; filename=\"/xyz.html\"",
disposition: `attachment; filename="/xyz.html"`,
expected: "xyz.html",
},
{
disposition: "attachment; filename=\"/xyz/uvw\"",
disposition: `attachment; filename="/xyz/uvw"`,
expected: "uvw",
},
{
disposition: "attachment; filename=\"Naïve file.txt\"",
disposition: `attachment; filename="Naïve file.txt"`,
expected: "Naïve file.txt",
},
}

View File

@@ -15,8 +15,8 @@ import (
)
var pathDenyList = map[string]bool{
"c:\\": true,
"c:\\windows": true,
`c:\`: true,
`c:\windows`: true,
}
func init() {

View File

@@ -28,7 +28,7 @@ import (
"github.com/moby/buildkit/frontend/dockerfile/parser"
"github.com/moby/buildkit/frontend/dockerfile/shell"
"github.com/moby/sys/signal"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
@@ -158,7 +158,7 @@ func initializeStage(ctx context.Context, d dispatchRequest, cmd *instructions.S
return err
}
var platform *specs.Platform
var platform *ocispec.Platform
if v := cmd.Platform; v != "" {
v, err := d.getExpandedString(d.shlex, v)
if err != nil {
@@ -232,7 +232,7 @@ func (d *dispatchRequest) getExpandedString(shlex *shell.Lex, str string) (strin
return name, nil
}
func (d *dispatchRequest) getImageOrStage(ctx context.Context, name string, platform *specs.Platform) (builder.Image, error) {
func (d *dispatchRequest) getImageOrStage(ctx context.Context, name string, platform *ocispec.Platform) (builder.Image, error) {
var localOnly bool
if im, ok := d.stages.getByName(name); ok {
name = im.Image
@@ -266,7 +266,7 @@ func (d *dispatchRequest) getImageOrStage(ctx context.Context, name string, plat
return imageMount.Image(), nil
}
func (d *dispatchRequest) getFromImage(ctx context.Context, shlex *shell.Lex, basename string, platform *specs.Platform) (builder.Image, error) {
func (d *dispatchRequest) getFromImage(ctx context.Context, shlex *shell.Lex, basename string, platform *ocispec.Platform) (builder.Image, error) {
name, err := d.getExpandedString(shlex, basename)
if err != nil {
return nil, err

View File

@@ -21,8 +21,11 @@ type dispatchTestCase struct {
files map[string]string
}
func init() {
reexec.Init()
func TestMain(m *testing.M) {
if reexec.Init() {
return
}
os.Exit(m.Run())
}
func TestDispatch(t *testing.T) {

View File

@@ -8,12 +8,12 @@ import (
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/builder"
dockerimage "github.com/docker/docker/image"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
type getAndMountFunc func(context.Context, string, bool, *specs.Platform) (builder.Image, builder.ROLayer, error)
type getAndMountFunc func(context.Context, string, bool, *ocispec.Platform) (builder.Image, builder.ROLayer, error)
// imageSources mounts images and provides a cache for mounted images. It tracks
// all images so they can be unmounted at the end of the build.
@@ -24,7 +24,7 @@ type imageSources struct {
}
func newImageSources(options builderOptions) *imageSources {
getAndMount := func(ctx context.Context, idOrRef string, localOnly bool, platform *specs.Platform) (builder.Image, builder.ROLayer, error) {
getAndMount := func(ctx context.Context, idOrRef string, localOnly bool, platform *ocispec.Platform) (builder.Image, builder.ROLayer, error) {
pullOption := backend.PullOptionNoPull
if !localOnly {
if options.Options.PullParent {
@@ -47,7 +47,7 @@ func newImageSources(options builderOptions) *imageSources {
}
}
func (m *imageSources) Get(ctx context.Context, idOrRef string, localOnly bool, platform *specs.Platform) (*imageMount, error) {
func (m *imageSources) Get(ctx context.Context, idOrRef string, localOnly bool, platform *ocispec.Platform) (*imageMount, error) {
if im, ok := m.byImageID[idOrRef]; ok {
return im, nil
}
@@ -71,7 +71,7 @@ func (m *imageSources) Unmount() (retErr error) {
return
}
func (m *imageSources) Add(im *imageMount, platform *specs.Platform) {
func (m *imageSources) Add(im *imageMount, platform *ocispec.Platform) {
switch im.image {
case nil:
// Set the platform for scratch images

View File

@@ -19,7 +19,7 @@ import (
"github.com/docker/docker/pkg/chrootarchive"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/go-connections/nat"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -63,7 +63,7 @@ func (b *Builder) commitContainer(ctx context.Context, dispatchState *dispatchSt
return err
}
func (b *Builder) exportImage(state *dispatchState, layer builder.RWLayer, parent builder.Image, runConfig *container.Config) error {
func (b *Builder) exportImage(ctx context.Context, state *dispatchState, layer builder.RWLayer, parent builder.Image, runConfig *container.Config) error {
newLayer, err := layer.Commit()
if err != nil {
return err
@@ -74,7 +74,7 @@ func (b *Builder) exportImage(state *dispatchState, layer builder.RWLayer, paren
return errors.Errorf("unexpected image type")
}
platform := &specs.Platform{
platform := &ocispec.Platform{
OS: parentImage.OS,
Architecture: parentImage.Architecture,
Variant: parentImage.Variant,
@@ -98,7 +98,15 @@ func (b *Builder) exportImage(state *dispatchState, layer builder.RWLayer, paren
return errors.Wrap(err, "failed to encode image config")
}
exportedImage, err := b.docker.CreateImage(config, state.imageID)
// when writing the new image's manifest, we now need to pass in the new layer's digest.
// before the containerd store work this was unnecessary since we get the layer id
// from the image's RootFS ChainID -- see:
// https://github.com/moby/moby/blob/8cf66ed7322fa885ef99c4c044fa23e1727301dc/image/store.go#L162
// however, with the containerd store we can't do this. An alternative implementation here
// without changing the signature would be to get the layer digest by walking the content store
// and filtering the objects to find the layer with the DiffID we want, but that has performance
// implications that should be called out/investigated
exportedImage, err := b.docker.CreateImage(ctx, config, state.imageID, newLayer.ContentStoreDigest())
if err != nil {
return errors.Wrapf(err, "failed to export image")
}
@@ -170,7 +178,7 @@ func (b *Builder) performCopy(ctx context.Context, req dispatchRequest, inst cop
return errors.Wrapf(err, "failed to copy files")
}
}
return b.exportImage(state, rwLayer, imageMount.Image(), runConfigWithCommentCmd)
return b.exportImage(ctx, state, rwLayer, imageMount.Image(), runConfigWithCommentCmd)
}
func createDestInfo(workingDir string, inst copyInstruction, rwLayer builder.RWLayer, platform string) (copyInfo, error) {

View File

@@ -1,6 +1,7 @@
package dockerfile // import "github.com/docker/docker/builder/dockerfile"
import (
"context"
"fmt"
"os"
"runtime"
@@ -193,6 +194,7 @@ type MockROLayer struct {
diffID layer.DiffID
}
func (l *MockROLayer) ContentStoreDigest() digest.Digest { return "" }
func (l *MockROLayer) Release() error { return nil }
func (l *MockROLayer) NewRWLayer() (builder.RWLayer, error) { return nil, nil }
func (l *MockROLayer) DiffID() layer.DiffID { return l.diffID }
@@ -217,6 +219,6 @@ func TestExportImage(t *testing.T) {
imageSources: getMockImageSource(nil, nil, nil),
docker: getMockBuildBackend(),
}
err := b.exportImage(ds, layer, parentImage, runConfig)
err := b.exportImage(context.TODO(), ds, layer, parentImage, runConfig)
assert.NilError(t, err)
}

View File

@@ -13,6 +13,7 @@ import (
containerpkg "github.com/docker/docker/container"
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/opencontainers/go-digest"
)
// MockBackend implements the builder.Backend interface for unit testing
@@ -80,7 +81,7 @@ func (m *MockBackend) MakeImageCache(ctx context.Context, cacheFrom []string) (b
return nil, nil
}
func (m *MockBackend) CreateImage(config []byte, parent string) (builder.Image, error) {
func (m *MockBackend) CreateImage(ctx context.Context, config []byte, parent string, layerDigest digest.Digest) (builder.Image, error) {
return &mockImage{id: "test"}, nil
}
@@ -119,6 +120,10 @@ func (mic *mockImageCache) GetCache(parentID string, cfg *container.Config) (str
type mockLayer struct{}
func (l *mockLayer) ContentStoreDigest() digest.Digest {
return ""
}
func (l *mockLayer) Release() error {
return nil
}

View File

@@ -14,9 +14,9 @@ import (
"github.com/docker/docker/builder/remotecontext/urlutil"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/containerfs"
"github.com/moby/buildkit/frontend/dockerfile/dockerignore"
"github.com/moby/buildkit/frontend/dockerfile/parser"
"github.com/moby/patternmatcher"
"github.com/moby/patternmatcher/ignorefile"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -123,10 +123,10 @@ func removeDockerfile(c modifiableContext, filesToRemove ...string) error {
case err != nil:
return err
}
excludes, err := dockerignore.ReadAll(f)
excludes, err := ignorefile.ReadAll(f)
if err != nil {
f.Close()
return err
return errors.Wrap(err, "error reading .dockerignore")
}
f.Close()
filesToRemove = append([]string{".dockerignore"}, filesToRemove...)

View File

@@ -15,7 +15,9 @@ type hashed interface {
Digest() digest.Digest
}
// CachableSource is a source that contains cache records for its contents
// CachableSource is a source that contains cache records for its contents.
//
// Deprecated: this type was used for the experimental "stream" support for the classic builder, which is no longer supported.
type CachableSource struct {
mu sync.Mutex
root string
@@ -23,7 +25,9 @@ type CachableSource struct {
txn *iradix.Txn
}
// NewCachableSource creates new CachableSource
// NewCachableSource creates new CachableSource.
//
// Deprecated: this type was used for the experimental "stream" support for the classic builder, which is no longer supported.
func NewCachableSource(root string) *CachableSource {
ts := &CachableSource{
tree: iradix.New(),

View File

@@ -17,8 +17,11 @@ const (
contents = "contents test"
)
func init() {
reexec.Init()
func TestMain(m *testing.M) {
if reexec.Init() {
return
}
os.Exit(m.Run())
}
func TestCloseRootDirectory(t *testing.T) {

View File

@@ -14,20 +14,20 @@ func TestEnable(t *testing.T) {
}()
Enable()
if os.Getenv("DEBUG") != "1" {
t.Fatalf("expected DEBUG=1, got %s\n", os.Getenv("DEBUG"))
t.Fatalf("expected DEBUG=1, got %s", os.Getenv("DEBUG"))
}
if logrus.GetLevel() != logrus.DebugLevel {
t.Fatalf("expected log level %v, got %v\n", logrus.DebugLevel, logrus.GetLevel())
t.Fatalf("expected log level %v, got %v", logrus.DebugLevel, logrus.GetLevel())
}
}
func TestDisable(t *testing.T) {
Disable()
if os.Getenv("DEBUG") != "" {
t.Fatalf("expected DEBUG=\"\", got %s\n", os.Getenv("DEBUG"))
t.Fatalf(`expected DEBUG="", got %s`, os.Getenv("DEBUG"))
}
if logrus.GetLevel() != logrus.InfoLevel {
t.Fatalf("expected log level %v, got %v\n", logrus.InfoLevel, logrus.GetLevel())
t.Fatalf("expected log level %v, got %v", logrus.InfoLevel, logrus.GetLevel())
}
}

View File

@@ -56,6 +56,36 @@ import (
"github.com/pkg/errors"
)
// DummyHost is a hostname used for local communication.
//
// It acts as a valid formatted hostname for local connections (such as "unix://"
// or "npipe://") which do not require a hostname. It should never be resolved,
// but uses the special-purpose ".localhost" TLD (as defined in [RFC 2606, Section 2]
// and [RFC 6761, Section 6.3]).
//
// [RFC 7230, Section 5.4] defines that an empty header must be used for such
// cases:
//
// If the authority component is missing or undefined for the target URI,
// then a client MUST send a Host header field with an empty field-value.
//
// However, [Go stdlib] enforces the semantics of HTTP(S) over TCP, does not
// allow an empty header to be used, and requires req.URL.Scheme to be either
// "http" or "https".
//
// For further details, refer to:
//
// - https://github.com/docker/engine-api/issues/189
// - https://github.com/golang/go/issues/13624
// - https://github.com/golang/go/issues/61076
// - https://github.com/moby/moby/issues/45935
//
// [RFC 2606, Section 2]: https://www.rfc-editor.org/rfc/rfc2606.html#section-2
// [RFC 6761, Section 6.3]: https://www.rfc-editor.org/rfc/rfc6761#section-6.3
// [RFC 7230, Section 5.4]: https://datatracker.ietf.org/doc/html/rfc7230#section-5.4
// [Go stdlib]: https://github.com/golang/go/blob/6244b1946bc2101b01955468f1be502dbadd6807/src/net/http/transport.go#L558-L569
const DummyHost = "api.moby.localhost"
// ErrRedirect is the error returned by checkRedirect when the request is non-GET.
var ErrRedirect = errors.New("unexpected redirect in response")

View File

@@ -9,7 +9,7 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/versions"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
type configWrapper struct {
@@ -20,7 +20,7 @@ type configWrapper struct {
// ContainerCreate creates a new container based on the given configuration.
// It can be associated with a name, but it's not mandatory.
func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (container.CreateResponse, error) {
func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) {
var response container.CreateResponse
if err := cli.NewVersionError("1.25", "stop timeout"); config != nil && config.StopTimeout != nil && err != nil {
@@ -75,7 +75,7 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config
// Similar to containerd's platforms.Format(), but does allow components to be
// omitted (e.g. pass "architecture" only, without "os":
// https://github.com/containerd/containerd/blob/v1.5.2/platforms/platforms.go#L243-L263
func formatPlatform(platform *specs.Platform) string {
func formatPlatform(platform *ocispec.Platform) string {
if platform == nil {
return ""
}

View File

@@ -23,14 +23,10 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu
if err != nil {
return types.HijackedResponse{}, err
}
apiPath := cli.getAPIPath(ctx, path, query)
req, err := http.NewRequest(http.MethodPost, apiPath, bodyEncoded)
req, err := cli.buildRequest(http.MethodPost, cli.getAPIPath(ctx, path, query), bodyEncoded, headers)
if err != nil {
return types.HijackedResponse{}, err
}
req = cli.addHeaders(req, headers)
conn, mediaType, err := cli.setupHijackConn(ctx, req, "tcp")
if err != nil {
return types.HijackedResponse{}, err
@@ -64,7 +60,6 @@ func fallbackDial(proto, addr string, tlsConfig *tls.Config) (net.Conn, error) {
}
func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto string) (net.Conn, string, error) {
req.Host = cli.addr
req.Header.Set("Connection", "Upgrade")
req.Header.Set("Upgrade", proto)
@@ -80,8 +75,8 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto
// state. Setting TCP KeepAlive on the socket connection will prohibit
// ECONNTIMEOUT unless the socket connection truly is broken
if tcpConn, ok := conn.(*net.TCPConn); ok {
tcpConn.SetKeepAlive(true)
tcpConn.SetKeepAlivePeriod(30 * time.Second)
_ = tcpConn.SetKeepAlive(true)
_ = tcpConn.SetKeepAlivePeriod(30 * time.Second)
}
clientconn := httputil.NewClientConn(conn, nil)
@@ -96,7 +91,7 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto
return nil, "", err
}
if resp.StatusCode != http.StatusSwitchingProtocols {
resp.Body.Close()
_ = resp.Body.Close()
return nil, "", fmt.Errorf("unable to upgrade to %s, received %d", proto, resp.StatusCode)
}
}

View File

@@ -42,7 +42,7 @@ func TestImageTagInvalidSourceImageName(t *testing.T) {
}
err := client.ImageTag(context.Background(), "invalid_source_image_name_", "repo:tag")
if err == nil || err.Error() != "Error parsing reference: \"invalid_source_image_name_\" is not a valid repository/tag: invalid reference format" {
if err == nil || err.Error() != `Error parsing reference: "invalid_source_image_name_" is not a valid repository/tag: invalid reference format` {
t.Fatalf("expected Parsing Reference Error, got %v", err)
}
}

View File

@@ -15,7 +15,7 @@ import (
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/volume"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// CommonAPIClient is the common methods between stable and experimental versions of APIClient.
@@ -47,7 +47,7 @@ type CommonAPIClient interface {
type ContainerAPIClient interface {
ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error)
ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.IDResponse, error)
ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (container.CreateResponse, error)
ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error)
ContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error)
ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error)
ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error)

View File

@@ -96,16 +96,14 @@ func (cli *Client) buildRequest(method, path string, body io.Reader, headers hea
return nil, err
}
req = cli.addHeaders(req, headers)
req.URL.Scheme = cli.scheme
req.URL.Host = cli.addr
if cli.proto == "unix" || cli.proto == "npipe" {
// For local communications, it doesn't matter what the host is. We just
// need a valid and meaningful host name. (See #189)
req.Host = "docker"
// Override host header for non-tcp connections.
req.Host = DummyHost
}
req.URL.Host = cli.addr
req.URL.Scheme = cli.scheme
if expectedPayload && req.Header.Get("Content-Type") == "" {
req.Header.Set("Content-Type", "text/plain")
}

View File

@@ -28,24 +28,24 @@ func TestSetHostHeader(t *testing.T) {
expectedURLHost string
}{
{
"unix:///var/run/docker.sock",
"docker",
"/var/run/docker.sock",
host: "unix:///var/run/docker.sock",
expectedHost: DummyHost,
expectedURLHost: "/var/run/docker.sock",
},
{
"npipe:////./pipe/docker_engine",
"docker",
"//./pipe/docker_engine",
host: "npipe:////./pipe/docker_engine",
expectedHost: DummyHost,
expectedURLHost: "//./pipe/docker_engine",
},
{
"tcp://0.0.0.0:4243",
"",
"0.0.0.0:4243",
host: "tcp://0.0.0.0:4243",
expectedHost: "",
expectedURLHost: "0.0.0.0:4243",
},
{
"tcp://localhost:4243",
"",
"localhost:4243",
host: "tcp://localhost:4243",
expectedHost: "",
expectedURLHost: "localhost:4243",
},
}

View File

@@ -15,7 +15,7 @@ import (
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/errdefs"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
@@ -91,10 +91,10 @@ func TestServiceCreateCompatiblePlatforms(t *testing.T) {
}, nil
} else if strings.HasPrefix(req.URL.Path, "/v1.30/distribution/") {
b, err := json.Marshal(registrytypes.DistributionInspect{
Descriptor: v1.Descriptor{
Descriptor: ocispec.Descriptor{
Digest: "sha256:c0537ff6a5218ef531ece93d4984efc99bbf3f7497c0a7726c88e2bb7584dc96",
},
Platforms: []v1.Platform{
Platforms: []ocispec.Platform{
{
Architecture: "amd64",
OS: "linux",
@@ -171,7 +171,7 @@ func TestServiceCreateDigestPinning(t *testing.T) {
} else if strings.HasPrefix(req.URL.Path, "/v1.30/distribution/") {
// resolvable images
b, err := json.Marshal(registrytypes.DistributionInspect{
Descriptor: v1.Descriptor{
Descriptor: ocispec.Descriptor{
Digest: digest.Digest(dgst),
},
})

View File

@@ -351,6 +351,7 @@ func newRouterOptions(ctx context.Context, config *config.Config, d *daemon.Daem
bk, err := buildkit.New(ctx, buildkit.Opt{
SessionManager: sm,
Root: filepath.Join(config.Root, "buildkit"),
EngineID: d.ID(),
Dist: d.DistributionServices(),
ImageTagger: d.ImageService(),
NetworkController: d.NetworkController(),

View File

@@ -7,7 +7,6 @@ import (
"io"
"log"
"os"
"os/exec"
"path/filepath"
"time"
@@ -145,16 +144,8 @@ func (h *etwHook) Fire(e *logrus.Entry) error {
return windows.ReportEvent(h.log.Handle, etype, 0, eid, 0, count, 0, &ss[0], nil)
}
func getServicePath() (string, error) {
p, err := exec.LookPath(os.Args[0])
if err != nil {
return "", err
}
return filepath.Abs(p)
}
func registerService() error {
p, err := getServicePath()
p, err := os.Executable()
if err != nil {
return err
}

View File

@@ -6,13 +6,9 @@ import (
"os"
"path"
"text/template"
"github.com/docker/docker/pkg/aaparser"
)
type profileData struct {
Version int
}
type profileData struct{}
func main() {
if len(os.Args) < 2 {
@@ -22,15 +18,6 @@ func main() {
// parse the arg
apparmorProfilePath := os.Args[1]
version, err := aaparser.GetVersion()
if err != nil {
log.Fatal(err)
}
data := profileData{
Version: version,
}
fmt.Printf("apparmor_parser is of version %+v\n", data)
// parse the template
compiled, err := template.New("apparmor_profile").Parse(dockerProfileTemplate)
if err != nil {
@@ -48,6 +35,7 @@ func main() {
}
defer f.Close()
data := profileData{}
if err := compiled.Execute(f, data); err != nil {
log.Fatalf("executing template failed: %v", err)
}

View File

@@ -149,9 +149,7 @@ profile /usr/bin/docker (attach_disconnected, complain) {
}
# xz works via pipes, so we do not need access to the filesystem.
profile /usr/bin/xz (complain) {
{{if ge .Version 209000}}
signal (receive) peer=/usr/bin/docker,
{{end}}
/etc/ld.so.cache r,
/lib/** rm,
/usr/bin/xz rm,

View File

@@ -10,10 +10,10 @@
# To publish: Needs someone with publishing rights
ARG WINDOWS_BASE_IMAGE=mcr.microsoft.com/windows/servercore
ARG WINDOWS_BASE_IMAGE_TAG=ltsc2022
ARG BUSYBOX_VERSION=FRP-3329-gcf0fa4d13
ARG BUSYBOX_VERSION=FRP-5007-g82accfc19
# Checksum taken from https://frippery.org/files/busybox/SHA256SUM
ARG BUSYBOX_SHA256SUM=bfaeb88638e580fc522a68e69072e305308f9747563e51fa085eec60ca39a5ae
ARG BUSYBOX_SHA256SUM=2d6fff0b2de5c034c92990d696c0d85a677b8a75931fa1ec30694fbf1f1df5c9
FROM ${WINDOWS_BASE_IMAGE}:${WINDOWS_BASE_IMAGE_TAG}
RUN mkdir C:\tmp && mkdir C:\bin

View File

@@ -218,7 +218,7 @@ check_flags \
CGROUPS CGROUP_CPUACCT CGROUP_DEVICE CGROUP_FREEZER CGROUP_SCHED CPUSETS MEMCG \
KEYS \
VETH BRIDGE BRIDGE_NETFILTER \
IP_NF_FILTER IP_NF_TARGET_MASQUERADE \
IP_NF_FILTER IP_NF_MANGLE IP_NF_TARGET_MASQUERADE \
NETFILTER_XT_MATCH_ADDRTYPE \
NETFILTER_XT_MATCH_CONNTRACK \
NETFILTER_XT_MATCH_IPVS \
@@ -351,7 +351,7 @@ echo " - \"$(wrap_color 'overlay' blue)\":"
check_flags VXLAN BRIDGE_VLAN_FILTERING | sed 's/^/ /'
echo ' Optional (for encrypted networks):'
check_flags CRYPTO CRYPTO_AEAD CRYPTO_GCM CRYPTO_SEQIV CRYPTO_GHASH \
XFRM XFRM_USER XFRM_ALGO INET_ESP | sed 's/^/ /'
XFRM XFRM_USER XFRM_ALGO INET_ESP NETFILTER_XT_MATCH_BPF | sed 's/^/ /'
if [ "$kernelMajor" -lt 5 ] || [ "$kernelMajor" -eq 5 -a "$kernelMinor" -le 3 ]; then
check_flags INET_XFRM_MODE_TRANSPORT | sed 's/^/ /'
fi

View File

@@ -37,6 +37,8 @@ BIN=""
SYSTEMD=""
CFG_DIR=""
XDG_RUNTIME_DIR_CREATED=""
USERNAME=""
USERNAME_ESCAPED=""
# run checks and also initialize global vars
init() {
@@ -78,6 +80,11 @@ init() {
exit 1
fi
# Set USERNAME from `id -un` and potentially protect backslash
# for windbind/samba domain users
USERNAME=$(id -un)
USERNAME_ESCAPED=$(echo $USERNAME | sed 's/\\/\\\\/g')
# set CFG_DIR
CFG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}"
@@ -222,21 +229,21 @@ init() {
fi
# instructions: validate subuid/subgid files for current user
if ! grep -q "^$(id -un):\|^$(id -u):" /etc/subuid 2> /dev/null; then
if ! grep -q "^$USERNAME_ESCAPED:\|^$(id -u):" /etc/subuid 2> /dev/null; then
instructions=$(
cat <<- EOI
${instructions}
# Add subuid entry for $(id -un)
echo "$(id -un):100000:65536" >> /etc/subuid
# Add subuid entry for ${USERNAME}
echo "${USERNAME}:100000:65536" >> /etc/subuid
EOI
)
fi
if ! grep -q "^$(id -un):\|^$(id -u):" /etc/subgid 2> /dev/null; then
if ! grep -q "^$USERNAME_ESCAPED:\|^$(id -u):" /etc/subgid 2> /dev/null; then
instructions=$(
cat <<- EOI
${instructions}
# Add subgid entry for $(id -un)
echo "$(id -un):100000:65536" >> /etc/subgid
# Add subgid entry for ${USERNAME}
echo "${USERNAME}:100000:65536" >> /etc/subgid
EOI
)
fi
@@ -340,7 +347,7 @@ install_systemd() {
)
INFO "Installed ${SYSTEMD_UNIT} successfully."
INFO "To control ${SYSTEMD_UNIT}, run: \`systemctl --user (start|stop|restart) ${SYSTEMD_UNIT}\`"
INFO "To run ${SYSTEMD_UNIT} on system startup, run: \`sudo loginctl enable-linger $(id -un)\`"
INFO "To run ${SYSTEMD_UNIT} on system startup, run: \`sudo loginctl enable-linger ${USERNAME}\`"
echo
}

View File

@@ -44,14 +44,6 @@ if [ ! -x $DOCKERD ]; then
exit 1
fi
check_init() {
# see also init_is_upstart in /lib/lsb/init-functions (which isn't available in Ubuntu 12.04, or we'd use it directly)
if [ -x /sbin/initctl ] && /sbin/initctl version 2> /dev/null | grep -q upstart; then
log_failure_msg "$DOCKER_DESC is managed via upstart, try using service $BASE $1"
exit 1
fi
}
fail_unless_root() {
if [ "$(id -u)" != '0' ]; then
log_failure_msg "$DOCKER_DESC must be run as root"
@@ -59,37 +51,10 @@ fail_unless_root() {
fi
}
cgroupfs_mount() {
# see also https://github.com/tianon/cgroupfs-mount/blob/master/cgroupfs-mount
if grep -v '^#' /etc/fstab | grep -q cgroup \
|| [ ! -e /proc/cgroups ] \
|| [ ! -d /sys/fs/cgroup ]; then
return
fi
if ! mountpoint -q /sys/fs/cgroup; then
mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup
fi
(
cd /sys/fs/cgroup
for sys in $(awk '!/^#/ { if ($4 == 1) print $1 }' /proc/cgroups); do
mkdir -p $sys
if ! mountpoint -q $sys; then
if ! mount -n -t cgroup -o $sys cgroup $sys; then
rmdir $sys || true
fi
fi
done
)
}
case "$1" in
start)
check_init
fail_unless_root
cgroupfs_mount
touch "$DOCKER_LOGFILE"
chgrp docker "$DOCKER_LOGFILE"
@@ -117,7 +82,6 @@ case "$1" in
;;
stop)
check_init
fail_unless_root
if [ -f "$DOCKER_SSD_PIDFILE" ]; then
log_begin_msg "Stopping $DOCKER_DESC: $BASE"
@@ -129,7 +93,6 @@ case "$1" in
;;
restart)
check_init
fail_unless_root
docker_pid=$(cat "$DOCKER_SSD_PIDFILE" 2> /dev/null || true)
[ -n "$docker_pid" ] \
@@ -139,13 +102,11 @@ case "$1" in
;;
force-reload)
check_init
fail_unless_root
$0 restart
;;
status)
check_init
status_of_proc -p "$DOCKER_SSD_PIDFILE" "$DOCKERD" "$DOCKER_DESC"
;;

View File

@@ -1,4 +1,4 @@
# Docker Upstart and SysVinit configuration file
# Docker SysVinit configuration file
#
# THIS FILE DOES NOT APPLY TO SYSTEMD

View File

@@ -1,72 +0,0 @@
description "Docker daemon"
start on (filesystem and net-device-up IFACE!=lo)
stop on runlevel [!2345]
limit nofile 524288 1048576
# Having non-zero limits causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
limit nproc unlimited unlimited
respawn
kill timeout 20
pre-start script
# see also https://github.com/tianon/cgroupfs-mount/blob/master/cgroupfs-mount
if grep -v '^#' /etc/fstab | grep -q cgroup \
|| [ ! -e /proc/cgroups ] \
|| [ ! -d /sys/fs/cgroup ]; then
exit 0
fi
if ! mountpoint -q /sys/fs/cgroup; then
mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup
fi
(
cd /sys/fs/cgroup
for sys in $(awk '!/^#/ { if ($4 == 1) print $1 }' /proc/cgroups); do
mkdir -p $sys
if ! mountpoint -q $sys; then
if ! mount -n -t cgroup -o $sys cgroup $sys; then
rmdir $sys || true
fi
fi
done
)
end script
script
# modify these in /etc/default/$UPSTART_JOB (/etc/default/docker)
DOCKERD=/usr/bin/dockerd
DOCKER_OPTS=
if [ -f /etc/default/$UPSTART_JOB ]; then
. /etc/default/$UPSTART_JOB
fi
exec "$DOCKERD" $DOCKER_OPTS --raw-logs
end script
# Don't emit "started" event until docker.sock is ready.
# See https://github.com/docker/docker/issues/6647
post-start script
DOCKER_OPTS=
DOCKER_SOCKET=
if [ -f /etc/default/$UPSTART_JOB ]; then
. /etc/default/$UPSTART_JOB
fi
if ! printf "%s" "$DOCKER_OPTS" | grep -qE -e '-H|--host'; then
DOCKER_SOCKET=/var/run/docker.sock
else
DOCKER_SOCKET=$(printf "%s" "$DOCKER_OPTS" | grep -oP -e '(-H|--host)\W*unix://\K(\S+)' | sed 1q)
fi
if [ -n "$DOCKER_SOCKET" ]; then
while ! [ -e "$DOCKER_SOCKET" ]; do
initctl status $UPSTART_JOB | grep -qE "(stop|respawn)/" && exit 1
echo "Waiting for $DOCKER_SOCKET"
sleep 0.1
done
echo "$DOCKER_SOCKET is up"
fi
end script

View File

@@ -140,7 +140,7 @@ type attacher struct {
// New creates a new Cluster instance using provided config.
func New(config Config) (*Cluster, error) {
root := filepath.Join(config.Root, swarmDirName)
if err := os.MkdirAll(root, 0700); err != nil {
if err := os.MkdirAll(root, 0o700); err != nil {
return nil, err
}
if config.RuntimeRoot == "" {
@@ -154,7 +154,7 @@ func New(config Config) (*Cluster, error) {
config.RaftElectionTick = 10 * config.RaftHeartbeatTick
}
if err := os.MkdirAll(config.RuntimeRoot, 0700); err != nil {
if err := os.MkdirAll(config.RuntimeRoot, 0o700); err != nil {
return nil, err
}
c := &Cluster{
@@ -359,7 +359,7 @@ func (c *Cluster) errNoManager(st nodeState) error {
if st.err == errSwarmCertificatesExpired {
return errSwarmCertificatesExpired
}
return errors.WithStack(notAvailableError("This node is not a swarm manager. Use \"docker swarm init\" or \"docker swarm join\" to connect this node to swarm and try again."))
return errors.WithStack(notAvailableError(`This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.`))
}
if st.swarmNode.Manager() != nil {
return errors.WithStack(notAvailableError("This node is not a swarm manager. Manager is being prepared or has trouble connecting to the cluster."))

View File

@@ -65,7 +65,8 @@ func NewController(backend Backend, t *api.Task) (*Controller, error) {
"controller": "plugin",
"task": t.ID,
"plugin": spec.Name,
})}, nil
}),
}, nil
}
func readSpec(t *api.Task) (runtime.PluginSpec, error) {

View File

@@ -118,7 +118,8 @@ func endpointFromGRPC(e *swarmapi.Endpoint) types.Endpoint {
for _, v := range e.VirtualIPs {
endpoint.VirtualIPs = append(endpoint.VirtualIPs, types.EndpointVirtualIP{
NetworkID: v.NetworkID,
Addr: v.Addr})
Addr: v.Addr,
})
}
}

View File

@@ -58,13 +58,20 @@ func NodeFromGRPC(n swarmapi.Node) types.Node {
}
for _, csi := range n.Description.CSIInfo {
if csi != nil {
convertedInfo := types.NodeCSIInfo{
PluginName: csi.PluginName,
NodeID: csi.NodeID,
MaxVolumesPerNode: csi.MaxVolumesPerNode,
}
if csi.AccessibleTopology != nil {
convertedInfo.AccessibleTopology = &types.Topology{
Segments: csi.AccessibleTopology.Segments,
}
}
node.Description.CSIInfo = append(
node.Description.CSIInfo,
types.NodeCSIInfo{
PluginName: csi.PluginName,
NodeID: csi.NodeID,
MaxVolumesPerNode: csi.MaxVolumesPerNode,
},
node.Description.CSIInfo, convertedInfo,
)
}
}

View File

@@ -0,0 +1,60 @@
package convert
import (
"testing"
types "github.com/docker/docker/api/types/swarm"
swarmapi "github.com/moby/swarmkit/v2/api"
"gotest.tools/v3/assert"
)
// TestNodeCSIInfoFromGRPC tests that conversion of the NodeCSIInfo from the
// gRPC to the Docker types is correct.
func TestNodeCSIInfoFromGRPC(t *testing.T) {
node := &swarmapi.Node{
ID: "someID",
Description: &swarmapi.NodeDescription{
CSIInfo: []*swarmapi.NodeCSIInfo{
{
PluginName: "plugin1",
NodeID: "p1n1",
MaxVolumesPerNode: 1,
},
{
PluginName: "plugin2",
NodeID: "p2n1",
MaxVolumesPerNode: 2,
AccessibleTopology: &swarmapi.Topology{
Segments: map[string]string{
"a": "1",
"b": "2",
},
},
},
},
},
}
expected := []types.NodeCSIInfo{
{
PluginName: "plugin1",
NodeID: "p1n1",
MaxVolumesPerNode: 1,
},
{
PluginName: "plugin2",
NodeID: "p2n1",
MaxVolumesPerNode: 2,
AccessibleTopology: &types.Topology{
Segments: map[string]string{
"a": "1",
"b": "2",
},
},
},
}
actual := NodeFromGRPC(*node)
assert.DeepEqual(t, actual.Description.CSIInfo, expected)
}

View File

@@ -5,13 +5,13 @@ const (
errNoSwarm notAvailableError = "This node is not part of a swarm"
// errSwarmExists is returned on initialize or join request for a cluster that has already been activated
errSwarmExists notAvailableError = "This node is already part of a swarm. Use \"docker swarm leave\" to leave this swarm and join another one."
errSwarmExists notAvailableError = `This node is already part of a swarm. Use "docker swarm leave" to leave this swarm and join another one.`
// errSwarmJoinTimeoutReached is returned when cluster join could not complete before timeout was reached.
errSwarmJoinTimeoutReached notAvailableError = "Timeout was reached before node joined. The attempt to join the swarm will continue in the background. Use the \"docker info\" command to see the current swarm status of your node."
errSwarmJoinTimeoutReached notAvailableError = `Timeout was reached before node joined. The attempt to join the swarm will continue in the background. Use the "docker info" command to see the current swarm status of your node.`
// errSwarmLocked is returned if the swarm is encrypted and needs a key to unlock it.
errSwarmLocked notAvailableError = "Swarm is encrypted and needs to be unlocked before it can be used. Please use \"docker swarm unlock\" to unlock it."
errSwarmLocked notAvailableError = `Swarm is encrypted and needs to be unlocked before it can be used. Please use "docker swarm unlock" to unlock it.`
// errSwarmCertificatesExpired is returned if docker was not started for the whole validity period and they had no chance to renew automatically.
errSwarmCertificatesExpired notAvailableError = "Swarm certificates have expired. To replace them, leave the swarm and join again."

View File

@@ -27,7 +27,7 @@ import (
"github.com/docker/docker/plugin"
volumeopts "github.com/docker/docker/volume/service/opts"
"github.com/moby/swarmkit/v2/agent/exec"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// Backend defines the executor component for a swarm agent.
@@ -75,7 +75,7 @@ type VolumeBackend interface {
// ImageBackend is used by an executor to perform image operations
type ImageBackend interface {
PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
PullImage(ctx context.Context, image, tag string, platform *ocispec.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
GetRepository(context.Context, reference.Named, *registry.AuthConfig) (distribution.Repository, error)
GetImage(ctx context.Context, refOrID string, options opts.GetImageOpts) (*image.Image, error)
}

View File

@@ -412,7 +412,7 @@ func (c *containerAdapter) wait(ctx context.Context) (<-chan containerpkg.StateS
}
func (c *containerAdapter) shutdown(ctx context.Context) error {
var options = containertypes.StopOptions{}
options := containertypes.StopOptions{}
// Default stop grace period to nil (daemon will use the stopTimeout of the container)
if spec := c.container.spec(); spec.StopGracePeriod != nil {
timeout := int(spec.StopGracePeriod.Seconds)

View File

@@ -1,9 +1,8 @@
package container // import "github.com/docker/docker/daemon/cluster/executor/container"
import (
"testing"
"context"
"testing"
"time"
"github.com/docker/docker/daemon"

View File

@@ -142,6 +142,7 @@ func getDataPathPort(portNum uint32) (uint32, error) {
}
return portNum, nil
}
func resolveDataPathAddr(dataPathAddr string) (string, error) {
if dataPathAddr == "" {
// dataPathAddr is not defined

View File

@@ -456,7 +456,7 @@ func (c *Cluster) ServiceLogs(ctx context.Context, selector *backend.LogSelector
} else {
t, err := strconv.Atoi(config.Tail)
if err != nil {
return nil, errors.New("tail value must be a positive integer or \"all\"")
return nil, errors.New(`tail value must be a positive integer or "all"`)
}
if t < 0 {
return nil, errors.New("negative tail values not supported")

View File

@@ -32,7 +32,7 @@ func savePersistentState(root string, config nodeStartConfig) error {
if err != nil {
return err
}
return ioutils.AtomicWriteFile(filepath.Join(root, stateFile), dt, 0600)
return ioutils.AtomicWriteFile(filepath.Join(root, stateFile), dt, 0o600)
}
func clearPersistentState(root string) error {

View File

@@ -744,6 +744,12 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName
return nil
}
if idOrName != container.HostConfig.NetworkMode.NetworkName() {
if err := daemon.normalizeNetMode(container); err != nil {
return err
}
}
var operIPAM bool
if config != nil {
if epConfig, ok := config.EndpointsConfig[n.Name()]; ok {
@@ -946,6 +952,25 @@ func (daemon *Daemon) tryDetachContainerFromClusterNetwork(network libnetwork.Ne
daemon.LogNetworkEventWithAttributes(network, "disconnect", attributes)
}
// normalizeNetMode checks whether the network mode references a network by a partial ID. In that case, it replaces the
// partial ID with the full network ID.
// TODO(aker): transform ID into name when the referenced network is one of the predefined.
func (daemon *Daemon) normalizeNetMode(container *container.Container) error {
if container.HostConfig.NetworkMode.IsUserDefined() {
netMode := container.HostConfig.NetworkMode.NetworkName()
nw, err := daemon.FindNetwork(netMode)
if err != nil {
return fmt.Errorf("could not find a network matching network mode %s: %w", netMode, err)
}
if netMode != nw.ID() && netMode != nw.Name() {
container.HostConfig.NetworkMode = containertypes.NetworkMode(nw.ID())
}
}
return nil
}
func (daemon *Daemon) initializeNetworking(container *container.Container) error {
var err error
@@ -1002,10 +1027,17 @@ func (daemon *Daemon) getNetworkedContainer(containerID, connectedContainerID st
func (daemon *Daemon) releaseNetwork(container *container.Container) {
start := time.Now()
// If live-restore is enabled, the daemon cleans up dead containers when it starts up. In that case, the
// netController hasn't been initialized yet and so we can't proceed.
// TODO(aker): If we hit this case, the endpoint state won't be cleaned up (ie. no call to cleanOperationalData).
if daemon.netController == nil {
return
}
if container.HostConfig.NetworkMode.IsContainer() || container.Config.NetworkDisabled {
// If the container uses the network namespace of another container, it doesn't own it -- nothing to do here.
if container.HostConfig.NetworkMode.IsContainer() {
return
}
if container.NetworkSettings == nil {
return
}

View File

@@ -2,11 +2,92 @@ package containerd
import (
"context"
"reflect"
"strings"
"github.com/docker/docker/api/types/container"
imagetype "github.com/docker/docker/api/types/image"
"github.com/docker/docker/builder"
"github.com/docker/docker/image"
)
// MakeImageCache creates a stateful image cache.
func (i *ImageService) MakeImageCache(ctx context.Context, cacheFrom []string) (builder.ImageCache, error) {
panic("not implemented")
images := []*image.Image{}
for _, c := range cacheFrom {
im, err := i.GetImage(ctx, c, imagetype.GetImageOpts{})
if err != nil {
return nil, err
}
images = append(images, im)
}
return &imageCache{images: images, c: i}, nil
}
type imageCache struct {
images []*image.Image
c *ImageService
}
func (ic *imageCache) GetCache(parentID string, cfg *container.Config) (imageID string, err error) {
ctx := context.TODO()
if parentID == "" {
// TODO handle "parentless" image cache lookups ("FROM scratch")
return "", nil
}
parent, err := ic.c.GetImage(ctx, parentID, imagetype.GetImageOpts{})
if err != nil {
return "", err
}
for _, localCachedImage := range ic.images {
if isMatch(localCachedImage, parent, cfg) {
return localCachedImage.ID().String(), nil
}
}
children, err := ic.c.Children(ctx, parent.ID())
if err != nil {
return "", err
}
for _, children := range children {
childImage, err := ic.c.GetImage(ctx, children.String(), imagetype.GetImageOpts{})
if err != nil {
return "", err
}
if isMatch(childImage, parent, cfg) {
return children.String(), nil
}
}
return "", nil
}
// isMatch checks whether a given target can be used as cache for the given
// parent image/config combination.
// A target can only be an immediate child of the given parent image. For
// a parent image with `n` history entries, a valid target must have `n+1`
// entries and the extra entry must match the provided config
func isMatch(target, parent *image.Image, cfg *container.Config) bool {
if target == nil || parent == nil || cfg == nil {
return false
}
if len(target.History) != len(parent.History)+1 ||
len(target.RootFS.DiffIDs) != len(parent.RootFS.DiffIDs)+1 {
return false
}
for i := range parent.History {
if !reflect.DeepEqual(parent.History[i], target.History[i]) {
return false
}
}
childCreatedBy := target.History[len(target.History)-1].CreatedBy
return childCreatedBy == strings.Join(cfg.Cmd, " ")
}

View File

@@ -9,16 +9,13 @@ import (
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// walkPresentChildren is a simple wrapper for containerdimages.Walk with
// presentChildrenHandler wrapping a simple handler that only operates on
// walked Descriptor and doesn't return any errror.
// walkPresentChildren is a simple wrapper for containerdimages.Walk with presentChildrenHandler.
// This is only a convenient helper to reduce boilerplate.
func (i *ImageService) walkPresentChildren(ctx context.Context, target ocispec.Descriptor, f func(context.Context, ocispec.Descriptor)) error {
func (i *ImageService) walkPresentChildren(ctx context.Context, target ocispec.Descriptor, f func(context.Context, ocispec.Descriptor) error) error {
store := i.client.ContentStore()
return containerdimages.Walk(ctx, presentChildrenHandler(store, containerdimages.HandlerFunc(
func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
f(ctx, desc)
return nil, nil
return nil, f(ctx, desc)
})), target)
}

View File

@@ -2,14 +2,13 @@ package containerd
import (
"context"
"encoding/json"
"fmt"
"regexp"
"sort"
"strconv"
"sync/atomic"
"time"
"github.com/containerd/containerd/content"
cerrdefs "github.com/containerd/containerd/errdefs"
containerdimages "github.com/containerd/containerd/images"
cplatforms "github.com/containerd/containerd/platforms"
@@ -33,7 +32,7 @@ var truncatedID = regexp.MustCompile(`^([a-f0-9]{4,64})$`)
// GetImage returns an image corresponding to the image referred to by refOrID.
func (i *ImageService) GetImage(ctx context.Context, refOrID string, options imagetype.GetImageOpts) (*image.Image, error) {
desc, err := i.resolveDescriptor(ctx, refOrID)
desc, err := i.resolveImage(ctx, refOrID)
if err != nil {
return nil, err
}
@@ -44,20 +43,46 @@ func (i *ImageService) GetImage(ctx context.Context, refOrID string, options ima
}
cs := i.client.ContentStore()
conf, err := containerdimages.Config(ctx, cs, desc, platform)
var presentImages []ocispec.Image
err = i.walkImageManifests(ctx, desc, func(img *ImageManifest) error {
conf, err := img.Config(ctx)
if err != nil {
if cerrdefs.IsNotFound(err) {
logrus.WithFields(logrus.Fields{
"manifestDescriptor": img.Target(),
}).Debug("manifest was present, but accessing its config failed, ignoring")
return nil
}
return errdefs.System(fmt.Errorf("failed to get config descriptor: %w", err))
}
var ociimage ocispec.Image
if err := readConfig(ctx, cs, conf, &ociimage); err != nil {
if cerrdefs.IsNotFound(err) {
logrus.WithFields(logrus.Fields{
"manifestDescriptor": img.Target(),
"configDescriptor": conf,
}).Debug("manifest present, but its config is missing, ignoring")
return nil
}
return errdefs.System(fmt.Errorf("failed to read config of the manifest %v: %w", img.Target().Digest, err))
}
presentImages = append(presentImages, ociimage)
return nil
})
if err != nil {
return nil, err
}
imageConfigBytes, err := content.ReadBlob(ctx, cs, conf)
if err != nil {
return nil, err
if len(presentImages) == 0 {
ref, _ := reference.ParseAnyReference(refOrID)
return nil, images.ErrImageDoesNotExist{Ref: ref}
}
var ociimage ocispec.Image
if err := json.Unmarshal(imageConfigBytes, &ociimage); err != nil {
return nil, err
}
sort.SliceStable(presentImages, func(i, j int) bool {
return platform.Less(presentImages[i].Platform, presentImages[j].Platform)
})
ociimage := presentImages[0]
rootfs := image.NewRootFS()
for _, id := range ociimage.RootFS.DiffIDs {
@@ -68,11 +93,31 @@ func (i *ImageService) GetImage(ctx context.Context, refOrID string, options ima
exposedPorts[nat.Port(k)] = v
}
img := image.NewImage(image.ID(desc.Digest))
derefTimeSafely := func(t *time.Time) time.Time {
if t != nil {
return *t
}
return time.Time{}
}
var imgHistory []image.History
for _, h := range ociimage.History {
imgHistory = append(imgHistory, image.History{
Created: derefTimeSafely(h.Created),
Author: h.Author,
CreatedBy: h.CreatedBy,
Comment: h.Comment,
EmptyLayer: h.EmptyLayer,
})
}
img := image.NewImage(image.ID(desc.Target.Digest))
img.V1Image = image.V1Image{
ID: string(desc.Digest),
ID: string(desc.Target.Digest),
OS: ociimage.OS,
Architecture: ociimage.Architecture,
Created: derefTimeSafely(ociimage.Created),
Variant: ociimage.Variant,
Config: &containertypes.Config{
Entrypoint: ociimage.Config.Entrypoint,
Env: ociimage.Config.Env,
@@ -87,20 +132,21 @@ func (i *ImageService) GetImage(ctx context.Context, refOrID string, options ima
}
img.RootFS = rootfs
img.History = imgHistory
if options.Details {
lastUpdated := time.Unix(0, 0)
size, err := i.size(ctx, desc, platform)
size, err := i.size(ctx, desc.Target, platform)
if err != nil {
return nil, err
}
tagged, err := i.client.ImageService().List(ctx, "target.digest=="+desc.Digest.String())
tagged, err := i.client.ImageService().List(ctx, "target.digest=="+desc.Target.Digest.String())
if err != nil {
return nil, err
}
// Each image will result in 2 references (named and digested).
// Usually each image will result in 2 references (named and digested).
refs := make([]reference.Named, 0, len(tagged)*2)
for _, i := range tagged {
if i.UpdatedAt.After(lastUpdated) {
@@ -125,7 +171,12 @@ func (i *ImageService) GetImage(ctx context.Context, refOrID string, options ima
}
refs = append(refs, name)
digested, err := reference.WithDigest(reference.TrimNamed(name), desc.Digest)
if _, ok := name.(reference.Digested); ok {
// Image name already contains a digest, so no need to create a digested reference.
continue
}
digested, err := reference.WithDigest(reference.TrimNamed(name), desc.Target.Digest)
if err != nil {
// This could only happen if digest is invalid, but considering that
// we get it from the Descriptor it's highly unlikely.
@@ -244,6 +295,24 @@ func (i *ImageService) resolveImage(ctx context.Context, refOrID string) (contai
return containerdimages.Image{}, images.ErrImageDoesNotExist{Ref: parsed}
}
// If reference is both Named and Digested, make sure we don't match
// images with a different repository even if digest matches.
// For example, busybox@sha256:abcdef..., shouldn't match asdf@sha256:abcdef...
if parsedNamed, ok := parsed.(reference.Named); ok {
for _, img := range imgs {
imgNamed, err := reference.ParseNormalizedNamed(img.Name)
if err != nil {
logrus.WithError(err).WithField("image", img.Name).Warn("image with invalid name encountered")
continue
}
if parsedNamed.Name() == imgNamed.Name() {
return img, nil
}
}
return containerdimages.Image{}, images.ErrImageDoesNotExist{Ref: parsed}
}
return imgs[0], nil
}

View File

@@ -2,23 +2,514 @@ package containerd
import (
"context"
"errors"
"fmt"
"io"
"os"
"runtime"
"time"
"github.com/containerd/containerd"
cerrdefs "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/leases"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/rootfs"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types/backend"
imagetypes "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/internal/compatcontext"
registrypkg "github.com/docker/docker/registry"
// "github.com/docker/docker/api/types/container"
containerdimages "github.com/containerd/containerd/images"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/builder"
"github.com/docker/docker/errdefs"
dimage "github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/system"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/identity"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/sirupsen/logrus"
)
// GetImageAndReleasableLayer returns an image and releaseable layer for a
// reference or ID. Every call to GetImageAndReleasableLayer MUST call
// releasableLayer.Release() to prevent leaking of layers.
func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts backend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error) {
return nil, nil, errdefs.NotImplemented(errors.New("not implemented"))
if refOrID == "" { // from SCRATCH
imgOS := runtime.GOOS
if runtime.GOOS == "windows" {
imgOS = "linux"
}
if opts.Platform != nil {
imgOS = opts.Platform.OS
}
if !system.IsOSSupported(imgOS) {
return nil, nil, system.ErrNotSupportedOperatingSystem
}
return nil, &rolayer{
key: "",
c: i.client,
snapshotter: i.snapshotter,
diffID: "",
root: "",
}, nil
}
if opts.PullOption != backend.PullOptionForcePull {
// TODO(laurazard): same as below
img, err := i.GetImage(ctx, refOrID, image.GetImageOpts{Platform: opts.Platform})
if err != nil && opts.PullOption == backend.PullOptionNoPull {
return nil, nil, err
}
imgDesc, err := i.resolveDescriptor(ctx, refOrID)
if err != nil && !errdefs.IsNotFound(err) {
return nil, nil, err
}
if img != nil {
if !system.IsOSSupported(img.OperatingSystem()) {
return nil, nil, system.ErrNotSupportedOperatingSystem
}
roLayer, err := newROLayerForImage(ctx, &imgDesc, i, opts.Platform)
if err != nil {
return nil, nil, err
}
return img, roLayer, nil
}
}
ctx, _, err := i.client.WithLease(ctx, leases.WithRandomID(), leases.WithExpiration(1*time.Hour))
if err != nil {
return nil, nil, fmt.Errorf("failed to create lease for commit: %w", err)
}
// TODO(laurazard): do we really need a new method here to pull the image?
imgDesc, err := i.pullForBuilder(ctx, refOrID, opts.AuthConfig, opts.Output, opts.Platform)
if err != nil {
return nil, nil, err
}
// TODO(laurazard): pullForBuilder should return whatever we
// need here instead of having to go and get it again
img, err := i.GetImage(ctx, refOrID, imagetypes.GetImageOpts{
Platform: opts.Platform,
})
if err != nil {
return nil, nil, err
}
roLayer, err := newROLayerForImage(ctx, imgDesc, i, opts.Platform)
if err != nil {
return nil, nil, err
}
return img, roLayer, nil
}
func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConfigs map[string]registry.AuthConfig, output io.Writer, platform *ocispec.Platform) (*ocispec.Descriptor, error) {
ref, err := reference.ParseNormalizedNamed(name)
if err != nil {
return nil, err
}
taggedRef := reference.TagNameOnly(ref)
pullRegistryAuth := &registry.AuthConfig{}
if len(authConfigs) > 0 {
// The request came with a full auth config, use it
repoInfo, err := i.registryService.ResolveRepository(ref)
if err != nil {
return nil, err
}
resolvedConfig := registrypkg.ResolveAuthConfig(authConfigs, repoInfo.Index)
pullRegistryAuth = &resolvedConfig
}
if err := i.PullImage(ctx, ref.Name(), taggedRef.(reference.NamedTagged).Tag(), platform, nil, pullRegistryAuth, output); err != nil {
return nil, err
}
img, err := i.GetImage(ctx, name, imagetypes.GetImageOpts{Platform: platform})
if err != nil {
if errdefs.IsNotFound(err) && img != nil && platform != nil {
imgPlat := ocispec.Platform{
OS: img.OS,
Architecture: img.BaseImgArch(),
Variant: img.BaseImgVariant(),
}
p := *platform
if !platforms.Only(p).Match(imgPlat) {
po := streamformatter.NewJSONProgressOutput(output, false)
progress.Messagef(po, "", `
WARNING: Pulled image with specified platform (%s), but the resulting image's configured platform (%s) does not match.
This is most likely caused by a bug in the build system that created the fetched image (%s).
Please notify the image author to correct the configuration.`,
platforms.Format(p), platforms.Format(imgPlat), name,
)
logrus.WithError(err).WithField("image", name).Warn("Ignoring error about platform mismatch where the manifest list points to an image whose configuration does not match the platform in the manifest.")
}
} else {
return nil, err
}
}
if !system.IsOSSupported(img.OperatingSystem()) {
return nil, system.ErrNotSupportedOperatingSystem
}
imgDesc, err := i.resolveDescriptor(ctx, name)
if err != nil {
return nil, err
}
return &imgDesc, err
}
func newROLayerForImage(ctx context.Context, imgDesc *ocispec.Descriptor, i *ImageService, platform *ocispec.Platform) (builder.ROLayer, error) {
if imgDesc == nil {
return nil, fmt.Errorf("can't make an RO layer for a nil image :'(")
}
platMatcher := platforms.Default()
if platform != nil {
platMatcher = platforms.Only(*platform)
}
// this needs it's own context + lease so that it doesn't get cleaned before we're ready
confDesc, err := containerdimages.Config(ctx, i.client.ContentStore(), *imgDesc, platMatcher)
if err != nil {
return nil, err
}
diffIDs, err := containerdimages.RootFS(ctx, i.client.ContentStore(), confDesc)
if err != nil {
return nil, err
}
parent := identity.ChainID(diffIDs).String()
s := i.client.SnapshotService(i.snapshotter)
key := stringid.GenerateRandomID()
ctx, _, err = i.client.WithLease(ctx, leases.WithRandomID(), leases.WithExpiration(1*time.Hour))
if err != nil {
return nil, fmt.Errorf("failed to create lease for commit: %w", err)
}
mounts, err := s.View(ctx, key, parent)
if err != nil {
return nil, err
}
tempMountLocation := os.TempDir()
root, err := os.MkdirTemp(tempMountLocation, "rootfs-mount")
if err != nil {
return nil, err
}
if err := mount.All(mounts, root); err != nil {
return nil, err
}
return &rolayer{
key: key,
c: i.client,
snapshotter: i.snapshotter,
diffID: digest.Digest(parent),
root: root,
contentStoreDigest: "",
}, nil
}
type rolayer struct {
key string
c *containerd.Client
snapshotter string
diffID digest.Digest
root string
contentStoreDigest digest.Digest
}
func (rl *rolayer) ContentStoreDigest() digest.Digest {
return rl.contentStoreDigest
}
func (rl *rolayer) DiffID() layer.DiffID {
if rl.diffID == "" {
return layer.DigestSHA256EmptyTar
}
return layer.DiffID(rl.diffID)
}
func (rl *rolayer) Release() error {
snapshotter := rl.c.SnapshotService(rl.snapshotter)
err := snapshotter.Remove(context.TODO(), rl.key)
if err != nil && !cerrdefs.IsNotFound(err) {
return err
}
if rl.root == "" { // nothing to release
return nil
}
if err := mount.UnmountAll(rl.root, 0); err != nil {
logrus.WithError(err).WithField("root", rl.root).Error("failed to unmount ROLayer")
return err
}
if err := os.Remove(rl.root); err != nil {
logrus.WithError(err).WithField("dir", rl.root).Error("failed to remove mount temp dir")
return err
}
rl.root = ""
return nil
}
// NewRWLayer creates a new read-write layer for the builder
func (rl *rolayer) NewRWLayer() (builder.RWLayer, error) {
snapshotter := rl.c.SnapshotService(rl.snapshotter)
// we need this here for the prepared snapshots or
// we'll have racy behaviour where sometimes they
// will get GC'd before we commit/use them
ctx, _, err := rl.c.WithLease(context.TODO(), leases.WithRandomID(), leases.WithExpiration(1*time.Hour))
if err != nil {
return nil, fmt.Errorf("failed to create lease for commit: %w", err)
}
key := stringid.GenerateRandomID()
mounts, err := snapshotter.Prepare(ctx, key, rl.diffID.String())
if err != nil {
return nil, err
}
root, err := os.MkdirTemp(os.TempDir(), "rootfs-mount")
if err != nil {
return nil, err
}
if err := mount.All(mounts, root); err != nil {
return nil, err
}
return &rwlayer{
key: key,
parent: rl.key,
c: rl.c,
snapshotter: rl.snapshotter,
root: root,
}, nil
}
type rwlayer struct {
key string
parent string
c *containerd.Client
snapshotter string
root string
}
func (rw *rwlayer) Root() string {
return rw.root
}
func (rw *rwlayer) Commit() (builder.ROLayer, error) {
// we need this here for the prepared snapshots or
// we'll have racy behaviour where sometimes they
// will get GC'd before we commit/use them
ctx, _, err := rw.c.WithLease(context.TODO(), leases.WithRandomID(), leases.WithExpiration(1*time.Hour))
if err != nil {
return nil, fmt.Errorf("failed to create lease for commit: %w", err)
}
snapshotter := rw.c.SnapshotService(rw.snapshotter)
key := stringid.GenerateRandomID()
err = snapshotter.Commit(ctx, key, rw.key)
if err != nil && !cerrdefs.IsAlreadyExists(err) {
return nil, err
}
differ := rw.c.DiffService()
desc, err := rootfs.CreateDiff(ctx, key, snapshotter, differ)
if err != nil {
return nil, err
}
info, err := rw.c.ContentStore().Info(ctx, desc.Digest)
if err != nil {
return nil, err
}
diffIDStr, ok := info.Labels["containerd.io/uncompressed"]
if !ok {
return nil, fmt.Errorf("invalid differ response with no diffID")
}
diffID, err := digest.Parse(diffIDStr)
if err != nil {
return nil, err
}
return &rolayer{
key: key,
c: rw.c,
snapshotter: rw.snapshotter,
diffID: diffID,
root: "",
contentStoreDigest: desc.Digest,
}, nil
}
func (rw *rwlayer) Release() error {
snapshotter := rw.c.SnapshotService(rw.snapshotter)
err := snapshotter.Remove(context.TODO(), rw.key)
if err != nil && !cerrdefs.IsNotFound(err) {
return err
}
if rw.root == "" { // nothing to release
return nil
}
if err := mount.UnmountAll(rw.root, 0); err != nil {
logrus.WithError(err).WithField("root", rw.root).Error("failed to unmount ROLayer")
return err
}
if err := os.Remove(rw.root); err != nil {
logrus.WithError(err).WithField("dir", rw.root).Error("failed to remove mount temp dir")
return err
}
rw.root = ""
return nil
}
// CreateImage creates a new image by adding a config and ID to the image store.
// This is similar to LoadImage() except that it receives JSON encoded bytes of
// an image instead of a tar archive.
func (i *ImageService) CreateImage(config []byte, parent string) (builder.Image, error) {
return nil, errdefs.NotImplemented(errors.New("not implemented"))
func (i *ImageService) CreateImage(ctx context.Context, config []byte, parent string, layerDigest digest.Digest) (builder.Image, error) {
imgToCreate, err := dimage.NewFromJSON(config)
if err != nil {
return nil, err
}
rootFS := ocispec.RootFS{
Type: imgToCreate.RootFS.Type,
DiffIDs: []digest.Digest{},
}
for _, diffId := range imgToCreate.RootFS.DiffIDs {
rootFS.DiffIDs = append(rootFS.DiffIDs, digest.Digest(diffId))
}
exposedPorts := make(map[string]struct{}, len(imgToCreate.Config.ExposedPorts))
for k, v := range imgToCreate.Config.ExposedPorts {
exposedPorts[string(k)] = v
}
var ociHistory []ocispec.History
for _, history := range imgToCreate.History {
created := history.Created
ociHistory = append(ociHistory, ocispec.History{
Created: &created,
CreatedBy: history.CreatedBy,
Author: history.Author,
Comment: history.Comment,
EmptyLayer: history.EmptyLayer,
})
}
// make an ocispec.Image from the docker/image.Image
ociImgToCreate := ocispec.Image{
Created: &imgToCreate.Created,
Author: imgToCreate.Author,
Platform: ocispec.Platform{
Architecture: imgToCreate.Architecture,
Variant: imgToCreate.Variant,
OS: imgToCreate.OS,
OSVersion: imgToCreate.OSVersion,
OSFeatures: imgToCreate.OSFeatures,
},
Config: ocispec.ImageConfig{
User: imgToCreate.Config.User,
ExposedPorts: exposedPorts,
Env: imgToCreate.Config.Env,
Entrypoint: imgToCreate.Config.Entrypoint,
Cmd: imgToCreate.Config.Cmd,
Volumes: imgToCreate.Config.Volumes,
WorkingDir: imgToCreate.Config.WorkingDir,
Labels: imgToCreate.Config.Labels,
StopSignal: imgToCreate.Config.StopSignal,
},
RootFS: rootFS,
History: ociHistory,
}
var layers []ocispec.Descriptor
// if the image has a parent, we need to start with the parents layers descriptors
if parent != "" {
parentDesc, err := i.resolveDescriptor(ctx, parent)
if err != nil {
return nil, err
}
parentImageManifest, err := containerdimages.Manifest(ctx, i.client.ContentStore(), parentDesc, platforms.Default())
if err != nil {
return nil, err
}
layers = parentImageManifest.Layers
}
// get the info for the new layers
info, err := i.client.ContentStore().Info(ctx, layerDigest)
if err != nil {
return nil, err
}
// append the new layer descriptor
layers = append(layers,
ocispec.Descriptor{
MediaType: containerdimages.MediaTypeDockerSchema2LayerGzip,
Digest: layerDigest,
Size: info.Size,
},
)
// necessary to prevent the contents from being GC'd
// between writing them here and creating an image
ctx, release, err := i.client.WithLease(ctx, leases.WithRandomID(), leases.WithExpiration(1*time.Hour))
if err != nil {
return nil, err
}
defer func() {
if err := release(compatcontext.WithoutCancel(ctx)); err != nil {
logrus.WithError(err).Warn("failed to release lease created for create")
}
}()
commitManifestDesc, err := writeContentsForImage(ctx, i.snapshotter, i.client.ContentStore(), ociImgToCreate, layers)
if err != nil {
return nil, err
}
// image create
img := containerdimages.Image{
Name: danglingImageName(commitManifestDesc.Digest),
Target: commitManifestDesc,
CreatedAt: time.Now(),
}
createdImage, err := i.client.ImageService().Update(ctx, img)
if err != nil {
if !cerrdefs.IsNotFound(err) {
return nil, err
}
if createdImage, err = i.client.ImageService().Create(ctx, img); err != nil {
return nil, fmt.Errorf("failed to create new image: %w", err)
}
}
if err := i.unpackImage(ctx, createdImage, platforms.DefaultSpec()); err != nil {
return nil, err
}
newImage := dimage.Clone(imgToCreate, dimage.ID(createdImage.Target.Digest))
return newImage, nil
}

View File

@@ -58,15 +58,10 @@ func (i *ImageService) Changes(ctx context.Context, container *container.Contain
}
}()
mounts, err := snapshotter.Mounts(ctx, container.ID)
if err != nil {
return nil, err
}
var changes []archive.Change
err = mount.WithReadonlyTempMount(ctx, mounts, func(fs string) error {
return mount.WithTempMount(ctx, parent, func(root string) error {
changes, err = archive.ChangesDirs(fs, root)
err = i.PerformWithBaseFS(ctx, container, func(containerRootfs string) error {
return mount.WithReadonlyTempMount(ctx, parent, func(parentRootfs string) error {
changes, err = archive.ChangesDirs(containerRootfs, parentRootfs)
return err
})
})

View File

@@ -127,3 +127,71 @@ func isRootfsChildOf(child ocispec.RootFS, parent ocispec.RootFS) bool {
return true
}
// parents returns a slice of image IDs whose entire rootfs contents match,
// in order, the childs first layers, excluding images with the exact same
// rootfs.
//
// Called from image_delete.go to prune dangling parents.
func (i *ImageService) parents(ctx context.Context, id image.ID) ([]imageWithRootfs, error) {
target, err := i.resolveDescriptor(ctx, id.String())
if err != nil {
return nil, errors.Wrap(err, "failed to get child image")
}
cs := i.client.ContentStore()
allPlatforms, err := containerdimages.Platforms(ctx, cs, target)
if err != nil {
return nil, errdefs.System(errors.Wrap(err, "failed to list platforms supported by image"))
}
var childRootFS []ocispec.RootFS
for _, platform := range allPlatforms {
rootfs, err := platformRootfs(ctx, cs, target, platform)
if err != nil {
if cerrdefs.IsNotFound(err) {
continue
}
return nil, errdefs.System(errors.Wrap(err, "failed to get platform-specific rootfs"))
}
childRootFS = append(childRootFS, rootfs)
}
imgs, err := i.client.ImageService().List(ctx)
if err != nil {
return nil, errdefs.System(errors.Wrap(err, "failed to list all images"))
}
var parents []imageWithRootfs
for _, img := range imgs {
nextImage:
for _, platform := range allPlatforms {
rootfs, err := platformRootfs(ctx, cs, img.Target, platform)
if err != nil {
if cerrdefs.IsNotFound(err) {
continue
}
return nil, errdefs.System(errors.Wrap(err, "failed to get platform-specific rootfs"))
}
for _, childRoot := range childRootFS {
if isRootfsChildOf(childRoot, rootfs) {
parents = append(parents, imageWithRootfs{
img: img,
rootfs: rootfs,
})
break nextImage
}
}
}
}
return parents, nil
}
type imageWithRootfs struct {
img containerdimages.Image
rootfs ocispec.RootFS
}

View File

@@ -6,9 +6,9 @@ import (
"crypto/rand"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"runtime"
"strings"
"time"
"github.com/containerd/containerd/content"
@@ -19,8 +19,9 @@ import (
"github.com/containerd/containerd/rootfs"
"github.com/containerd/containerd/snapshots"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/pkg/archive"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/identity"
"github.com/opencontainers/image-spec/specs-go"
@@ -39,28 +40,27 @@ func (i *ImageService) CommitImage(ctx context.Context, cc backend.CommitConfig)
container := i.containers.Get(cc.ContainerID)
cs := i.client.ContentStore()
imageManifest, err := getContainerImageManifest(container)
if err != nil {
return "", err
}
var parentManifest ocispec.Manifest
var parentImage ocispec.Image
imageManifestBytes, err := content.ReadBlob(ctx, cs, imageManifest)
if err != nil {
return "", err
}
// ImageManifest can be nil when committing an image with base FROM scratch
if container.ImageManifest != nil {
imageManifestBytes, err := content.ReadBlob(ctx, cs, *container.ImageManifest)
if err != nil {
return "", err
}
var manifest ocispec.Manifest
if err := json.Unmarshal(imageManifestBytes, &manifest); err != nil {
return "", err
}
if err := json.Unmarshal(imageManifestBytes, &parentManifest); err != nil {
return "", err
}
imageConfigBytes, err := content.ReadBlob(ctx, cs, manifest.Config)
if err != nil {
return "", err
}
var ociimage ocispec.Image
if err := json.Unmarshal(imageConfigBytes, &ociimage); err != nil {
return "", err
imageConfigBytes, err := content.ReadBlob(ctx, cs, parentManifest.Config)
if err != nil {
return "", err
}
if err := json.Unmarshal(imageConfigBytes, &parentImage); err != nil {
return "", err
}
}
var (
@@ -69,25 +69,33 @@ func (i *ImageService) CommitImage(ctx context.Context, cc backend.CommitConfig)
)
// Don't gc me and clean the dirty data after 1 hour!
ctx, done, err := i.client.WithLease(ctx, leases.WithRandomID(), leases.WithExpiration(1*time.Hour))
ctx, release, err := i.client.WithLease(ctx, leases.WithRandomID(), leases.WithExpiration(1*time.Hour))
if err != nil {
return "", fmt.Errorf("failed to create lease for commit: %w", err)
}
defer done(ctx)
defer func() {
if err := release(compatcontext.WithoutCancel(ctx)); err != nil {
logrus.WithError(err).Warn("failed to release lease created for commit")
}
}()
diffLayerDesc, diffID, err := createDiff(ctx, cc.ContainerID, sn, cs, differ)
if err != nil {
return "", fmt.Errorf("failed to export layer: %w", err)
}
imageConfig := generateCommitImageConfig(parentImage, diffID, cc)
imageConfig := generateCommitImageConfig(ociimage, diffID, cc)
layers := parentManifest.Layers
if diffLayerDesc != nil {
rootfsID := identity.ChainID(imageConfig.RootFS.DiffIDs).String()
rootfsID := identity.ChainID(imageConfig.RootFS.DiffIDs).String()
if err := applyDiffLayer(ctx, rootfsID, ociimage, sn, differ, diffLayerDesc); err != nil {
return "", fmt.Errorf("failed to apply diff: %w", err)
if err := applyDiffLayer(ctx, rootfsID, parentImage, sn, differ, *diffLayerDesc); err != nil {
return "", fmt.Errorf("failed to apply diff: %w", err)
}
layers = append(layers, *diffLayerDesc)
}
layers := append(manifest.Layers, diffLayerDesc)
commitManifestDesc, err := writeContentsForImage(ctx, container.Driver, cs, imageConfig, layers)
if err != nil {
return "", err
@@ -131,21 +139,30 @@ func generateCommitImageConfig(baseConfig ocispec.Image, diffID digest.Digest, o
logrus.Warnf("assuming os=%q", os)
}
logrus.Debugf("generateCommitImageConfig(): arch=%q, os=%q", arch, os)
diffIds := baseConfig.RootFS.DiffIDs
if diffID != "" {
diffIds = append(diffIds, diffID)
}
return ocispec.Image{
Architecture: arch,
OS: os,
Created: &createdTime,
Author: opts.Author,
Config: containerConfigToOciImageConfig(opts.Config),
Platform: ocispec.Platform{
Architecture: arch,
OS: os,
},
Created: &createdTime,
Author: opts.Author,
Config: containerConfigToOciImageConfig(opts.Config),
RootFS: ocispec.RootFS{
Type: "layers",
DiffIDs: append(baseConfig.RootFS.DiffIDs, diffID),
DiffIDs: diffIds,
},
History: append(baseConfig.History, ocispec.History{
Created: &createdTime,
CreatedBy: "", // FIXME(ndeloof) ?
Author: opts.Author,
Comment: opts.Comment,
Created: &createdTime,
CreatedBy: strings.Join(opts.ContainerConfig.Cmd, " "),
Author: opts.Author,
Comment: opts.Comment,
// TODO(laurazard): this check might be incorrect
EmptyLayer: diffID == "",
}),
}
@@ -215,28 +232,43 @@ func writeContentsForImage(ctx context.Context, snName string, cs content.Store,
}
// createDiff creates a layer diff into containerd's content store.
func createDiff(ctx context.Context, name string, sn snapshots.Snapshotter, cs content.Store, comparer diff.Comparer) (ocispec.Descriptor, digest.Digest, error) {
// If the diff is empty it returns nil empty digest and no error.
func createDiff(ctx context.Context, name string, sn snapshots.Snapshotter, cs content.Store, comparer diff.Comparer) (*ocispec.Descriptor, digest.Digest, error) {
newDesc, err := rootfs.CreateDiff(ctx, name, sn, comparer)
if err != nil {
return ocispec.Descriptor{}, "", err
return nil, "", err
}
ra, err := cs.ReaderAt(ctx, newDesc)
if err != nil {
return nil, "", fmt.Errorf("failed to read diff archive: %w", err)
}
defer ra.Close()
empty, err := archive.IsEmpty(content.NewReader(ra))
if err != nil {
return nil, "", fmt.Errorf("failed to check if archive is empty: %w", err)
}
if empty {
return nil, "", nil
}
info, err := cs.Info(ctx, newDesc.Digest)
if err != nil {
return ocispec.Descriptor{}, "", err
return nil, "", fmt.Errorf("failed to get content info: %w", err)
}
diffIDStr, ok := info.Labels["containerd.io/uncompressed"]
if !ok {
return ocispec.Descriptor{}, "", fmt.Errorf("invalid differ response with no diffID")
return nil, "", fmt.Errorf("invalid differ response with no diffID")
}
diffID, err := digest.Parse(diffIDStr)
if err != nil {
return ocispec.Descriptor{}, "", err
return nil, "", err
}
return ocispec.Descriptor{
return &ocispec.Descriptor{
MediaType: ocispec.MediaTypeImageLayerGzip,
Digest: newDesc.Digest,
Size: info.Size,
@@ -252,7 +284,7 @@ func applyDiffLayer(ctx context.Context, name string, baseImg ocispec.Image, sn
mount, err := sn.Prepare(ctx, key, parent)
if err != nil {
return err
return fmt.Errorf("failed to prepare snapshot: %w", err)
}
defer func() {
@@ -297,5 +329,13 @@ func uniquePart() string {
//
// This is a temporary shim. Should be removed when builder stops using commit.
func (i *ImageService) CommitBuildStep(ctx context.Context, c backend.CommitConfig) (image.ID, error) {
return "", errdefs.NotImplemented(errors.New("not implemented"))
ctr := i.containers.Get(c.ContainerID)
if ctr == nil {
// TODO: use typed error
return "", fmt.Errorf("container not found: %s", c.ContainerID)
}
c.ContainerMountLabel = ctr.MountLabel
c.ContainerOS = ctr.OS
c.ParentImageID = string(ctr.ImageID)
return i.CommitImage(ctx, c)
}

View File

@@ -2,10 +2,16 @@ package containerd
import (
"context"
"fmt"
"sort"
"strings"
"github.com/containerd/containerd/images"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/container"
"github.com/docker/docker/image"
"github.com/docker/docker/pkg/stringid"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/sirupsen/logrus"
@@ -30,8 +36,6 @@ import (
// are divided into two categories grouped by their severity:
//
// Hard Conflict:
// - a pull or build using the image.
// - any descendant image.
// - any running container using the image.
//
// Soft Conflict:
@@ -45,8 +49,6 @@ import (
// meaning any delete conflicts will cause the image to not be deleted and the
// conflict will not be reported.
//
// TODO(thaJeztah): implement ImageDelete "force" options; see https://github.com/moby/moby/issues/43850
// TODO(thaJeztah): implement ImageDelete "prune" options; see https://github.com/moby/moby/issues/43849
// TODO(thaJeztah): image delete should send prometheus counters; see https://github.com/moby/moby/issues/45268
func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error) {
parsedRef, err := reference.ParseNormalizedNamed(imageRef)
@@ -59,28 +61,279 @@ func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force,
return nil, err
}
possiblyDeletedConfigs := map[digest.Digest]struct{}{}
if err := i.walkPresentChildren(ctx, img.Target, func(_ context.Context, d ocispec.Descriptor) {
if images.IsConfigType(d.MediaType) {
possiblyDeletedConfigs[d.Digest] = struct{}{}
}
}); err != nil {
return nil, err
imgID := image.ID(img.Target.Digest)
if isImageIDPrefix(imgID.String(), imageRef) {
return i.deleteAll(ctx, img, force, prune)
}
err = i.client.ImageService().Delete(ctx, img.Name, images.SynchronousDelete())
singleRef, err := i.isSingleReference(ctx, img)
if err != nil {
return nil, err
}
// Workaround for: https://github.com/moby/buildkit/issues/3797
if err := i.unleaseSnapshotsFromDeletedConfigs(context.Background(), possiblyDeletedConfigs); err != nil {
logrus.WithError(err).Warn("failed to unlease snapshots")
if !singleRef {
err := i.client.ImageService().Delete(ctx, img.Name)
if err != nil {
return nil, err
}
i.LogImageEvent(imgID.String(), imgID.String(), "untag")
records := []types.ImageDeleteResponseItem{{Untagged: reference.FamiliarString(reference.TagNameOnly(parsedRef))}}
return records, nil
}
imgID := string(img.Target.Digest)
i.LogImageEvent(imgID, imgID, "untag")
i.LogImageEvent(imgID, imgID, "delete")
using := func(c *container.Container) bool {
return c.ImageID == imgID
}
ctr := i.containers.First(using)
if ctr != nil {
if !force {
// If we removed the repository reference then
// this image would remain "dangling" and since
// we really want to avoid that the client must
// explicitly force its removal.
refString := reference.FamiliarString(reference.TagNameOnly(parsedRef))
err := &imageDeleteConflict{
reference: refString,
used: true,
message: fmt.Sprintf("container %s is using its referenced image %s",
stringid.TruncateID(ctr.ID),
stringid.TruncateID(imgID.String())),
}
return nil, err
}
return []types.ImageDeleteResponseItem{{Untagged: reference.FamiliarString(parsedRef)}}, nil
err := i.softImageDelete(ctx, img)
if err != nil {
return nil, err
}
i.LogImageEvent(imgID.String(), imgID.String(), "untag")
records := []types.ImageDeleteResponseItem{{Untagged: reference.FamiliarString(reference.TagNameOnly(parsedRef))}}
return records, nil
}
return i.deleteAll(ctx, img, force, prune)
}
// deleteAll deletes the image from the daemon, and if prune is true,
// also deletes dangling parents if there is no conflict in doing so.
// Parent images are removed quietly, and if there is any issue/conflict
// it is logged but does not halt execution/an error is not returned.
func (i *ImageService) deleteAll(ctx context.Context, img images.Image, force, prune bool) ([]types.ImageDeleteResponseItem, error) {
var records []types.ImageDeleteResponseItem
// Workaround for: https://github.com/moby/buildkit/issues/3797
possiblyDeletedConfigs := map[digest.Digest]struct{}{}
err := i.walkPresentChildren(ctx, img.Target, func(_ context.Context, d ocispec.Descriptor) error {
if images.IsConfigType(d.MediaType) {
possiblyDeletedConfigs[d.Digest] = struct{}{}
}
return nil
})
if err != nil {
return nil, err
}
defer func() {
if err := i.unleaseSnapshotsFromDeletedConfigs(context.Background(), possiblyDeletedConfigs); err != nil {
logrus.WithError(err).Warn("failed to unlease snapshots")
}
}()
imgID := img.Target.Digest.String()
var parents []imageWithRootfs
if prune {
parents, err = i.parents(ctx, image.ID(imgID))
if err != nil {
logrus.WithError(err).Warn("failed to get image parents")
}
sortParentsByAffinity(parents)
}
imageRefs, err := i.client.ImageService().List(ctx, "target.digest=="+imgID)
if err != nil {
return nil, err
}
for _, imageRef := range imageRefs {
if err := i.imageDeleteHelper(ctx, imageRef, &records, force); err != nil {
return records, err
}
}
i.LogImageEvent(imgID, imgID, "delete")
records = append(records, types.ImageDeleteResponseItem{Deleted: imgID})
for _, parent := range parents {
if !isDanglingImage(parent.img) {
break
}
err = i.imageDeleteHelper(ctx, parent.img, &records, false)
if err != nil {
logrus.WithError(err).Warn("failed to remove image parent")
break
}
parentID := parent.img.Target.Digest.String()
i.LogImageEvent(parentID, parentID, "delete")
records = append(records, types.ImageDeleteResponseItem{Deleted: parentID})
}
return records, nil
}
// isImageIDPrefix returns whether the given
// possiblePrefix is a prefix of the given imageID.
func isImageIDPrefix(imageID, possiblePrefix string) bool {
if strings.HasPrefix(imageID, possiblePrefix) {
return true
}
if i := strings.IndexRune(imageID, ':'); i >= 0 {
return strings.HasPrefix(imageID[i+1:], possiblePrefix)
}
return false
}
func sortParentsByAffinity(parents []imageWithRootfs) {
sort.Slice(parents, func(i, j int) bool {
lenRootfsI := len(parents[i].rootfs.DiffIDs)
lenRootfsJ := len(parents[j].rootfs.DiffIDs)
if lenRootfsI == lenRootfsJ {
return isDanglingImage(parents[i].img)
}
return lenRootfsI > lenRootfsJ
})
}
// isSingleReference returns true if there are no other images in the
// daemon targeting the same content as `img` that are not dangling.
func (i *ImageService) isSingleReference(ctx context.Context, img images.Image) (bool, error) {
refs, err := i.client.ImageService().List(ctx, "target.digest=="+img.Target.Digest.String())
if err != nil {
return false, err
}
for _, ref := range refs {
if !isDanglingImage(ref) && ref.Name != img.Name {
return false, nil
}
}
return true, nil
}
type conflictType int
const (
conflictRunningContainer conflictType = 1 << iota
conflictActiveReference
conflictStoppedContainer
conflictHard = conflictRunningContainer
conflictSoft = conflictActiveReference | conflictStoppedContainer
)
// imageDeleteHelper attempts to delete the given image from this daemon.
// If the image has any hard delete conflicts (running containers using
// the image) then it cannot be deleted. If the image has any soft delete
// conflicts (any tags/digests referencing the image or any stopped container
// using the image) then it can only be deleted if force is true. Any deleted
// images and untagged references are appended to the given records. If any
// error or conflict is encountered, it will be returned immediately without
// deleting the image.
func (i *ImageService) imageDeleteHelper(ctx context.Context, img images.Image, records *[]types.ImageDeleteResponseItem, force bool) error {
// First, determine if this image has any conflicts. Ignore soft conflicts
// if force is true.
c := conflictHard
if !force {
c |= conflictSoft
}
imgID := image.ID(img.Target.Digest)
err := i.checkImageDeleteConflict(ctx, imgID, c)
if err != nil {
return err
}
untaggedRef, err := reference.ParseAnyReference(img.Name)
if err != nil {
return err
}
err = i.client.ImageService().Delete(ctx, img.Name, images.SynchronousDelete())
if err != nil {
return err
}
i.LogImageEvent(imgID.String(), imgID.String(), "untag")
*records = append(*records, types.ImageDeleteResponseItem{Untagged: reference.FamiliarString(untaggedRef)})
return nil
}
// ImageDeleteConflict holds a soft or hard conflict and associated
// error. A hard conflict represents a running container using the
// image, while a soft conflict is any tags/digests referencing the
// given image or any stopped container using the image.
// Implements the error interface.
type imageDeleteConflict struct {
hard bool
used bool
reference string
message string
}
func (idc *imageDeleteConflict) Error() string {
var forceMsg string
if idc.hard {
forceMsg = "cannot be forced"
} else {
forceMsg = "must be forced"
}
return fmt.Sprintf("conflict: unable to delete %s (%s) - %s", idc.reference, forceMsg, idc.message)
}
func (imageDeleteConflict) Conflict() {}
// checkImageDeleteConflict returns a conflict representing
// any issue preventing deletion of the given image ID, and
// nil if there are none. It takes a bitmask representing a
// filter for which conflict types the caller cares about,
// and will only check for these conflict types.
func (i *ImageService) checkImageDeleteConflict(ctx context.Context, imgID image.ID, mask conflictType) error {
if mask&conflictRunningContainer != 0 {
running := func(c *container.Container) bool {
return c.ImageID == imgID && c.IsRunning()
}
if ctr := i.containers.First(running); ctr != nil {
return &imageDeleteConflict{
reference: stringid.TruncateID(imgID.String()),
hard: true,
used: true,
message: fmt.Sprintf("image is being used by running container %s", stringid.TruncateID(ctr.ID)),
}
}
}
if mask&conflictStoppedContainer != 0 {
stopped := func(c *container.Container) bool {
return !c.IsRunning() && c.ImageID == imgID
}
if ctr := i.containers.First(stopped); ctr != nil {
return &imageDeleteConflict{
reference: stringid.TruncateID(imgID.String()),
used: true,
message: fmt.Sprintf("image is being used by stopped container %s", stringid.TruncateID(ctr.ID)),
}
}
}
if mask&conflictActiveReference != 0 {
refs, err := i.client.ImageService().List(ctx, "target.digest=="+imgID.String())
if err != nil {
return err
}
if len(refs) > 1 {
return &imageDeleteConflict{
reference: stringid.TruncateID(imgID.String()),
message: "image is referenced in multiple repositories",
}
}
}
return nil
}

View File

@@ -6,10 +6,11 @@ import (
"io"
"github.com/containerd/containerd"
"github.com/containerd/containerd/content"
cerrdefs "github.com/containerd/containerd/errdefs"
containerdimages "github.com/containerd/containerd/images"
"github.com/containerd/containerd/images/archive"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/leases"
cplatforms "github.com/containerd/containerd/platforms"
"github.com/docker/distribution/reference"
"github.com/docker/docker/container"
@@ -18,6 +19,7 @@ import (
"github.com/docker/docker/pkg/streamformatter"
"github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -27,7 +29,13 @@ func (i *ImageService) PerformWithBaseFS(ctx context.Context, c *container.Conta
if err != nil {
return err
}
return mount.WithTempMount(ctx, mounts, fn)
path, err := i.refCountMounter.Mount(mounts, c.ID)
if err != nil {
return err
}
defer i.refCountMounter.Unmount(path)
return fn(path)
}
// ExportImage exports a list of images to the given output stream. The
@@ -56,11 +64,17 @@ func (i *ImageService) ExportImage(ctx context.Context, names []string, outStrea
archive.WithPlatform(platform),
}
ctx, release, err := i.client.WithLease(ctx)
contentStore := i.client.ContentStore()
leasesManager := i.client.LeasesService()
lease, err := leasesManager.Create(ctx, leases.WithRandomID())
if err != nil {
return errdefs.System(err)
}
defer release(ctx)
defer func() {
if err := leasesManager.Delete(ctx, lease); err != nil {
logrus.WithError(err).Warn("cleaning up lease")
}
}()
for _, name := range names {
target, err := i.resolveDescriptor(ctx, name)
@@ -68,6 +82,10 @@ func (i *ImageService) ExportImage(ctx context.Context, names []string, outStrea
return err
}
if err = leaseContent(ctx, contentStore, leasesManager, lease, target); err != nil {
return err
}
// We may not have locally all the platforms that are specified in the index.
// Export only those manifests that we have.
// TODO(vvoland): Reconsider this when `--platform` is added.
@@ -99,6 +117,30 @@ func (i *ImageService) ExportImage(ctx context.Context, names []string, outStrea
return i.client.Export(ctx, outStream, opts...)
}
// leaseContent will add a resource to the lease for each child of the descriptor making sure that it and
// its children won't be deleted while the lease exists
func leaseContent(ctx context.Context, store content.Store, leasesManager leases.Manager, lease leases.Lease, desc ocispec.Descriptor) error {
return containerdimages.Walk(ctx, containerdimages.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
_, err := store.Info(ctx, desc.Digest)
if err != nil {
if errors.Is(err, cerrdefs.ErrNotFound) {
return nil, nil
}
return nil, errdefs.System(err)
}
r := leases.Resource{
ID: desc.Digest.String(),
Type: "content",
}
if err := leasesManager.AddResource(ctx, lease, r); err != nil {
return nil, errdefs.System(err)
}
return containerdimages.Children(ctx, store, desc)
}), desc)
}
// LoadImage uploads a set of images into the repository. This is the
// complement of ExportImage. The input stream is an uncompressed tar
// ball containing images and metadata.
@@ -109,7 +151,7 @@ func (i *ImageService) LoadImage(ctx context.Context, inTar io.ReadCloser, outSt
// Create an additional image with dangling name for imported images...
containerd.WithDigestRef(danglingImageName),
/// ... but only if they don't have a name or it's invalid.
// / ... but only if they don't have a name or it's invalid.
containerd.WithSkipDigestRef(func(nameFromArchive string) bool {
if nameFromArchive == "" {
return false
@@ -125,16 +167,9 @@ func (i *ImageService) LoadImage(ctx context.Context, inTar io.ReadCloser, outSt
return errdefs.System(err)
}
store := i.client.ContentStore()
progress := streamformatter.NewStdoutWriter(outStream)
for _, img := range imgs {
allPlatforms, err := containerdimages.Platforms(ctx, store, img.Target)
if err != nil {
logrus.WithError(err).WithField("image", img.Name).Debug("failed to get image platforms")
return errdefs.Unknown(err)
}
name := img.Name
loadedMsg := "Loaded image"
@@ -145,17 +180,25 @@ func (i *ImageService) LoadImage(ctx context.Context, inTar io.ReadCloser, outSt
name = reference.FamiliarName(reference.TagNameOnly(named))
}
for _, platform := range allPlatforms {
err = i.walkImageManifests(ctx, img, func(platformImg *ImageManifest) error {
logger := logrus.WithFields(logrus.Fields{
"platform": platform,
"image": name,
"manifest": platformImg.Target().Digest,
})
platformImg := containerd.NewImageWithPlatform(i.client, img, cplatforms.OnlyStrict(platform))
if isPseudo, err := platformImg.IsPseudoImage(ctx); isPseudo || err != nil {
if err != nil {
logger.WithError(err).Warn("failed to read manifest")
} else {
logger.Debug("don't unpack non-image manifest")
}
return nil
}
unpacked, err := platformImg.IsUnpacked(ctx, i.snapshotter)
if err != nil {
logger.WithError(err).Debug("failed to check if image is unpacked")
continue
logger.WithError(err).Warn("failed to check if image is unpacked")
return nil
}
if !unpacked {
@@ -166,6 +209,10 @@ func (i *ImageService) LoadImage(ctx context.Context, inTar io.ReadCloser, outSt
}
}
logger.WithField("alreadyUnpacked", unpacked).WithError(err).Debug("unpack")
return nil
})
if err != nil {
return errors.Wrap(err, "failed to unpack loaded image")
}
fmt.Fprintf(progress, "%s: %s\n", loadedMsg, name)

View File

@@ -2,13 +2,12 @@ package containerd
import (
"context"
"encoding/json"
"sort"
"github.com/containerd/containerd/content"
containerdimages "github.com/containerd/containerd/images"
cplatforms "github.com/containerd/containerd/platforms"
"github.com/docker/distribution/reference"
imagetype "github.com/docker/docker/api/types/image"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/platforms"
"github.com/opencontainers/image-spec/identity"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -18,32 +17,39 @@ import (
// ImageHistory returns a slice of HistoryResponseItem structures for the
// specified image name by walking the image lineage.
func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imagetype.HistoryResponseItem, error) {
desc, err := i.resolveDescriptor(ctx, name)
desc, err := i.resolveImage(ctx, name)
if err != nil {
return nil, err
}
cs := i.client.ContentStore()
// TODO: pass the platform from the cli
conf, err := containerdimages.Config(ctx, cs, desc, platforms.AllPlatformsWithPreference(cplatforms.Default()))
// TODO: pass platform in from the CLI
platform := platforms.AllPlatformsWithPreference(cplatforms.Default())
var presentImages []ocispec.Image
err = i.walkImageManifests(ctx, desc, func(img *ImageManifest) error {
conf, err := img.Config(ctx)
if err != nil {
return err
}
var ociimage ocispec.Image
if err := readConfig(ctx, cs, conf, &ociimage); err != nil {
return err
}
presentImages = append(presentImages, ociimage)
return nil
})
if err != nil {
return nil, err
}
diffIDs, err := containerdimages.RootFS(ctx, cs, conf)
if err != nil {
return nil, err
if len(presentImages) == 0 {
return nil, errdefs.NotFound(errors.New("failed to find image manifest"))
}
blob, err := content.ReadBlob(ctx, cs, conf)
if err != nil {
return nil, err
}
var image ocispec.Image
if err := json.Unmarshal(blob, &image); err != nil {
return nil, err
}
sort.SliceStable(presentImages, func(i, j int) bool {
return platform.Less(presentImages[i].Platform, presentImages[j].Platform)
})
ociimage := presentImages[0]
var (
history []*imagetype.HistoryResponseItem
@@ -51,6 +57,7 @@ func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imaget
)
s := i.client.SnapshotService(i.snapshotter)
diffIDs := ociimage.RootFS.DiffIDs
for i := range diffIDs {
chainID := identity.ChainID(diffIDs[0 : i+1]).String()
@@ -62,7 +69,7 @@ func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imaget
sizes = append(sizes, use.Size)
}
for _, h := range image.History {
for _, h := range ociimage.History {
size := int64(0)
if !h.EmptyLayer {
if len(sizes) == 0 {
@@ -83,20 +90,23 @@ func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imaget
}
if len(history) != 0 {
history[0].ID = desc.Digest.String()
history[0].ID = desc.Target.Digest.String()
tagged, err := i.client.ImageService().List(ctx, "target.digest=="+desc.Digest.String())
tagged, err := i.client.ImageService().List(ctx, "target.digest=="+desc.Target.Digest.String())
if err != nil {
return nil, err
}
tags := make([]string, len(tagged))
for i, t := range tagged {
var tags []string
for _, t := range tagged {
if isDanglingImage(t) {
continue
}
name, err := reference.ParseNamed(t.Name)
if err != nil {
return nil, err
}
tags[i] = reference.FamiliarString(name)
tags = append(tags, reference.FamiliarString(name))
}
history[0].Tags = tags
}

View File

@@ -18,6 +18,7 @@ import (
"github.com/docker/docker/builder/dockerfile"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/pools"
"github.com/google/uuid"
@@ -46,7 +47,11 @@ func (i *ImageService) ImportImage(ctx context.Context, ref reference.Named, pla
if err != nil {
return "", errdefs.System(err)
}
defer release(ctx)
defer func() {
if err := release(compatcontext.WithoutCancel(ctx)); err != nil {
logger.WithError(err).Warn("failed to release lease created for import")
}
}()
if platform == nil {
def := platforms.DefaultSpec()
@@ -86,11 +91,10 @@ func (i *ImageService) ImportImage(ctx context.Context, ref reference.Named, pla
ociCfg := containerConfigToOciImageConfig(imageConfig)
createdAt := time.Now()
config := ocispec.Image{
Architecture: platform.Architecture,
OS: platform.OS,
Created: &createdAt,
Author: "",
Config: ociCfg,
Platform: *platform,
Created: &createdAt,
Author: "",
Config: ociCfg,
RootFS: ocispec.RootFS{
Type: "layers",
DiffIDs: []digest.Digest{uncompressedDigest},
@@ -256,9 +260,9 @@ func compressAndWriteBlob(ctx context.Context, cs content.Store, compression arc
writeChan := make(chan digest.Digest)
// Start copying the blob to the content store from the pipe.
go func() {
digest, err := writeBlobAndReturnDigest(ctx, cs, mediaType, pr)
dgst, err := writeBlobAndReturnDigest(ctx, cs, mediaType, pr)
pr.CloseWithError(err)
writeChan <- digest
writeChan <- dgst
}()
// Copy archive to the pipe and tee it to a digester.
@@ -393,8 +397,11 @@ func containerConfigToOciImageConfig(cfg *container.Config) ocispec.ImageConfig
StopSignal: cfg.StopSignal,
ArgsEscaped: cfg.ArgsEscaped,
}
for k, v := range cfg.ExposedPorts {
ociCfg.ExposedPorts[string(k)] = v
if len(cfg.ExposedPorts) > 0 {
ociCfg.ExposedPorts = map[string]struct{}{}
for k, v := range cfg.ExposedPorts {
ociCfg.ExposedPorts[string(k)] = v
}
}
return ociCfg

View File

@@ -0,0 +1,22 @@
package containerd
import (
"testing"
"github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
// regression test for https://github.com/moby/moby/issues/45904
func TestContainerConfigToOciImageConfig(t *testing.T) {
ociCFG := containerConfigToOciImageConfig(&container.Config{
ExposedPorts: nat.PortSet{
"80/tcp": struct{}{},
},
})
expected := map[string]struct{}{"80/tcp": {}}
assert.Check(t, is.DeepEqual(ociCFG.ExposedPorts, expected))
}

View File

@@ -6,20 +6,19 @@ import (
"strings"
"time"
"github.com/containerd/containerd"
"github.com/containerd/containerd/content"
cerrdefs "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/labels"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/snapshots"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
timetypes "github.com/docker/docker/api/types/time"
"github.com/moby/buildkit/util/attestation"
"github.com/docker/docker/errdefs"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/identity"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -87,72 +86,41 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions)
continue
}
err := images.Walk(ctx, images.HandlerFunc(func(ctx context.Context, desc v1.Descriptor) ([]v1.Descriptor, error) {
if images.IsIndexType(desc.MediaType) {
return images.Children(ctx, contentStore, desc)
err := i.walkImageManifests(ctx, img, func(img *ImageManifest) error {
if isPseudo, err := img.IsPseudoImage(ctx); isPseudo || err != nil {
return err
}
if images.IsManifestType(desc.MediaType) {
// Ignore buildkit attestation manifests
// https://github.com/moby/buildkit/blob/v0.11.4/docs/attestations/attestation-storage.md
// This would have also been caught by the isImageManifest call below, but it requires
// an additional content read and deserialization of Manifest.
if _, has := desc.Annotations[attestation.DockerAnnotationReferenceType]; has {
return nil, nil
}
available, err := img.CheckContentAvailable(ctx)
if err != nil {
logrus.WithFields(logrus.Fields{
logrus.ErrorKey: err,
"manifest": img.Target(),
"image": img.Name(),
}).Warn("checking availability of platform specific manifest failed")
return nil
}
mfst, err := images.Manifest(ctx, contentStore, desc, platforms.All)
if err != nil {
if cerrdefs.IsNotFound(err) {
return nil, nil
}
return nil, err
}
if !available {
return nil
}
if !isImageManifest(mfst) {
return nil, nil
}
image, chainIDs, err := i.singlePlatformImage(ctx, contentStore, img)
if err != nil {
return err
}
platform, err := getManifestPlatform(ctx, contentStore, desc, mfst.Config)
if err != nil {
if cerrdefs.IsNotFound(err) {
return nil, nil
}
return nil, err
}
summaries = append(summaries, image)
pm := platforms.OnlyStrict(platform)
available, _, _, missing, err := images.Check(ctx, contentStore, img.Target, pm)
if err != nil {
logrus.WithFields(logrus.Fields{
logrus.ErrorKey: err,
"platform": platform,
"image": img.Target,
}).Warn("checking availability of platform content failed")
return nil, nil
}
if !available || len(missing) > 0 {
return nil, nil
}
c8dImage := containerd.NewImageWithPlatform(i.client, img, pm)
image, chainIDs, err := i.singlePlatformImage(ctx, contentStore, c8dImage)
if err != nil {
return nil, err
}
summaries = append(summaries, image)
if opts.SharedSize {
root = append(root, &chainIDs)
for _, id := range chainIDs {
layers[id] = layers[id] + 1
}
if opts.SharedSize {
root = append(root, &chainIDs)
for _, id := range chainIDs {
layers[id] = layers[id] + 1
}
}
return nil, nil
}), img.Target)
return nil
})
if err != nil {
return nil, err
@@ -173,44 +141,35 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions)
return summaries, nil
}
func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore content.Store, image containerd.Image) (*types.ImageSummary, []digest.Digest, error) {
func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore content.Store, image *ImageManifest) (*types.ImageSummary, []digest.Digest, error) {
diffIDs, err := image.RootFS(ctx)
if err != nil {
return nil, nil, err
}
chainIDs := identity.ChainIDs(diffIDs)
size, err := image.Size(ctx)
if err != nil {
return nil, nil, err
return nil, nil, errors.Wrapf(err, "failed to get rootfs of image %s", image.Name())
}
// TODO(thaJeztah): do we need to take multiple snapshotters into account? See https://github.com/moby/moby/issues/45273
snapshotter := i.client.SnapshotService(i.snapshotter)
sizeCache := make(map[digest.Digest]int64)
snapshotSizeFn := func(d digest.Digest) (int64, error) {
if s, ok := sizeCache[d]; ok {
return s, nil
imageSnapshotID := identity.ChainID(diffIDs).String()
unpackedUsage, err := calculateSnapshotTotalUsage(ctx, snapshotter, imageSnapshotID)
if err != nil {
if !cerrdefs.IsNotFound(err) {
logrus.WithError(err).WithFields(logrus.Fields{
"image": image.Name(),
"snapshotID": imageSnapshotID,
}).Warn("failed to calculate unpacked size of image")
}
usage, err := snapshotter.Usage(ctx, d.String())
if err != nil {
if cerrdefs.IsNotFound(err) {
return 0, nil
}
return 0, err
}
sizeCache[d] = usage.Size
return usage.Size, nil
unpackedUsage = snapshots.Usage{Size: 0}
}
snapshotSize, err := computeSnapshotSize(chainIDs, snapshotSizeFn)
contentSize, err := image.Size(ctx)
if err != nil {
return nil, nil, err
}
// totalSize is the size of the image's packed layers and snapshots
// (unpacked layers) combined.
totalSize := size + snapshotSize
totalSize := contentSize + unpackedUsage.Size
var repoTags, repoDigests []string
rawImg := image.Metadata()
@@ -259,7 +218,7 @@ func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore con
Containers: -1,
}
return summary, chainIDs, nil
return summary, identity.ChainIDs(diffIDs), nil
}
type imageFilterFunc func(image images.Image) bool
@@ -418,7 +377,7 @@ func setupLabelFilter(store content.Store, fltrs filters.Args) (func(image image
// processing more content (otherwise it will run for all children).
// It will be returned once a matching config is found.
errFoundConfig := errors.New("success, found matching config")
err := images.Dispatch(ctx, presentChildrenHandler(store, images.HandlerFunc(func(ctx context.Context, desc v1.Descriptor) (subdescs []v1.Descriptor, err error) {
err := images.Dispatch(ctx, presentChildrenHandler(store, images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) (subdescs []ocispec.Descriptor, err error) {
if !images.IsConfigType(desc.MediaType) {
return nil, nil
}
@@ -480,20 +439,6 @@ func setupLabelFilter(store content.Store, fltrs filters.Args) (func(image image
}, nil
}
// computeSnapshotSize calculates the total size consumed by the snapshots
// for the given chainIDs.
func computeSnapshotSize(chainIDs []digest.Digest, sizeFn func(d digest.Digest) (int64, error)) (int64, error) {
var totalSize int64
for _, chainID := range chainIDs {
size, err := sizeFn(chainID)
if err != nil {
return totalSize, err
}
totalSize += size
}
return totalSize, nil
}
func computeSharedSize(chainIDs []digest.Digest, layers map[digest.Digest]int, sizeFn func(d digest.Digest) (int64, error)) (int64, error) {
var sharedSize int64
for _, chainID := range chainIDs {
@@ -509,42 +454,24 @@ func computeSharedSize(chainIDs []digest.Digest, layers map[digest.Digest]int, s
return sharedSize, nil
}
// getManifestPlatform returns a platform specified by the manifest descriptor
// or reads it from its config.
func getManifestPlatform(ctx context.Context, store content.Provider, manifestDesc, configDesc v1.Descriptor) (v1.Platform, error) {
var platform v1.Platform
if manifestDesc.Platform != nil {
platform = *manifestDesc.Platform
} else {
// Config is technically a v1.Image, but it has the same member as v1.Platform
// which makes the v1.Platform a subset of Image so we can unmarshal directly.
if err := readConfig(ctx, store, configDesc, &platform); err != nil {
return platform, err
}
}
return platforms.Normalize(platform), nil
}
// isImageManifest returns true if the manifest has any layer that is a known image layer.
// Some manifests use the image media type for compatibility, even if they are not a real image.
func isImageManifest(mfst v1.Manifest) bool {
for _, l := range mfst.Layers {
if images.IsLayerType(l.MediaType) {
return true
}
}
return false
}
// readConfig reads content pointed by the descriptor and unmarshals it into a specified output.
func readConfig(ctx context.Context, store content.Provider, desc v1.Descriptor, out interface{}) error {
func readConfig(ctx context.Context, store content.Provider, desc ocispec.Descriptor, out interface{}) error {
data, err := content.ReadBlob(ctx, store, desc)
if err != nil {
return errors.Wrapf(err, "failed to read config content")
err = errors.Wrapf(err, "failed to read config content")
if cerrdefs.IsNotFound(err) {
return errdefs.NotFound(err)
}
return err
}
err = json.Unmarshal(data, out)
if err != nil {
return errors.Wrapf(err, "could not deserialize image config")
err = errors.Wrapf(err, "could not deserialize image config")
if cerrdefs.IsNotFound(err) {
return errdefs.NotFound(err)
}
return err
}
return nil

View File

@@ -0,0 +1,151 @@
package containerd
import (
"context"
"encoding/json"
"github.com/containerd/containerd"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/images"
containerdimages "github.com/containerd/containerd/images"
cplatforms "github.com/containerd/containerd/platforms"
"github.com/docker/docker/errdefs"
"github.com/moby/buildkit/util/attestation"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
var (
errNotManifestOrIndex = errdefs.InvalidParameter(errors.New("descriptor is neither a manifest or index"))
errNotManifest = errdefs.InvalidParameter(errors.New("descriptor isn't a manifest"))
)
// walkImageManifests calls the handler for each locally present manifest in
// the image. The image implements the containerd.Image interface, but all
// operations act on the specific manifest instead of the index.
func (i *ImageService) walkImageManifests(ctx context.Context, img containerdimages.Image, handler func(img *ImageManifest) error) error {
desc := img.Target
handleManifest := func(ctx context.Context, d ocispec.Descriptor) error {
platformImg, err := i.NewImageManifest(ctx, img, d)
if err != nil {
if err == errNotManifest {
return nil
}
return err
}
return handler(platformImg)
}
if containerdimages.IsManifestType(desc.MediaType) {
return handleManifest(ctx, desc)
}
if containerdimages.IsIndexType(desc.MediaType) {
return i.walkPresentChildren(ctx, desc, handleManifest)
}
return errNotManifestOrIndex
}
type ImageManifest struct {
containerd.Image
// Parent of the manifest (index/manifest list)
RealTarget ocispec.Descriptor
manifest *ocispec.Manifest
}
func (i *ImageService) NewImageManifest(ctx context.Context, img containerdimages.Image, manifestDesc ocispec.Descriptor) (*ImageManifest, error) {
if !containerdimages.IsManifestType(manifestDesc.MediaType) {
return nil, errNotManifest
}
parent := img.Target
img.Target = manifestDesc
c8dImg := containerd.NewImageWithPlatform(i.client, img, cplatforms.All)
return &ImageManifest{
Image: c8dImg,
RealTarget: parent,
}, nil
}
func (im *ImageManifest) Metadata() containerdimages.Image {
md := im.Image.Metadata()
md.Target = im.RealTarget
return md
}
// IsPseudoImage returns false if the manifest has no layers or any of its layers is a known image layer.
// Some manifests use the image media type for compatibility, even if they are not a real image.
func (im *ImageManifest) IsPseudoImage(ctx context.Context) (bool, error) {
desc := im.Target()
// Quick check for buildkit attestation manifests
// https://github.com/moby/buildkit/blob/v0.11.4/docs/attestations/attestation-storage.md
// This would have also been caught by the layer check below, but it requires
// an additional content read and deserialization of Manifest.
if _, has := desc.Annotations[attestation.DockerAnnotationReferenceType]; has {
return true, nil
}
mfst, err := im.Manifest(ctx)
if err != nil {
return true, err
}
if len(mfst.Layers) == 0 {
return false, nil
}
for _, l := range mfst.Layers {
if images.IsLayerType(l.MediaType) {
return false, nil
}
}
return true, nil
}
func (im *ImageManifest) Manifest(ctx context.Context) (ocispec.Manifest, error) {
if im.manifest != nil {
return *im.manifest, nil
}
mfst, err := readManifest(ctx, im.ContentStore(), im.Target())
if err != nil {
return ocispec.Manifest{}, err
}
im.manifest = &mfst
return mfst, nil
}
func (im *ImageManifest) CheckContentAvailable(ctx context.Context) (bool, error) {
// The target is already a platform-specific manifest, so no need to match platform.
pm := cplatforms.All
available, _, _, missing, err := containerdimages.Check(ctx, im.ContentStore(), im.Target(), pm)
if err != nil {
return false, err
}
if !available || len(missing) > 0 {
return false, nil
}
return true, nil
}
func readManifest(ctx context.Context, store content.Provider, desc ocispec.Descriptor) (ocispec.Manifest, error) {
p, err := content.ReadBlob(ctx, store, desc)
if err != nil {
return ocispec.Manifest{}, err
}
var mfst ocispec.Manifest
if err := json.Unmarshal(p, &mfst); err != nil {
return ocispec.Manifest{}, err
}
return mfst, nil
}

View File

@@ -2,6 +2,7 @@ package containerd
import (
"context"
"strings"
cerrdefs "github.com/containerd/containerd/errdefs"
containerdimages "github.com/containerd/containerd/images"
@@ -69,35 +70,50 @@ func (i *ImageService) pruneUnused(ctx context.Context, filterFunc imageFilterFu
return nil, err
}
// How many images make reference to a particular target digest.
digestRefCount := map[digest.Digest]int{}
// Images considered for pruning.
imagesToPrune := map[string]containerdimages.Image{}
for _, img := range allImages {
digestRefCount[img.Target.Digest] += 1
if !danglingOnly || isDanglingImage(img) {
imagesToPrune[img.Name] = img
canBePruned := filterFunc(img)
logrus.WithFields(logrus.Fields{
"image": img.Name,
"canBePruned": canBePruned,
}).Debug("considering image for pruning")
if canBePruned {
imagesToPrune[img.Name] = img
}
}
}
// Apply filters
for name, img := range imagesToPrune {
filteredOut := !filterFunc(img)
logrus.WithFields(logrus.Fields{
"image": name,
"filteredOut": filteredOut,
}).Debug("filtering image")
// Image specified by digests that are used by containers.
usedDigests := map[digest.Digest]struct{}{}
if filteredOut {
delete(imagesToPrune, name)
}
}
containers := i.containers.List()
var errs error
// Exclude images used by existing containers
for _, ctr := range containers {
for _, ctr := range i.containers.List() {
// If the original image was deleted, make sure we don't delete the dangling image
delete(imagesToPrune, danglingImageName(ctr.ImageID.Digest()))
// Config.Image is the image reference passed by user.
// For example: container created by `docker run alpine` will have Image="alpine"
// Warning: This doesn't handle truncated ids:
// `docker run 124c7d2` will have Image="124c7d270790"
// Config.ImageID is the resolved content digest based on the user's Config.Image.
// For example: container created by:
// `docker run alpine` will have Config.Image="alpine"
// `docker run 82d1e9d` will have Config.Image="82d1e9d"
// but both will have ImageID="sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1"
imageDgst := ctr.ImageID.Digest()
// If user didn't specify an explicit image, mark the digest as used.
normalizedImageID := "sha256:" + strings.TrimPrefix(ctr.Config.Image, "sha256:")
if strings.HasPrefix(imageDgst.String(), normalizedImageID) {
usedDigests[imageDgst] = struct{}{}
continue
}
ref, err := reference.ParseNormalizedNamed(ctr.Config.Image)
logrus.WithFields(logrus.Fields{
"ctr": ctr.ID,
@@ -106,12 +122,28 @@ func (i *ImageService) pruneUnused(ctx context.Context, filterFunc imageFilterFu
}).Debug("filtering container's image")
if err == nil {
// If user provided a specific image name, exclude that image.
name := reference.TagNameOnly(ref)
delete(imagesToPrune, name.String())
}
}
// Create dangling images for images that will be deleted but are still in use.
for _, img := range imagesToPrune {
dgst := img.Target.Digest
digestRefCount[dgst] -= 1
if digestRefCount[dgst] == 0 {
if _, isUsed := usedDigests[dgst]; isUsed {
if err := i.ensureDanglingImage(ctx, img); err != nil {
return &report, errors.Wrapf(err, "failed to create ensure dangling image for %s", img.Name)
}
}
}
}
possiblyDeletedConfigs := map[digest.Digest]struct{}{}
var errs error
// Workaround for https://github.com/moby/buildkit/issues/3797
defer func() {
@@ -125,11 +157,12 @@ func (i *ImageService) pruneUnused(ctx context.Context, filterFunc imageFilterFu
blobs := []ocispec.Descriptor{}
err := i.walkPresentChildren(ctx, img.Target, func(_ context.Context, desc ocispec.Descriptor) {
err := i.walkPresentChildren(ctx, img.Target, func(_ context.Context, desc ocispec.Descriptor) error {
blobs = append(blobs, desc)
if containerdimages.IsConfigType(desc.MediaType) {
possiblyDeletedConfigs[desc.Digest] = struct{}{}
}
return nil
})
if err != nil {
errs = multierror.Append(errs, err)
@@ -186,10 +219,11 @@ func (i *ImageService) unleaseSnapshotsFromDeletedConfigs(ctx context.Context, p
var errs error
for _, img := range all {
err := i.walkPresentChildren(ctx, img.Target, func(_ context.Context, desc ocispec.Descriptor) {
err := i.walkPresentChildren(ctx, img.Target, func(_ context.Context, desc ocispec.Descriptor) error {
if containerdimages.IsConfigType(desc.MediaType) {
delete(possiblyDeletedConfigs, desc.Digest)
}
return nil
})
if err != nil {
errs = multierror.Append(errs, err)

View File

@@ -14,13 +14,13 @@ import (
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/streamformatter"
"github.com/opencontainers/go-digest"
specs "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/sirupsen/logrus"
)
// PullImage initiates a pull operation. image is the repository name to pull, and
// tagOrDigest may be either empty, or indicate a specific tag or digest to pull.
func (i *ImageService) PullImage(ctx context.Context, image, tagOrDigest string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error {
func (i *ImageService) PullImage(ctx context.Context, image, tagOrDigest string, platform *ocispec.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error {
var opts []containerd.RemoteOpt
if platform != nil {
opts = append(opts, containerd.WithPlatform(platforms.Format(*platform)))
@@ -45,11 +45,11 @@ func (i *ImageService) PullImage(ctx context.Context, image, tagOrDigest string,
}
}
resolver, _ := i.newResolverFromAuthConfig(authConfig)
resolver, _ := i.newResolverFromAuthConfig(ctx, authConfig)
opts = append(opts, containerd.WithResolver(resolver))
jobs := newJobs()
h := images.HandlerFunc(func(ctx context.Context, desc specs.Descriptor) ([]specs.Descriptor, error) {
h := images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
if desc.MediaType != images.MediaTypeDockerSchema1Manifest {
jobs.Add(desc)
}

View File

@@ -17,6 +17,7 @@ import (
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/pkg/streamformatter"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -46,9 +47,8 @@ func (i *ImageService) PushImage(ctx context.Context, targetRef reference.Named,
return err
}
defer func() {
err := release(leasedCtx)
if err != nil && !cerrdefs.IsNotFound(err) {
logrus.WithField("image", targetRef).WithError(err).Error("failed to delete lease created for push")
if err := release(compatcontext.WithoutCancel(leasedCtx)); err != nil {
logrus.WithField("image", targetRef).WithError(err).Warn("failed to release lease created for push")
}
}()
@@ -62,7 +62,7 @@ func (i *ImageService) PushImage(ctx context.Context, targetRef reference.Named,
target := img.Target
store := i.client.ContentStore()
resolver, tracker := i.newResolverFromAuthConfig(authConfig)
resolver, tracker := i.newResolverFromAuthConfig(ctx, authConfig)
progress := pushProgress{Tracker: tracker}
jobsQueue := newJobs()
finishProgress := jobsQueue.showProgress(ctx, out, combinedProgress([]progressUpdater{

View File

@@ -2,40 +2,61 @@ package containerd
import (
"context"
"fmt"
"github.com/containerd/containerd"
cerrdefs "github.com/containerd/containerd/errdefs"
containerdimages "github.com/containerd/containerd/images"
"github.com/containerd/containerd/leases"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/snapshots"
"github.com/docker/docker/errdefs"
"github.com/opencontainers/image-spec/identity"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
// PrepareSnapshot prepares a snapshot from a parent image for a container
func (i *ImageService) PrepareSnapshot(ctx context.Context, id string, parentImage string, platform *v1.Platform) error {
desc, err := i.resolveDescriptor(ctx, parentImage)
if err != nil {
return err
func (i *ImageService) PrepareSnapshot(ctx context.Context, id string, parentImage string, platform *ocispec.Platform) error {
var parentSnapshot string
if parentImage != "" {
img, err := i.resolveImage(ctx, parentImage)
if err != nil {
return err
}
cs := i.client.ContentStore()
matcher := platforms.Default()
if platform != nil {
matcher = platforms.Only(*platform)
}
platformImg := containerd.NewImageWithPlatform(i.client, img, matcher)
unpacked, err := platformImg.IsUnpacked(ctx, i.snapshotter)
if err != nil {
return err
}
if !unpacked {
if err := platformImg.Unpack(ctx, i.snapshotter); err != nil {
return err
}
}
desc, err := containerdimages.Config(ctx, cs, img.Target, matcher)
if err != nil {
return err
}
diffIDs, err := containerdimages.RootFS(ctx, cs, desc)
if err != nil {
return err
}
parentSnapshot = identity.ChainID(diffIDs).String()
}
cs := i.client.ContentStore()
matcher := platforms.Default()
if platform != nil {
matcher = platforms.Only(*platform)
}
desc, err = containerdimages.Config(ctx, cs, desc, matcher)
if err != nil {
return err
}
diffIDs, err := containerdimages.RootFS(ctx, cs, desc)
if err != nil {
return err
}
parent := identity.ChainID(diffIDs).String()
// Add a lease so that containerd doesn't garbage collect our snapshot
ls := i.client.LeasesService()
lease, err := ls.Create(ctx, leases.WithID(id))
@@ -51,6 +72,49 @@ func (i *ImageService) PrepareSnapshot(ctx context.Context, id string, parentIma
}
s := i.client.SnapshotService(i.StorageDriver())
_, err = s.Prepare(ctx, id, parent)
_, err = s.Prepare(ctx, id, parentSnapshot)
return err
}
// calculateSnapshotParentUsage returns the usage of all ancestors of the
// provided snapshot. It doesn't include the size of the snapshot itself.
func calculateSnapshotParentUsage(ctx context.Context, snapshotter snapshots.Snapshotter, snapshotID string) (snapshots.Usage, error) {
info, err := snapshotter.Stat(ctx, snapshotID)
if err != nil {
if cerrdefs.IsNotFound(err) {
return snapshots.Usage{}, errdefs.NotFound(err)
}
return snapshots.Usage{}, errdefs.System(errors.Wrapf(err, "snapshotter.Stat failed for %s", snapshotID))
}
if info.Parent == "" {
return snapshots.Usage{}, errdefs.NotFound(fmt.Errorf("snapshot %s has no parent", snapshotID))
}
return calculateSnapshotTotalUsage(ctx, snapshotter, info.Parent)
}
// calculateSnapshotTotalUsage returns the total usage of that snapshot
// including all of its ancestors.
func calculateSnapshotTotalUsage(ctx context.Context, snapshotter snapshots.Snapshotter, snapshotID string) (snapshots.Usage, error) {
var total snapshots.Usage
next := snapshotID
for next != "" {
usage, err := snapshotter.Usage(ctx, next)
if err != nil {
if cerrdefs.IsNotFound(err) {
return total, errdefs.NotFound(errors.Wrapf(err, "non-existing ancestor of %s", snapshotID))
}
return total, errdefs.System(errors.Wrapf(err, "snapshotter.Usage failed for %s", next))
}
total.Size += usage.Size
total.Inodes += usage.Inodes
info, err := snapshotter.Stat(ctx, next)
if err != nil {
return total, errdefs.System(errors.Wrapf(err, "snapshotter.Stat failed for %s", next))
}
next = info.Parent
}
return total, nil
}

View File

@@ -3,9 +3,7 @@ package containerd
import (
"context"
"fmt"
"os"
"github.com/containerd/containerd/mount"
"github.com/docker/docker/container"
"github.com/sirupsen/logrus"
)
@@ -19,17 +17,13 @@ func (i *ImageService) Mount(ctx context.Context, container *container.Container
return err
}
// The temporary location will be under /var/lib/docker/... because
// we set the `TMPDIR`
root, err := os.MkdirTemp("", fmt.Sprintf("%s_rootfs-mount", container.ID))
if err != nil {
return fmt.Errorf("failed to create temp dir: %w", err)
}
if err := mount.All(mounts, root); err != nil {
var root string
if root, err = i.refCountMounter.Mount(mounts, container.ID); err != nil {
return fmt.Errorf("failed to mount %s: %w", root, err)
}
logrus.WithField("container", container.ID).Debugf("container mounted via snapshotter: %v", root)
container.BaseFS = root
return nil
}
@@ -38,15 +32,10 @@ func (i *ImageService) Mount(ctx context.Context, container *container.Container
func (i *ImageService) Unmount(ctx context.Context, container *container.Container) error {
root := container.BaseFS
if err := mount.UnmountAll(root, 0); err != nil {
if err := i.refCountMounter.Unmount(root); err != nil {
logrus.WithField("container", container.ID).WithError(err).Error("error unmounting container")
return fmt.Errorf("failed to unmount %s: %w", root, err)
}
if err := os.Remove(root); err != nil {
logrus.WithError(err).WithField("dir", root).Error("failed to remove mount temp dir")
}
container.BaseFS = ""
return nil
}

View File

@@ -152,7 +152,7 @@ func (p pullProgress) UpdateProgress(ctx context.Context, ongoing *jobs, out pro
} else if p.ShowExists {
out.WriteProgress(progress.Progress{
ID: stringid.TruncateID(j.Digest.Encoded()),
Action: "Exists",
Action: "Already exists",
HideCounts: true,
LastUpdate: true,
})

View File

@@ -1,30 +1,42 @@
package containerd
import (
"context"
"crypto/tls"
"errors"
"net/http"
"github.com/containerd/containerd/remotes"
"github.com/containerd/containerd/remotes/docker"
"github.com/containerd/containerd/version"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/pkg/useragent"
"github.com/docker/docker/registry"
"github.com/sirupsen/logrus"
)
func (i *ImageService) newResolverFromAuthConfig(authConfig *registrytypes.AuthConfig) (remotes.Resolver, docker.StatusTracker) {
func (i *ImageService) newResolverFromAuthConfig(ctx context.Context, authConfig *registrytypes.AuthConfig) (remotes.Resolver, docker.StatusTracker) {
tracker := docker.NewInMemoryTracker()
hostsFn := i.registryHosts.RegistryHosts()
hosts := hostsWrapper(hostsFn, authConfig, i.registryService)
headers := http.Header{}
headers.Set("User-Agent", dockerversion.DockerUserAgent(ctx, useragent.VersionInfo{Name: "containerd-client", Version: version.Version}, useragent.VersionInfo{Name: "storage-driver", Version: i.snapshotter}))
return docker.NewResolver(docker.ResolverOptions{
Hosts: hosts,
Tracker: tracker,
Headers: headers,
}), tracker
}
func hostsWrapper(hostsFn docker.RegistryHosts, authConfig *registrytypes.AuthConfig, regService RegistryConfigProvider) docker.RegistryHosts {
func hostsWrapper(hostsFn docker.RegistryHosts, optAuthConfig *registrytypes.AuthConfig, regService RegistryConfigProvider) docker.RegistryHosts {
var authorizer docker.Authorizer
if optAuthConfig != nil {
authorizer = docker.NewDockerAuthorizer(authorizationCredsFromAuthConfig(*optAuthConfig))
}
return func(n string) ([]docker.RegistryHost, error) {
hosts, err := hostsFn(n)
if err != nil {
@@ -33,12 +45,7 @@ func hostsWrapper(hostsFn docker.RegistryHosts, authConfig *registrytypes.AuthCo
for i := range hosts {
if hosts[i].Authorizer == nil {
var opts []docker.AuthorizerOpt
if authConfig != nil {
opts = append(opts, authorizationCredsFromAuthConfig(*authConfig))
}
hosts[i].Authorizer = docker.NewDockerAuthorizer(opts...)
hosts[i].Authorizer = authorizer
isInsecure := regService.IsInsecureRegistry(hosts[i].Host)
if hosts[i].Client.Transport != nil && isInsecure {
hosts[i].Client.Transport = httpFallback{super: hosts[i].Client.Transport}
@@ -51,13 +58,16 @@ func hostsWrapper(hostsFn docker.RegistryHosts, authConfig *registrytypes.AuthCo
func authorizationCredsFromAuthConfig(authConfig registrytypes.AuthConfig) docker.AuthorizerOpt {
cfgHost := registry.ConvertToHostname(authConfig.ServerAddress)
if cfgHost == registry.IndexHostname {
if cfgHost == "" || cfgHost == registry.IndexHostname {
cfgHost = registry.DefaultRegistryHost
}
return docker.WithAuthCreds(func(host string) (string, string, error) {
if cfgHost != host {
logrus.WithField("host", host).WithField("cfgHost", cfgHost).Warn("Host doesn't match")
logrus.WithFields(logrus.Fields{
"host": host,
"cfgHost": cfgHost,
}).Warn("Host doesn't match")
return "", "", nil
}
if authConfig.IdentityToken != "" {

View File

@@ -2,23 +2,23 @@ package containerd
import (
"context"
"encoding/json"
"fmt"
"sync/atomic"
"github.com/containerd/containerd"
"github.com/containerd/containerd/content"
cerrdefs "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/remotes/docker"
"github.com/containerd/containerd/snapshots"
imagetypes "github.com/docker/docker/api/types/image"
"github.com/docker/distribution/reference"
"github.com/docker/docker/container"
daemonevents "github.com/docker/docker/daemon/events"
"github.com/docker/docker/daemon/images"
"github.com/docker/docker/daemon/snapshotter"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/identity"
"github.com/docker/docker/registry"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -33,6 +33,7 @@ type ImageService struct {
registryService RegistryConfigProvider
eventsService *daemonevents.Events
pruneRunning atomic.Bool
refCountMounter snapshotter.Mounter
}
type RegistryHostsProvider interface {
@@ -41,15 +42,17 @@ type RegistryHostsProvider interface {
type RegistryConfigProvider interface {
IsInsecureRegistry(host string) bool
ResolveRepository(name reference.Named) (*registry.RepositoryInfo, error)
}
type ImageServiceConfig struct {
Client *containerd.Client
Containers container.Store
Snapshotter string
HostsProvider RegistryHostsProvider
Registry RegistryConfigProvider
EventsService *daemonevents.Events
Client *containerd.Client
Containers container.Store
Snapshotter string
HostsProvider RegistryHostsProvider
Registry RegistryConfigProvider
EventsService *daemonevents.Events
RefCountMounter snapshotter.Mounter
}
// NewService creates a new ImageService.
@@ -61,6 +64,7 @@ func NewService(config ImageServiceConfig) *ImageService {
registryHosts: config.HostsProvider,
registryService: config.Registry,
eventsService: config.EventsService,
refCountMounter: config.RefCountMounter,
}
}
@@ -158,72 +162,29 @@ func (i *ImageService) GetContainerLayerSize(ctx context.Context, containerID st
}
snapshotter := i.client.SnapshotService(ctr.Driver)
usage, err := snapshotter.Usage(ctx, containerID)
rwLayerUsage, err := snapshotter.Usage(ctx, containerID)
if err != nil {
return 0, 0, err
}
imageManifest, err := getContainerImageManifest(ctr)
if err != nil {
// Best efforts attempt to pick an image.
// We don't have platform information at this point, so we can only
// assume that the platform matches host.
// Otherwise this will give a wrong base image size (different
// platform), but should be close enough.
mfst, err := i.GetImageManifest(ctx, ctr.Config.Image, imagetypes.GetImageOpts{})
if err != nil {
// Log error, don't error out whole operation.
logrus.WithFields(logrus.Fields{
logrus.ErrorKey: err,
"container": containerID,
}).Warn("empty ImageManifest, can't calculate base image size")
return usage.Size, 0, nil
if cerrdefs.IsNotFound(err) {
return 0, 0, errdefs.NotFound(fmt.Errorf("rw layer snapshot not found for container %s", containerID))
}
imageManifest = *mfst
return 0, 0, errdefs.System(errors.Wrapf(err, "snapshotter.Usage failed for %s", containerID))
}
cs := i.client.ContentStore()
imageManifestBytes, err := content.ReadBlob(ctx, cs, imageManifest)
unpackedUsage, err := calculateSnapshotParentUsage(ctx, snapshotter, containerID)
if err != nil {
return 0, 0, err
}
var manifest ocispec.Manifest
if err := json.Unmarshal(imageManifestBytes, &manifest); err != nil {
return 0, 0, err
}
imageConfigBytes, err := content.ReadBlob(ctx, cs, manifest.Config)
if err != nil {
return 0, 0, err
}
var img ocispec.Image
if err := json.Unmarshal(imageConfigBytes, &img); err != nil {
return 0, 0, err
}
sizeCache := make(map[digest.Digest]int64)
snapshotSizeFn := func(d digest.Digest) (int64, error) {
if s, ok := sizeCache[d]; ok {
return s, nil
if cerrdefs.IsNotFound(err) {
logrus.WithField("ctr", containerID).Warn("parent of container snapshot no longer present")
} else {
logrus.WithError(err).WithField("ctr", containerID).Warn("unexpected error when calculating usage of the parent snapshots")
}
u, err := snapshotter.Usage(ctx, d.String())
if err != nil {
return 0, err
}
sizeCache[d] = u.Size
return u.Size, nil
}
chainIDs := identity.ChainIDs(img.RootFS.DiffIDs)
snapShotSize, err := computeSnapshotSize(chainIDs, snapshotSizeFn)
if err != nil {
return 0, 0, err
}
logrus.WithFields(logrus.Fields{
"rwLayerUsage": rwLayerUsage.Size,
"unpacked": unpackedUsage.Size,
}).Debug("GetContainerLayerSize")
// TODO(thaJeztah): include content-store size for the image (similar to "GET /images/json")
return usage.Size, usage.Size + snapShotSize, nil
return rwLayerUsage.Size, rwLayerUsage.Size + unpackedUsage.Size, nil
}
// getContainerImageManifest safely dereferences ImageManifest.

View File

@@ -7,6 +7,7 @@ import (
containerdimages "github.com/containerd/containerd/images"
"github.com/docker/docker/errdefs"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
@@ -18,10 +19,10 @@ func (i *ImageService) softImageDelete(ctx context.Context, img containerdimages
// If the image already exists, persist it as dangling image
// but only if no other image has the same target.
digest := img.Target.Digest.String()
imgs, err := is.List(ctx, "target.digest=="+digest)
dgst := img.Target.Digest.String()
imgs, err := is.List(ctx, "target.digest=="+dgst)
if err != nil {
return errdefs.System(errors.Wrapf(err, "failed to check if there are images targeting digest %s", digest))
return errdefs.System(errors.Wrapf(err, "failed to check if there are images targeting digest %s", dgst))
}
// From this point explicitly ignore the passed context
@@ -29,19 +30,12 @@ func (i *ImageService) softImageDelete(ctx context.Context, img containerdimages
// Create dangling image if this is the last image pointing to this target.
if len(imgs) == 1 {
danglingImage := img
danglingImage.Name = danglingImageName(img.Target.Digest)
delete(danglingImage.Labels, "io.containerd.image.name")
delete(danglingImage.Labels, "org.opencontainers.image.ref.name")
_, err = is.Create(context.Background(), danglingImage)
err = i.ensureDanglingImage(context.Background(), img)
// Error out in case we couldn't persist the old image.
// If it already exists, then just continue.
if err != nil && !cerrdefs.IsAlreadyExists(err) {
if err != nil {
return errdefs.System(errors.Wrapf(err, "failed to create a dangling image for the replaced image %s with digest %s",
danglingImage.Name, danglingImage.Target.Digest.String()))
img.Name, img.Target.Digest.String()))
}
}
@@ -56,6 +50,29 @@ func (i *ImageService) softImageDelete(ctx context.Context, img containerdimages
return nil
}
func (i *ImageService) ensureDanglingImage(ctx context.Context, from containerdimages.Image) error {
danglingImage := from
danglingImage.Labels = make(map[string]string)
for k, v := range from.Labels {
switch k {
case containerdimages.AnnotationImageName, ocispec.AnnotationRefName:
// Don't copy name labels.
default:
danglingImage.Labels[k] = v
}
}
danglingImage.Name = danglingImageName(from.Target.Digest)
_, err := i.client.ImageService().Create(context.Background(), danglingImage)
// If it already exists, then just continue.
if cerrdefs.IsAlreadyExists(err) {
return nil
}
return err
}
func danglingImageName(digest digest.Digest) string {
return "moby-dangling@" + digest.String()
}

View File

@@ -19,7 +19,7 @@ import (
"github.com/docker/docker/image"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/runconfig"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opencontainers/selinux/go-selinux"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -74,7 +74,7 @@ func (daemon *Daemon) containerCreate(ctx context.Context, opts createOpts) (con
}
if img != nil {
p := maximumSpec()
imgPlat := v1.Platform{
imgPlat := ocispec.Platform{
OS: img.OS,
Architecture: img.Architecture,
Variant: img.Variant,
@@ -117,7 +117,7 @@ func (daemon *Daemon) create(ctx context.Context, opts createOpts) (retC *contai
var (
ctr *container.Container
img *image.Image
imgManifest *v1.Descriptor
imgManifest *ocispec.Descriptor
imgID image.ID
err error
os = runtime.GOOS
@@ -345,7 +345,7 @@ func verifyNetworkingConfig(nwConfig *networktypes.NetworkingConfig) error {
}
// maximumSpec returns the distribution platform with maximum compatibility for the current node.
func maximumSpec() v1.Platform {
func maximumSpec() ocispec.Platform {
p := platforms.DefaultSpec()
if p.Architecture == "amd64" {
p.Variant = archvariant.AMD64Variant()

View File

@@ -40,6 +40,7 @@ import (
"github.com/docker/docker/daemon/images"
dlogger "github.com/docker/docker/daemon/logger"
"github.com/docker/docker/daemon/network"
"github.com/docker/docker/daemon/snapshotter"
"github.com/docker/docker/daemon/stats"
"github.com/docker/docker/distribution"
dmetadata "github.com/docker/docker/distribution/metadata"
@@ -129,6 +130,13 @@ type Daemon struct {
// It stores metadata for the content store (used for manifest caching)
// This needs to be closed on daemon exit
mdDB *bbolt.DB
usesSnapshotter bool
}
// ID returns the daemon id
func (daemon *Daemon) ID() string {
return daemon.id
}
// StoreHosts stores the addresses the daemon is listening on
@@ -153,16 +161,7 @@ func (daemon *Daemon) Features() *map[string]bool {
// UsesSnapshotter returns true if feature flag to use containerd snapshotter is enabled
func (daemon *Daemon) UsesSnapshotter() bool {
// TEST_INTEGRATION_USE_SNAPSHOTTER is used for integration tests only.
if os.Getenv("TEST_INTEGRATION_USE_SNAPSHOTTER") != "" {
return true
}
if daemon.configStore.Features != nil {
if b, ok := daemon.configStore.Features["containerd-snapshotter"]; ok {
return b
}
}
return false
return daemon.usesSnapshotter
}
// RegistryHosts returns registry configuration in containerd resolvers format
@@ -421,6 +420,8 @@ func (daemon *Daemon) restore() error {
if es != nil {
ces.ExitCode = int(es.ExitCode())
ces.ExitedAt = es.ExitTime()
} else {
ces.ExitCode = 255
}
c.SetStopped(&ces)
daemon.Cleanup(c)
@@ -796,6 +797,13 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
startupDone: make(chan struct{}),
}
// TEST_INTEGRATION_USE_SNAPSHOTTER is used for integration tests only.
if os.Getenv("TEST_INTEGRATION_USE_SNAPSHOTTER") != "" {
d.usesSnapshotter = true
} else {
d.usesSnapshotter = config.Features["containerd-snapshotter"]
}
// Ensure the daemon is properly shutdown if there is a failure during
// initialization
defer func() {
@@ -1018,12 +1026,13 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
return nil, err
}
d.imageService = ctrd.NewService(ctrd.ImageServiceConfig{
Client: d.containerdCli,
Containers: d.containers,
Snapshotter: driverName,
HostsProvider: d,
Registry: d.registryService,
EventsService: d.EventsService,
Client: d.containerdCli,
Containers: d.containers,
Snapshotter: driverName,
HostsProvider: d,
Registry: d.registryService,
EventsService: d.EventsService,
RefCountMounter: snapshotter.NewMounter(config.Root, driverName, idMapping),
})
} else {
layerStore, err := layer.NewStoreFromOptions(layer.StoreOptions{

Some files were not shown because too many files have changed in this diff Show More