-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
Description
Noticed this while writing a reply to;
When pushing an incomplete multi-platform image with multiple platforms available, an error should be shown, telling the user to use the --platform
flag to select what platform to push. The relevant code on the CLI side is here (but the issue is on the daemon side; CLI code is only for reference)
if err == nil && missing.ContentMissing {
note := `You're trying to push a manifest list/index which
references multiple platform specific manifests, but not all of them are available locally
or available to the remote repository.
Make sure you have all the referenced content and try again.
You can also push only a single platform specific manifest directly by specifying the platform you want to push with the --platform flag.`
notes = append(notes, note)
}
However, it looks like we don't fail the push, and go with the other path, which is to dismantle the image, and to only push a single-arch image;
var stripped auxprogress.ManifestPushedInsteadOfIndex
err := json.Unmarshal(b, &stripped)
if err == nil && stripped.ManifestPushedInsteadOfIndex {
note := fmt.Sprintf("Not all multiplatform-content is present and only the available single-platform image was pushed\n%s -> %s",
aec.RedF.Apply(stripped.OriginalIndex.Digest.String()),
aec.GreenF.Apply(stripped.SelectedManifest.Digest.String()),
)
notes = append(notes, note)
}
We should only automatically fall back to pushing a single-platform image from the manifest-index if there's only a single platform present.
Reproduce
To reproduce;
Run a local registry for testing;
$ docker run -d --name registry -p 5001:5000 registry:2
Pull 2 variants of the alpine image;
$ docker pull --quiet --platform=linux/arm64/v8 alpine:latest
$ docker pull --quiet --platform=linux/amd64 alpine:latest
Tag the image, and verify that it has 2 variants:
$ docker tag alpine localhost:5001/myimage:latest
$ docker image ls --tree localhost:5001/myimage:latest
IMAGE ID DISK USAGE CONTENT SIZE USED
localhost:5001/myimage:latest beefdbd8a1da 25.7MB 7.72MB
├─ linux/arm64/v8 9cee2b382fe2 13.6MB 4.09MB
├─ linux/amd64 33735bd63cf8 12.1MB 3.63MB
├─ linux/arm/v6 50f635c8b04d 0B 0B
├─ linux/arm/v7 f2f82d424957 0B 0B
├─ linux/386 b3e87f642f5c 0B 0B
├─ linux/ppc64le c7a6800e3dc5 0B 0B
├─ linux/riscv64 80cde017a105 0B 0B
└─ linux/s390x 2b5b26e09ca2 0B 0B
Push the image, and notice that we dismantled the image, and pushed a single-platform image instead, as the Info message describes;
$ docker push localhost:5001/myimage:latest
The push refers to repository [localhost:5001/myimage]
cf04c63912e1: Pushed
latest: digest: sha256:9cee2b382fe2412cd77d5d437d15a93da8de373813621f2e4d406e3df0cf0e7c size: 528
i Info → Not all multiplatform-content is present and only the available single-platform image was pushed
sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d -> sha256:9cee2b382fe2412cd77d5d437d15a93da8de373813621f2e4d406e3df0cf0e7c
Verify that we indeed pushed a single-platform image using docker buildx imagetools inspect
;
$ docker buildx imagetools inspect localhost:5001/myimage:latest
Name: localhost:5001/myimage:latest
MediaType: application/vnd.docker.distribution.manifest.v2+json
Digest: sha256:9cee2b382fe2412cd77d5d437d15a93da8de373813621f2e4d406e3df0cf0e7c
Expected behavior
Docker should refuse to push the image, and inform the user to use the --platform
flag to tell it which variant to push.
docker version
Client:
Version: 27.2.0
API version: 1.47
Go version: go1.21.13
Git commit: 3ab4256
Built: Tue Aug 27 14:14:45 2024
OS/Arch: darwin/arm64
Context: desktop-linux
Server: Docker Desktop 4.34.3 (170107)
Engine:
Version: 27.2.0
API version: 1.47 (minimum version 1.24)
Go version: go1.21.13
Git commit: 3ab5c7d
Built: Tue Aug 27 14:15:41 2024
OS/Arch: linux/arm64
Experimental: false
containerd:
Version: 1.7.20
GitCommit: 8fc6bcff51318944179630522a095cc9dbf9f353
runc:
Version: 1.1.13
GitCommit: v1.1.13-0-g58aa920
docker-init:
Version: 0.19.0
GitCommit: de40ad0
docker info
Client:
Version: 27.2.0
Context: desktop-linux
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.16.2-desktop.1
Path: /Applications/Docker.app/Contents/Resources/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.29.2-desktop.2
Path: /Applications/Docker.app/Contents/Resources/cli-plugins/docker-compose
debug: Get a shell into any image or container (Docker Inc.)
Version: 0.0.34
Path: /Applications/Docker.app/Contents/Resources/cli-plugins/docker-debug
desktop: Docker Desktop commands (Alpha) (Docker Inc.)
Version: v0.0.15
Path: /Applications/Docker.app/Contents/Resources/cli-plugins/docker-desktop
dev: Docker Dev Environments (Docker Inc.)
Version: v0.1.2
Path: /Applications/Docker.app/Contents/Resources/cli-plugins/docker-dev
extension: Manages Docker extensions (Docker Inc.)
Version: v0.2.25
Path: /Applications/Docker.app/Contents/Resources/cli-plugins/docker-extension
feedback: Provide feedback, right in your terminal! (Docker Inc.)
Version: v1.0.5
Path: /Applications/Docker.app/Contents/Resources/cli-plugins/docker-feedback
init: Creates Docker-related starter files for your project (Docker Inc.)
Version: v1.3.0
Path: /Applications/Docker.app/Contents/Resources/cli-plugins/docker-init
sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc.)
Version: 0.6.0
Path: /Applications/Docker.app/Contents/Resources/cli-plugins/docker-sbom
scout: Docker Scout (Docker Inc.)
Version: v1.13.0
Path: /Applications/Docker.app/Contents/Resources/cli-plugins/docker-scout
Server:
Containers: 1
Running: 1
Paused: 0
Stopped: 0
Images: 6
Server Version: 27.2.0
Storage Driver: overlayfs
driver-type: io.containerd.snapshotter.v1
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
Swarm: active
NodeID: coqxeoka66uwu1t53yj6hp0bf
Is Manager: true
ClusterID: rp95hhvjqie1jfa8nxdln8i49
Managers: 1
Nodes: 1
Default Address Pool: 10.0.0.0/8
SubnetSize: 24
Data Path Port: 4789
Orchestration:
Task History Retention Limit: 5
Raft:
Snapshot Interval: 10000
Number of Old Snapshots to Retain: 0
Heartbeat Tick: 1
Election Tick: 10
Dispatcher:
Heartbeat Period: 5 seconds
CA Configuration:
Expiry Duration: 3 months
Force Rotate: 0
Autolock Managers: false
Root Rotation In Progress: false
Node Address: 192.168.65.3
Manager Addresses:
192.168.65.3:2377
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 8fc6bcff51318944179630522a095cc9dbf9f353
runc version: v1.1.13-0-g58aa920
init version: de40ad0
Security Options:
seccomp
Profile: unconfined
Kernel Version: 6.10.4-linuxkit
Operating System: Docker Desktop
OSType: linux
Architecture: aarch64
CPUs: 10
Total Memory: 7.655GiB
Name: docker-desktop
ID: 58815d06-8744-4af3-b6f1-7a88003318ad
Docker Root Dir: /var/lib/docker
Debug Mode: true
File Descriptors: 85
Goroutines: 227
System Time: 2024-10-23T09:38:13.709729877Z
EventsListeners: 15
HTTP Proxy: http.docker.internal:3128
HTTPS Proxy: http.docker.internal:3128
No Proxy: hubproxy.docker.internal
Labels:
com.docker.desktop.address=unix:///Users/thajeztah/Library/Containers/com.docker.docker/Data/docker-cli.sock
Experimental: false
Insecure Registries:
host.docker.internal:5001
host.docker.internal:5002
hubproxy.docker.internal:5555
127.0.0.0/8
Live Restore Enabled: false
Additional Info
I noticed this on Docker Desktop with Docker 27.2, but will try reproduce on current master as well
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Status