Improve support for manifest lists and image indexes#400
Improve support for manifest lists and image indexes#400rhatdan merged 1 commit intocontainers:masterfrom
Conversation
|
(There's a |
dde2ae2 to
e6a48b4
Compare
mtrmac
left a comment
There was a problem hiding this comment.
WIP, reviewed only the easy docker:/atomic:/dir: transport updates so far.
mtrmac
left a comment
There was a problem hiding this comment.
Makes sense overall.
Highlights are the determination of instance digests in destinations, and how OCI is supposed to work.
e6a48b4 to
ef30284
Compare
| } | ||
| } | ||
| // ... but if we're forcing it, we prefer the forced value a bit more. | ||
| if forcedManifestListMIMEType != "" { |
There was a problem hiding this comment.
can you do the for loop from 251-255 as part of an else for this if statement?
|
The linter's complaining about stuttering with the |
| // we just need to screen out the ones that are actually layers to get the list of non-layers. | ||
| if err = s.commitDataBlobs(img.ID); err != nil { | ||
| if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil { | ||
| logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2) |
There was a problem hiding this comment.
On the fence here, but if you've an error deleting an incomplete image, should it just go to debug or should you wrap up err2 also and return with the return below?
There was a problem hiding this comment.
Ditto with the next few delete with a debug on error.
There was a problem hiding this comment.
copy.Image does that in a few (very few) cases, see if err := dest.Close(); err != nil {. All too often we do defer something.Close() and ignore the possible failure.
Either way it’s problematic. On one hand, yes, throwing away failure information may make diagnosing failures difficult. On the other, the copy.Image attempt to parenthesize the secondary failure has already confused at least one user, who focused on the secondary failure instead of the primary one.
| logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2) | ||
| } | ||
| logrus.Debugf("error saving manifest for image %q: %v", img.ID, err) | ||
| return err |
There was a problem hiding this comment.
The errors prior to this you wrapped with a little verbiage. This one and below you did a debug then straight error. I'd vote continuing on with the error wrap using the veribage from the debugs, but your call.
There was a problem hiding this comment.
Changed them as you described.
|
|
@nalind is this something you are still interested in or should we close this? |
The feature is definitely useful and eventually we would like to have it; this PR is about 90% there, so it seems more useful to keep it open and noticed once in a few months than to close it and have it forgotten forever. |
In order to support copying multi-arch containers and Flatpaks, we need to be able to copy manifest lists and OCI image indexes from registry to registry. Work is underway to add such support to skopeo (containers/image#400), but as a temporary workaround add 'bodhi-skopeo-lite', which implements the subset of 'skopeo copy' we need, but with manifest list/image index support. Use of this needs to be specifically configured.
In order to support copying multi-arch containers and Flatpaks, we need to be able to copy manifest lists and OCI image indexes from registry to registry. Work is underway to add such support to skopeo (containers/image#400), but as a temporary workaround add 'bodhi-skopeo-lite', which implements the subset of 'skopeo copy' we need, but with manifest list/image index support. Use of this needs to be specifically configured. Signed-off-by: Owen W. Taylor <otaylor@fishsoup.net>
In order to support copying multi-arch containers and Flatpaks, we need to be able to copy manifest lists and OCI image indexes from registry to registry. Work is underway to add such support to skopeo (containers/image#400), but as a temporary workaround add 'bodhi-skopeo-lite', which implements the subset of 'skopeo copy' we need, but with manifest list/image index support. Use of this needs to be specifically configured. Signed-off-by: Owen W. Taylor <otaylor@fishsoup.net>
In order to support copying multi-arch containers and Flatpaks, we need to be able to copy manifest lists and OCI image indexes from registry to registry. Work is underway to add such support to skopeo (containers/image#400), but as a temporary workaround add 'bodhi-skopeo-lite', which implements the subset of 'skopeo copy' we need, but with manifest list/image index support. Use of this needs to be specifically configured. Signed-off-by: Owen W. Taylor <otaylor@fishsoup.net>
In order to support copying multi-arch containers and Flatpaks, we need to be able to copy manifest lists and OCI image indexes from registry to registry. Work is underway to add such support to skopeo (containers/image#400), but as a temporary workaround add 'bodhi-skopeo-lite', which implements the subset of 'skopeo copy' we need, but with manifest list/image index support. Use of this needs to be specifically configured. Signed-off-by: Owen W. Taylor <otaylor@fishsoup.net>
In order to support copying multi-arch containers and Flatpaks, we need to be able to copy manifest lists and OCI image indexes from registry to registry. Work is underway to add such support to skopeo (containers/image#400), but as a temporary workaround add 'bodhi-skopeo-lite', which implements the subset of 'skopeo copy' we need, but with manifest list/image index support. Use of this needs to be specifically configured. Signed-off-by: Owen W. Taylor <otaylor@fishsoup.net>
|
I would also really like OCI and manifest list support in Skopeo for https://github.com/fedora-infra/bodhi |
|
Rebased. |
f5eaa59 to
8f8d9c4
Compare
|
Rebased. |
8f8d9c4 to
f956c29
Compare
|
Tweaked the description for |
f956c29 to
9f81195
Compare
|
@vrothberg ptal |
vrothberg
left a comment
There was a problem hiding this comment.
First review. It's looking really good so far. I plan to get my hands dirty a bit and play with the code.
9f81195 to
0c63aa8
Compare
|
Updated. |
| // Copy each image, or just the ones we want to copy, in turn. | ||
| instanceDigests := list.Instances() | ||
| updates := make([]manifest.ListUpdate, len(instanceDigests)) | ||
| for i, instanceDigest := range instanceDigests { |
There was a problem hiding this comment.
This is still valid but I am cool to defer beautifying the copy reports to a future PR.
vrothberg
left a comment
There was a problem hiding this comment.
Just very minor nits. After that LGTM.
0c63aa8 to
d4632a5
Compare
Add the manifest.List interface, and implementations for OCIv1 Index and Docker Schema2List documents. Add an instanceDigest parameter to PutManifest(), PutSignatures(), and LayerInfosForCopy, for symmetry with GetManifest() and GetSignatures(). Return an error if the instanceDigest is supplied to destinations which don't support them, and add stubs that do so even to the transports which would support it, so that we don't break compilation here. Add a MultipleImages flag to copy.Options, and if the source for a copy operation contains multiple images, copy all of the images if we can. If we can't copy them all, but we were told to, return an error. Use the generic manifest list API to select a single image to copy from a list, so that we aren't just limited to the Docker manifest list format for those cases. When guessing at the type of a manifest, if the manifest contains a list of manifests, use its declared MIME type if it included one, else assume it's an OCI index, because an OCI index doesn't include its MIME type. When copying, switch from using an encode-then-compare of the original and updated versions of the list to checking if the instance list was changed (one of the things we might have changed) or if its type has changed due to conversion (the other change we might have made). If neither has changed, then we don't need to change the encoded value of the manifest. When copying, when checking for a digest mismatch in a target image reference, ignore a mismatch between the digest in the reference and the digest of the main manifest if we're copying one element from a list, and the digest in the reference matches the digest of the manifest list. When copying, if conversion of manifests for single images is being forced, convert manifest lists to the corresponding list types. When copying, supply the unparsed top level to Commit() by attaching the value to the context.Context. Support manifest lists in the directory transport by using the instance digest as a prefix of the filename used to store a manifest or a piece of signature data. Support manifest lists in the oci-layout transport by accepting indexes as we do images, and stop guessing about Platform values to add to the top-level index. Support storing manifest lists to registries in the docker: transport by using the manifest digest when we're writing one image as part of pushing a list of them, and by using the instance digest when reading or writing signature data, when one is specified, or the cached digest of the non-instanced digest when one is not specified. Add partial support for manifest lists to the storage transport: when committing one image from a list into storage, also add a copy of the manifest list by extracting it from the context.Context. The logic is already in place to enable locating an image using any of multiple manifest digests. When writing an image that has an instanceDigest value (meaning it's a secondary image), don't try to generate a canonical reference to add to the image's list of names if the reference for the primary image doesn't contain a name. That should only happen if we're writing using just an image ID, which is unlikely, but we still need to handle it. Avoid computing the digest of the manifest, or retrieving the either-a-tag-or-a-digest value from the target reference, if we're given an instanceDigest, which would override them anyway. Move the check for non-nil instanceDigest values up into the main PutSignatures() method instead of duplicating it in the per-strategy helpers. Add mention of the instanceDigest parameter and its use to various PutManifest, PutSignatures, and LayerInfosForCopy implementations and their declarations in interfaces. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
d4632a5 to
1836b4d
Compare
1836b4d to
ca5fe04
Compare
|
Dropped the patch that redirected to containers/skopeo#741 for testing, so I expect the |
|
LGTM |
|
Thank you all for writing and reviewing this feature. 🍰 |
This patch series adds a
ManifestListinterface, implemented bySchema2ListandOCI1Indextypes, to themanifestpackage.It then adds an
instanceDigestparameter to theImageSource.LayerInfosForCopy(),ImageDestination.PutManifest(), andImageDestination.PutSignatures()methods, so that we can store multiple manifests to transports that can support them, and read them from sources which need to update the layer digest list.It uses those parameters and updates
copy.Image()to accept aMultipleImagesboolean option which directs it to copy all instances if the source reference produces anImageSourcethat represents multiple images.It then finishes updating the
containers-storage,directory,docker, andocitransports to be able to read and write multiple images at a time.