Fallback to manifest list when no platform match#41955
Conversation
0d33ce8 to
217f0db
Compare
c9476b8 to
7f83ec5
Compare
There was a problem hiding this comment.
Just to note it somewhere - this is due to a quirk in containerd's platform matching where platforms.Normalize is invoked on both the argument to platforms.Only and the things it's being compared against, so linux/arm gets normalized to linux/arm/v7 in both cases (and thus fails if you specify --platform linux/arm/v6 on a single-arch, no-manifest-list image that only has os and architecture).
Ideally, we'd fix platforms.Only in containerd to handle this case better, but it's complicated. 😅
tianon
left a comment
There was a problem hiding this comment.
Conceptually this seems like a good workaround IMO - the logic in GetImage makes sense.
I did my best to review the flow in manifestMatchesPlatform and it seems sane to me, but I felt like I was stretching my understanding of all the APIs at play in reviewing it (so it should definitely get more eyes 🙈).
This comment has been minimized.
This comment has been minimized.
|
Also check how it behaves on https://hub.docker.com/r/balenalib/rpi-raspbian, which is not multi-arch, but has wrong arch |
In some cases, in fact many in the wild, an image may have the incorrect platform on the image config. This can lead to failures to run an image, particularly when a user specifies a `--platform`. Typically what we see in the wild is a manifest list with an an entry for, as an example, linux/arm64 pointing to an image config that has linux/amd64 on it. This change falls back to looking up the manifest list for an image to see if the manifest list shows the image as the correct one for that platform. In order to accomplish this we need to traverse the leases associated with an image. Each image, if pulled with Docker 20.10, will have the manifest list stored in the containerd content store with the resource assigned to a lease keyed on the image ID. So we look up the lease for the image, then look up the assocated resources to find the manifest list, then check the manifest list for a platform match, then ensure that manifest referes to our image config. This is only used as a fallback when a user specified they want a particular platform and the image config that we have does not match that platform. Signed-off-by: Brian Goff <[email protected]>
|
@thaJeztah That image doesn't have a manifest list so this PR doesn't improve anything there as far as I can tell. |
7f83ec5 to
504e418
Compare
|
I updated this to move the CPU variant fallback to a platform matcher that wraps re: #41955 (comment) In the case where a user does specify a platform and there is no match we error out with the same details. I don't think it makes sense to warn and error. |
504e418 to
78fb419
Compare
78fb419 to
ca81b2a
Compare
|
Looks like there's a linting failiure; |
There was a problem hiding this comment.
| retErr = errdefs.NotFound(errors.Errorf("image with reference %s was found but does not match the specified platform: wanted %s, actual: %s", refOrID, platforms.Format(p), platforms.Format(imgPlat))) | |
| return | |
| retErr = errdefs.NotFound(errors.Errorf("image with reference %s was found but does not match the specified platform: wanted %s, actual: %s", refOrID, platforms.Format(p), platforms.Format(imgPlat))) |
There was a problem hiding this comment.
(edited; noticed this was in the defer, so no error to return)
Wrap platforms.Only and fallback to our ignore mismatches due to empty CPU variants. This just cleans things up and makes the logic re-usable in other places. Signed-off-by: Brian Goff <[email protected]>
ca81b2a to
50f39e7
Compare
|
Test failiure is unrelated; that test has the same problem as I fixed in #41936 |
relates to / addresses docker/for-linux#1170 (comment)
In some cases, in fact many in the wild, an image may have the incorrect
platform on the image config.
This can lead to failures to run an image, particularly when a user
specifies a
--platform.Typically what we see in the wild is a manifest list with an an entry
for, as an example, linux/arm64 pointing to an image config that has
linux/amd64 on it.
This change falls back to looking up the manifest list for an image to
see if the manifest list shows the image as the correct one for that
platform.
In order to accomplish this we need to traverse the leases associated
with an image. Each image, if pulled with Docker 20.10, will have the
manifest list stored in the containerd content store with the resource
assigned to a lease keyed on the image ID.
So we look up the lease for the image, then look up the assocated
resources to find the manifest list, then check the manifest list for a
platform match, then ensure that manifest referes to our image config.
This is only used as a fallback when a user specified they want a
particular platform and the image config that we have does not match
that platform.