-
Notifications
You must be signed in to change notification settings - Fork 206
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
libimage: add support for ForceCompressionFormat
for image copier
and manifest
#1602
libimage: add support for ForceCompressionFormat
for image copier
and manifest
#1602
Conversation
Signed-off-by: Aditya R <[email protected]>
d94715a
to
170f138
Compare
libimage/copier.go
Outdated
@@ -49,6 +49,10 @@ type CopyOptions struct { | |||
CompressionFormat *compression.Algorithm | |||
// CompressionLevel specifies what compression level is used | |||
CompressionLevel *int | |||
// ForceCompressionFormat ensures that the compression algorithm set in | |||
// DestinationCtx.CompressionFormat is used exclusively, and blobs of other |
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 don't think it's clear what DestinationCtx.CompressionFormat
is in libimage
.
I think it's important to highlight why setting CompressionFormat
may not suffice.
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.
It should be CompressionFormat
I have amended this.
|
||
pushOptions := &PushOptions{} | ||
pushOptions.CompressionFormat = &compression.Gzip | ||
pushOptions.ForceCompressionFormat = true |
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.
How could we verify that layers are getting compressed correctly? Should we load/pull the archive and inspect?
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.
Easier and actual integration test would be against a registry, where we can pre-upload a gzip and while pushing again with ForceCompressionFormat
we can check push logs that no reuse
candidates are there, it can be easily verified by inspecting push logs
. Its easier to add this test on Podman/Buildah
side.
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.
could we push to a local "oci:" directory and inspect the tarball there?
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.
let me check that, I'll amend test if that works.
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 don't think the problem which ForceCompressionFormat
is solving persists with other transports which works locally, c/image
force pushes blobs for oci:
and dir:
transports when same destination is used even ending up creating invalid OCI images. ( I have added a test and it passes even when ForceCompressionFormat = false
, I see similar behavior when directly working with buildah )
I am only able to reproduce the problem which ForceCompressionFormat
solves with registry as transport where candidates are actually re-evaluated if they can reused before actually Copying
content. @mtrmac could you confirm this because afaics local transports and not attempting to re-use dest blobs as registry://
is doing.
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.
dir:
can’t be used to test reuse because every write to dir:
deletes the previous contents.
Local transports are also trying to reuse blobs, but they don’t look for candidates in the blob info cache.
In effect, that means that reuse happens between compressed and uncompressed versions, only if the digest from the source matches an existing blob on the destination. In particular, copying an image from an uncompressed source (most commonly c/storage) to a destination uncompressed, and then copying the same image from the same uncompressed source with compression enabled triggers a reuse.
Demo:
# Create an uncompressed source
$ skopeo copy --override-os linux --dest-decompress docker://quay.io/libpod/alpine dir:uncompressed0
# Normal behavior of copies to OCI: compress
$ skopeo copy --override-os linux dir:uncompressed0 oci:direct
$ ls -la direct/blobs/sha256
… 2765584 … d8761bb9b4751d85618813b8f32d545dfb8dabc79ec8c2a59429851e8e5ee6f5
# Copy uncompressed first
$ skopeo copy --override-os linux --dest-oci-accept-uncompressed-layers dir:uncompressed0 oci:reuse
$ ls -la reuse/blobs/sha256
… 5589504 … 5e0d8111135538b8a86ce5fc969849efce16c455fd016bb3dc53131bcedc4da5
# … And then a compressed copy triggers reuse:
$ skopeo copy --override-os linux dir:uncompressed0 oci:reuse
…
Copying blob 5e0d81111355 skipped: already exists
…
# With a compressed layer not added
$ ls -la reuse/blobs/sha256
… 5589504 … 5e0d8111135538b8a86ce5fc969849efce16c455fd016bb3dc53131bcedc4da5
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.
@mtrmac Thanks :) this worked for me in the test.
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 looks plausible at a very quick glance, I didn’t read the test now.
(An alternative would be to add an ExclusiveCompressionFormat
option, which would set the algorithm + the flag in one, but that’s not orthogonal, e.g. we would need to also support setting compression level. To an extent this seems to what we anticipate the CLI design to be … and I think --force-compression-format
or something like that is reasonable, and IIRC there’s precedent for an option with some similar name in Docker.)
|
6cf031c
to
a045159
Compare
Found the original reference: containers/buildah#4613 (comment) . |
… which is not using the |
a045159
to
58ce959
Compare
Implement containers/image#2068 for libimage/copier. Signed-off-by: Aditya R <[email protected]>
Implement containers/image#2068 for libimage/manifest.Push Signed-off-by: Aditya R <[email protected]>
58ce959
to
248cc73
Compare
@vrothberg @giuseppe @mtrmac PTAL |
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.
LGTM
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.
/lgtm
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: flouthoc, giuseppe, vrothberg The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
// Push newly pulled alpine to directory with uncompressed blobs | ||
pushOptions := &PushOptions{} | ||
pushOptions.SystemContext = &types.SystemContext{} | ||
pushOptions.SystemContext.DirForceDecompress = true | ||
pushOptions.Writer = os.Stdout | ||
dirDest := t.TempDir() | ||
_, err = runtime.Push(ctx, "docker.io/library/alpine:latest", "dir:"+dirDest, pushOptions) | ||
require.NoError(t, err) | ||
|
||
// Pull uncompressed alpine from `dir:dirDest` as source. | ||
pullOptions = &PullOptions{} | ||
pullOptions.Writer = os.Stdout | ||
pullOptions.Architecture = "arm64" | ||
pulledImages, err = runtime.Pull(ctx, "dir:"+dirDest, config.PullPolicyAlways, pullOptions) | ||
require.NoError(t, err) | ||
require.Len(t, pulledImages, 1) |
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.
FWIW I didn’t test this now but I don’t think the dir:
step is necessary if the test is structured primarily around c/storage.
c/storage itself is a source of always-uncompressed data.
(This works well enough as is, no need to go back and spend time changing it.)
v5.26.1-0.20230807184415-3fb422379cfa
ForceCompressionFormat allows end users to force selected compression format (set in DestinationCtx.CompressionFormat) which ensures that while copying blobs of other compression algorithms are not reused.
See: containers/image#2068 for more details.