Skip to content

fix(lambda): stop rejecting a foreign-platform image the daemon cannot describe - #3357

Merged
pgermosen merged 2 commits into
floci-io:mainfrom
okinaka:fix/image-cache-foreign-platform
Sep 10, 2026
Merged

fix(lambda): stop rejecting a foreign-platform image the daemon cannot describe#3357
pgermosen merged 2 commits into
floci-io:mainfrom
okinaka:fix/image-cache-foreign-platform

Conversation

@okinaka

@okinaka okinaka commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #3304.

Docker 29 makes the containerd image store its default, and there an image
inspect answers for the index rather than for the variant that will run. For an
image pulled for another architecture it reports an empty Os and Architecture
while no other variant of that tag is local, and the host's variant once one is.
ImageCacheService compared that answer with the requested platform and threw,
so every container started for a non-host architecture failed even though the
pull had already selected the right variant:

DockerClientException: Docker image does not match requested platform linux/amd64:
  public.ecr.aws/docker/library/busybox:1.36
  • The comparison is gone. The daemon enforces the platform at both points that
    decide anything, pullImageCmd.withPlatform choosing the variant to fetch and
    createContainerCmd.withPlatform in ContainerLifecycleManager choosing the
    variant to run, so resolving the reference only has to hand back an id and say
    so plainly when the daemon reports no image at all.
  • The local-reuse check is untouched. An inspect that cannot confirm the platform
    still means "pull it", which is the safe direction and costs only a pull.
  • ContainerPlatformDockerIntegrationTest verified the platform through the same
    inspect, so it would have compared amd64 against an empty string. It now runs
    the container, whose command is uname -m, and reads what the selected variant
    reports. Running a container built for another architecture needs emulation on
    the host, so where the start fails the test falls back to the inspect
    assertion, and skips when that reading is the empty or host-variant answer that
    cannot confirm anything.

Type of change

  • Bug fix (fix:)
  • New feature (feat:)
  • Breaking change (feat!: or fix!:)
  • Docs / chore

AWS Compatibility

No wire behavior changes. This is the container launcher that every
Docker-backed service shares, and the fix restores Architectures: [arm64] on
an amd64 host, and an amd64 image on Apple Silicon, on Docker 29.

Measured on Docker 29.7.2 (macOS, Apple Silicon, containerd image store):

Reading Answer
docker image inspect <tag> right after pull --platform linux/amd64 empty Os and Architecture
the same inspect once the arm64 variant is also local linux / arm64, the host's variant
docker inspect <container> created with --platform linux/amd64 Platform: linux, no architecture
uname -m inside that container x86_64

So the only reading that describes the variant the daemon selected is the
running container, which is what the integration test now uses.

ImageCacheServiceTest gains a regression test for each of the two readings
above, both of which the old implementation rejects: the pull that comes back
described as the host's variant, and the one that comes back described as
nothing. Docker-backed classes are green together: ImageCache*,
ContainerLauncher*, ContainerPlatform*, ContainerCaBundle*,
LambdaExecutionRoleDocker*, ElbV2LambdaTargetDataPlane*, SwfLambda* and
RdsContainerManager*, 161 tests.

A full ./mvnw test on this host, with #3348 applied for the unrelated Macie
failure it fixes, runs 19150 tests with no failures. Before this change that run
ends on the exception above, since ContainerPlatformDockerIntegrationTest is
the test that exercises it.

Checklist

  • ./mvnw test passes locally
  • New or updated integration test added
  • Commit messages follow Conventional Commits

Copilot AI lite review requested due to automatic review settings September 10, 2026 07:10
@greptile-apps

greptile-apps Bot commented Sep 10, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes foreign-platform Lambda image launches on Docker 29 by no longer treating image-index inspection metadata as authoritative after a platform-specific pull.

  • Keeps platform enforcement at Docker pull and container creation.
  • Still requires the daemon to return a nonblank image ID.
  • Updates the Docker integration test to verify the architecture from inside the selected container, with an inspect fallback when emulation is unavailable.
  • Adds regression coverage for empty and host-variant platform metadata.

Confidence Score: 5/5

The PR appears safe to merge, with the previously reported timeout path fixed and no remaining actionable defects.

The daemon continues to enforce the requested platform during pull and container creation, while image resolution now avoids rejecting valid index metadata and still rejects missing or blank image IDs. The previous integration-test finding was fixed by routing wait failures through the documented inspect fallback, and its thread is resolved.

Important Files Changed

