Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker mime types contained within OCI image index #1150

Open
ibazulic opened this issue Dec 8, 2023 · 7 comments
Open

Docker mime types contained within OCI image index #1150

ibazulic opened this issue Dec 8, 2023 · 7 comments

Comments

@ibazulic
Copy link

ibazulic commented Dec 8, 2023

According to the image spec, the manifests section describes that the implementation MUST support the OCI image mime type and SHOULD support the nested indexes. It also says that when encountering a mime type that is unknown to the implementation, that an error MUST NOT be generated.

I'm wondering what exactly does the last sentence mean. Specifically, what does it mean that an error should not be generated. Should this manifest be then accepted as it was sent by the client? If it means that, then we might as well put in the specification that the manifest must be accepted regardless of what mime type the client is sending, right? Why are we then specifying the minimum requirements if we should accept all? The reason I'm asking about clarification here is that there are images on the Docker Hub that contain both Docker v2 schema 2 mime types and OCI mime types inside the same index. For instance:

# skopeo inspect --raw  docker://memcached:1.6-alpine | jq '.manifests[].mediaType'
"application/vnd.oci.image.manifest.v1+json"
"application/vnd.oci.image.manifest.v1+json"
"application/vnd.docker.distribution.manifest.v2+json"
"application/vnd.oci.image.manifest.v1+json"
"application/vnd.oci.image.manifest.v1+json"
"application/vnd.oci.image.manifest.v1+json"
"application/vnd.oci.image.manifest.v1+json"
"application/vnd.oci.image.manifest.v1+json"
"application/vnd.oci.image.manifest.v1+json"
"application/vnd.oci.image.manifest.v1+json"
"application/vnd.oci.image.manifest.v1+json"

This image will fail to be pushed to Quay in this format, because of validation, our implementation does not allow this kind of mixing and images with this kind of an OCI index are rejected:

https://github.com/quay/quay/blob/master/image/oci/__init__.py#L1

Which behaviour is correct?
Thank you for your time!

@sudo-bmitch
Copy link
Contributor

I don't believe OCI disallows this behavior, so I'd say the Quay behavior is overly restrictive. The fact that a docker media type is a known media type would mean Quay could decide they explicitly don't want to support the Docker media types, but I don't think that's happening here.

In practice, it's uncommon. Tooling that generates one type of manifest tends to be consistent for the entire image. And the reverse may not be permitted (I'm not aware of whether a docker manifest list allows non-docker media types).

In this specific image, it looks a bit weird. The linux/arm/v7 image in that index is rather old compared to the other platforms. This image may be the result of merging an update with the previous state of the image for that one platform. @tianon would have more context there.

@ibazulic
Copy link
Author

ibazulic commented Dec 9, 2023

Hey @sudo-bmitch ,

Thanks for your reply!

I don't believe OCI disallows this behavior, so I'd say the Quay behavior is overly restrictive. The fact that a docker media type is a known media type would mean Quay could decide they explicitly don't want to support the Docker media types, but I don't think that's happening here.

So, currently, Quay disallows mixing of media types. Depending on what image is the client pushing, we validate the manifest and all child manifests against our current implementation. OCI doesn't strictly disallow this kind of manifest, that's true, but as far as I'm aware, it doesn't also explicitly allow it. You say that the Docker media type is a known media type. I agree, but is it known to OCI or is it known to Docker v2 schema 2? And another question would be, if it's really up to Quay dev team to decide whether we would support this behaviour or not, how would we tell that to the client which is pushing the manifest? OCI spec says that an error should not be raised. Is 400 Bad request considered an error?

In practice, it's uncommon. Tooling that generates one type of manifest tends to be consistent for the entire image. And the reverse may not be permitted (I'm not aware of whether a docker manifest list allows non-docker media types).

As far as I know, it doesn't. But I could be wrong.

In this specific image, it looks a bit weird. The linux/arm/v7 image in that index is rather old compared to the other platforms. This image may be the result of merging an update with the previous state of the image for that one platform. @tianon would have more context there.

That's just the most recent example, I believe there are other examples of images that have the same "problem".

@dmesser
Copy link

dmesser commented Dec 22, 2023

So, should we just clarify the guidance in the spec to say something along the lines of "must accept any mediaType and as result, should support nested indexes" ?

@sudo-bmitch
Copy link
Contributor

Part of the complication is the spec is written for multiple parties, the content producer, registry, and consumer. I think it makes sense for a registry to allow any descriptor pointing to content it has already accepted (or would accept, if they aren't validating digests). For runtimes, we probably can't say they must accept media types defined outside of the spec. But anyone that writes a tool that supports that scenario shouldn't be blocked by the spec. I doubt we'll find a lot of runtimes that support nested indexes, but a lot of registries and some other tooling do.

@dmesser
Copy link

dmesser commented Jan 2, 2024

Makes sense. Would it be wrong if we get more specific about the expected behaviors of clients vs. registries at this particular point in the spec?

@codingben
Copy link

codingben commented Mar 21, 2024

We're using google/go-containerregistry in our tooling to create container images.

Our steps:

  1. Create a new image manifest from empty image base [1] that has DockerManifestSchema2.
  2. Create a new image index from empty image index base [2] that has OCIImageIndex.

When trying to copy it from internal registry to Quay container registry, it fails with an error that it's not supported.

[1] https://github.com/google/go-containerregistry/blob/main/pkg/v1/empty/image.go#L32
[2] https://github.com/google/go-containerregistry/blob/main/pkg/v1/empty/index.go#L32

@sudo-bmitch
Copy link
Contributor

At this point, I'm not sure there's anything for OCI to do here. I don't think it would be correct for OCI to mandate support for non-OCI media types. I know there are other registries that only support OCI media types.

I think it would be good, but not required, for Quay to be more permissive in the entries supported in the OCI Index.

For end users, I think it would be good to use the OCI media type for all content, but understand that has challenges (particularly when some content comes from other sources). The other option is to use a different registry since I suspect most will support this scenario.

Looking back at the original question:

It also says that when encountering a mime type that is unknown to the implementation, that an error MUST NOT be generated.
I'm wondering what exactly does the last sentence mean.

I believe this was originally written from the perspective of content consumers, e.g. container runtimes, that are looking through an OCI Index for content to execute. If there are entries created with versions of the spec, or by projects adding custom content, the runtime should ignore any unrecognized content and only leverage the media types it does recognize.

For this issue, my personal recommendation is to move it to a feature request on the Quay project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants