-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
image export: Use correct media type when creating new layer blobs. #1541
Conversation
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.
As we discussed in slack this should also use conversion between equivalent docker and oci layer types when manifest is created so the manifest always contains the correct information. Did you plan that as a separate PR? Tbh when we have that fix I don't think it would be very bad if differ always created oci types. The information about the mediatype that was used when blob was first created is kind of meaningless apart from the compression.
The fix in GetMediaTypeForLayers
LGTM
@@ -102,21 +102,30 @@ func detectCompressionType(cr io.Reader) (CompressionType, error) { | |||
|
|||
// GetMediaTypeForLayers retrieves media type for layer from ref information. | |||
func GetMediaTypeForLayers(diffPairs []DiffPair, ref cache.ImmutableRef) []string { |
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.
Add a comment that on error, slice with full length and partial data would be returned. This confused me in the beginning.
Ah okay, I think I slightly misunderstood originally. I thought I had addressed this already by including these lines but now that you mention it those lines won't handle the case where there is already a blob associated with a layer but the media type stored in cache metadata is different from what the exporter wants. I'll update to do the mediatype conversion on a higher level in the exporter rather than |
You can add a public helper function that takes an array of descriptors and makes sure they are either docker or oci. Then if someone calls |
ContainerdAddress() string | ||
}); !ok { | ||
cdAddress := sb.ContainerdAddress() | ||
if cdAddress == "" { | ||
return |
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 you mind to add some log for skip check? It will be nice to debug!
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.
Yeah good call, updated with that
There is a bug in the way images are pushed that results in oci types being used for layers even when docker types should be used, but only in single-layer images. Signed-off-by: Erik Sipsma <erik@sipsma.dev>
Makes sense, but when I went to actually make the updates for this PR I remembered that as it currently stands the exporter uses a slice of diffpairs and slice of mediatype strings rather than a slice of descriptors, so for now I updated this PR to have a public helper func |
cache/blobs/compression.go
Outdated
converted = toDockerLayerType[mediaType] | ||
} | ||
if converted == "" { | ||
return "", fmt.Errorf("unhandled layer media type %q", mediaType) |
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 think ignoring error (and maybe printing the warning would be more appropriate). Especially because the conversion doesn't currently handle the alternative compressions (zstd etc).
tref = tref.Parent() | ||
parent := tref.Parent() | ||
tref.Release(context.TODO()) | ||
tref = parent | ||
} |
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.
in an odd case where parent chain length does not match the length of diffPairs
(shouldn't happen) we should make sure we don't leave the tref
referenced after returning.
Updated from all the comments, think travis just needs a retry due to |
exporter/containerimage/writer.go
Outdated
@@ -141,7 +141,7 @@ func (ic *ImageWriter) Commit(ctx context.Context, inp exporter.Source, oci bool | |||
return &idxDesc, nil | |||
} | |||
|
|||
func (ic *ImageWriter) exportLayers(ctx context.Context, compression blobs.CompressionType, refs ...cache.ImmutableRef) ([][]blobs.DiffPair, error) { | |||
func (ic *ImageWriter) exportLayers(ctx context.Context, compression blobs.CompressionType, oci bool, refs ...cache.ImmutableRef) ([][]blobs.DiffPair, error) { |
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.
oci bool
unused in here now
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.
oh duh... fixed
There are a few bugs in the image export related code being fixed here. GetMediaTypeForLayers was iterating over diffPairs in the wrong order, resulting in it always returning nil for images with more than one layer. This actually worked most of the time because it accidentally triggered a separate codepath meant to handle v0.6 migrations where mediatypes left empty get filled in. However, fixing that bug revealed another existing bug where the "oci" parameter in the image exporter was not being honored except when the v0.6 codepath got followed, resulting in images to always have oci layer media types even when docker types are used for the rest of the image descriptors. Due to the interaction between these various bugs, the only practical end effect previously was that single-layer images could use the wrong layer media type. An existing test has been expanded to cover that case in a previous commit. Signed-off-by: Erik Sipsma <erik@sipsma.dev>
Signed-off-by: Erik Sipsma <erik@sipsma.dev>
There are a few bugs in the image export related code being fixed here. GetMediaTypeForLayers was iterating over diffPairs in the wrong order, resulting in it always returning nil for images with more than one layer. This actually worked most of the time because it accidentally triggered a separate codepath meant to handle v0.6 migrations where mediatypes left empty get filled in. However, fixing that bug revealed another existing bug where the "oci" parameter in the image exporter was never passed to GetDiffPairs, resulting in newly created images to always have oci layer media types even when docker types are used for the rest of the image descriptors (manifests, config, etc.).
Due to the interaction between these various bugs, the only practical end effect previously was that single-layer images could incorrectly use oci layer media types when docker types were supposed to be used. An existing test has been expanded to cover that case in a previous commit.
Signed-off-by: Erik Sipsma erik@sipsma.dev
Note: This PR currently also includes the commits from #1538 so that tests can run in full. I'll rebase once #1538 is merged.