Filename Overview
src/main/java/io/github/hectorvent/floci/services/lambda/launcher/ImageCacheService.java Stops rejecting successfully pulled images based on unreliable Docker 29 index metadata while retaining image-presence and ID validation.
src/test/java/io/github/hectorvent/floci/core/common/docker/ContainerPlatformDockerIntegrationTest.java Verifies the selected foreign architecture through uname and safely falls back when emulation or container waiting fails.
src/test/java/io/github/hectorvent/floci/services/lambda/launcher/ImageCacheServiceTest.java Covers Docker 29 inspection responses that report either the host platform or no platform after a foreign-platform pull.

Reviews (5): Last reviewed commit: "test(docker): fall back to inspect when ..." | Re-trigger Greptile

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The updated ContainerPlatformDockerIntegrationTest introduces a compilation issue (return Assumptions.abort(...)) and a fallback path that can still fail due to non-best-effort log reading.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR fixes Lambda’s Docker image resolution on Docker 29 (containerd image store) by stopping Floci from rejecting a successfully pulled foreign-platform image when docker image inspect reports empty or host-variant Os/Architecture. This preserves the intended behavior where the Docker daemon enforces the requested platform at pull and container create time.

Changes:

  • Remove the post-pull platform/arch verification from ImageCacheService and only require that Docker reports an image ID.
  • Add regression tests covering Docker 29’s inspect behaviors (empty platform, or host variant after a foreign pull).
  • Update ContainerPlatformDockerIntegrationTest to verify the selected image variant primarily by running uname -m inside the container, with a fallback to daemon inspection and skip behavior when inspection cannot confirm.
File summaries
File Description
src/main/java/io/github/hectorvent/floci/services/lambda/launcher/ImageCacheService.java Stops rejecting pulled images based on unreliable inspect-reported platform, and instead resolves by image ID only.
src/test/java/io/github/hectorvent/floci/services/lambda/launcher/ImageCacheServiceTest.java Adds unit regression coverage for Docker 29 containerd index-inspect behaviors.
src/test/java/io/github/hectorvent/floci/core/common/docker/ContainerPlatformDockerIntegrationTest.java Switches verification to runtime uname -m with fallback inspect-based assertion or skip when daemon reporting is ambiguous.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@okinaka

This comment was marked as outdated.

@hectorvent hectorvent added bug Something isn't working lambda AWS Lambda labels Sep 10, 2026
@okinaka
okinaka force-pushed the fix/image-cache-foreign-platform branch from c06a9d4 to 4c2a7e2 Compare September 10, 2026 13:27
@okinaka

okinaka commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Upstream context for this, including why an inspect cannot confirm the platform and why it only surfaced on Docker 29, is collected on the issue: #3304 (comment)

The short version for review: Docker 29 can answer precisely through docker image inspect --platform, but docker-java 3.7.1's InspectImageCmd has no platform parameter, so dropping the comparison is what is available today, and the exact check can come back when the client library grows one.

@okinaka

This comment was marked as outdated.

@okinaka
okinaka force-pushed the fix/image-cache-foreign-platform branch from 4c2a7e2 to edc239d Compare September 10, 2026 14:19
…t describe

Docker 29 makes the containerd image store its default, and there an image
inspect answers for the index rather than the variant that will run: an empty Os
and Architecture while no other variant of the tag is local, and the host's
variant once one is. ImageCacheService compared that answer with the requested
platform and threw, so every container started for another architecture failed
with "Docker image does not match requested platform" even though the pull had
selected the right variant.

Drop that comparison. The daemon enforces the platform where it counts, choosing
the variant to pull and the variant to create the container from, so resolving
the reference only has to hand back an id.

The integration test verified the platform through the same inspect, so it now
runs the container and reads uname -m, falling back to inspect where the host
cannot run another architecture.
…r never reports

awaitStatusCode throws when its timeout expires, so a container that starts but
hangs failed the test instead of reaching the inspect fallback the method
documents. The wait now treats a failure the same way it treats a nonzero exit.

Reading the logs is diagnostic on that path, so it reports a failed read in the
text it returns rather than throwing, as the sibling Docker tests already do.
@okinaka
okinaka force-pushed the fix/image-cache-foreign-platform branch from edc239d to 15090da Compare September 10, 2026 15:36

@pgermosen pgermosen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Traced through why removing the check rather than patching it is right: --platform enforcement at pull and create is daemon-authoritative on every Docker version, so the old inspect-based re-check was always redundant with that, not the actual correctness mechanism, and it's actively wrong on Docker 29's containerd store. A genuinely unavailable platform still fails at the pull step itself before reaching this code, so nothing slips through. The two new unit tests mirror the exact broken readings your own measurement table documents, and the integration test's fallback to running the container degrades sensibly on a host without cross-arch emulation. Approving.

@pgermosen
pgermosen merged commit 570f975 into floci-io:main Sep 10, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working lambda AWS Lambda

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Foreign-platform container images are rejected on Docker 29

4 participants