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
Support zstd compression in image commit #5452
base: main
Are you sure you want to change the base?
Conversation
Without this change, specifying `Compression: imagebuildah.Zstd` in `imagebuildah`'s `BuildOptions fails, so it is not possible to push cache to a registry with zstd compression. https://github.com/opencontainers/image-spec/blob/main/media-types.md defines a media type for zstd-compressed layers, so I don't think the comment about lack of a defined media type is still applicable. Signed-off-by: Aaron Lehmann <alehmann@netflix.com>
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: aaronlehmann The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
If a test is required for this change, I'd appreciate suggestions about how to best add test coverage. It doesn't seem possible to test via the CLI because the if c.Flag("compress").Changed {
logrus.Debugf("--compress option specified but is ignored")
}
compression := define.Gzip
if iopts.DisableCompression {
compression = define.Uncompressed
} |
@flouthoc PTAL |
// how to decompress them, we can't try to compress layers with zstd. | ||
return "", "", errors.New("media type for zstd-compressed layers is not defined") | ||
omediaType = v1.MediaTypeImageLayerZstd | ||
dmediaType = "application/vnd.docker.image.rootfs.diff.tar.zstd" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drive-by comment: I'm uncomfortable with hardcoded magic strings. Shouldn't this be defined as a constant in c/image?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if this should happen, it would be in c/image/v5/manifest
.
(Buildkit does seem to use this constant, but it is not a part of the public API.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We must refuse to create v2s2 images with zstd compression.
AFAICS that means that the whole of NewImageSource
needs to be restructured around respecting i.preferredManifestType
, instead of always building data in both formats.
There may be various ways to do it:
- Add some kind of “manifest type” abstraction, and call it everywhere the code currently computes both values
- Continue building both formats all the time, but somehow represent “this format failed”, and check that at the very end (might be less invasive, but also rather more convoluted)
- Maybe some other design.
@@ -155,9 +155,9 @@ func computeLayerMIMEType(what string, layerCompression archive.Compression) (om | |||
// how to decompress them, we can't try to compress layers with xz. | |||
return "", "", errors.New("media type for xz-compressed layers is not defined") | |||
case archive.Zstd: | |||
// Until the image specs define a media type for zstd-compressed layers, even if we know | |||
// how to decompress them, we can't try to compress layers with zstd. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is accurate: Docker images can’t represent Zstd images layers.
We can’t very well just silently ignore that problem and create something that doesn’t work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to defer to you and refuse to create schema2 images with zstd compression. But I'm curious to understand why this is a problem - BuildKit seems happy to create them using this media type, and they seem to work fine with Docker and kaniko (but not buildah...).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One place is our own https://github.com/containers/image/blob/1c648b405e0763472db0bcc189136ddb6a5b61c6/manifest/docker_schema2.go#L173 . In retrospect, being that strict might have been a mistake, but either way that code refusing unexpected MIME types has been there for many years.
(IIRC, Docker is not checking MIME types at all when pulling; that’s the other extreme option.)
So we would need to think about a migration mechanism, and giving users enough tools to manage it. For a format feature which is, AFAICS, undocumented. Meanwhile, “if you want to use Zstd, migrate to OCI” is a simple story that works. for all implementations.
To keep the change relatively contained, what would you think about returning an empty // Figure out if we need to change the media type, in case we've changed the compression.
omediaType, dmediaType, err = computeLayerMIMEType(what, i.compression)
if err != nil {
return nil, err
}
// The layer media type must be defined for the type of manifest we are producing.
if (omediaType == "" && manifestType == v1.MediaTypeImageManifest) ||
(dmediaType == "" && manifestType == manifest.DockerV2Schema2MediaType) {
return nil, fmt.Errorf("manifest type %q does not support selected compression format", manifestType)
} Refactoring with a manifest type abstraction seems like a worthy idea as well. I can't see a reason why this function is constructing both in parallel (not sure if I'm missing something). I'm not sure I'm the best person to do this refactor though, as I'm brand new to the codebase. |
I’ll let actual Buildah maintainers to decide how this should be organized. |
@rhatdan: How would you like to proceed here? |
Hoping for some direction on where to go with this PR. I'm happy to make the changes if the maintainers have thoughts on what makes most sense. |
My preference would be
but that’s the option that requires more work, and I’m not authoritative to commit Buildah to that direction, nor can I spend very much time helping with that work. |
@rhatdan: Still looking for guidance on this one... |
What type of PR is this?
/kind feature
What this PR does / why we need it:
Without this change, specifying
Compression: imagebuildah.Zstd
inimagebuildah
's `BuildOptions fails, so it is not possible to push cache to a registry with zstd compression.https://github.com/opencontainers/image-spec/blob/main/media-types.md defines a media type for zstd-compressed layers, so I don't think the comment about lack of a defined media type is still applicable.
How to verify it
Specify
Compression: imagebuildah.Zstd
when building an image usingimagebuildah.BuildDockerfiles
,.Which issue(s) this PR fixes:
None
Special notes for your reviewer:
n/a
Does this PR introduce a user-facing change?