Fix several conversions of "ocispec.Image" to "ocispec.Platform"#7376
Fix several conversions of "ocispec.Image" to "ocispec.Platform"#7376samuelkarp merged 1 commit intocontainerd:mainfrom
Conversation
|
Can we have an unit test? |
|
I'm honestly not exactly sure where I would put unit tests for these changes -- they're all reading blobs from the content store, and each one is pretty deeply nested in other functionality. 😬 With a bit more guidance, I'd be willing to try, though! Any suggestions on a good place to start? |
pkg/unpack/unpacker.go
Outdated
| imgPlatform := platforms.Normalize(ocispec.Platform{ | ||
| OS: i.OS, | ||
| Architecture: i.Architecture, | ||
| Variant: i.Variant, | ||
|
|
||
| OSVersion: i.OSVersion, | ||
| OSFeatures: i.OSFeatures, | ||
| }) |
There was a problem hiding this comment.
We should consider updating the ocispec.Image to embed the ocispec.Platform 🤔 ;
// Image is the JSON structure which describes some basic information about the image.
// This provides the `application/vnd.oci.image.config.v1+json` mediatype when marshalled to JSON.
type Image struct {
// Created is the combined date and time at which the image was created, formatted as defined by RFC 3339, section 5.6.
Created *time.Time `json:"created,omitempty"`
// Author defines the name and/or email address of the person or entity which created and is responsible for maintaining the image.
Author string `json:"author,omitempty"`
Platform
// Config defines the execution parameters which should be used as a base when running a container using the image.
Config ImageConfig `json:"config,omitempty"`
// RootFS references the layer content addresses used by the image.
RootFS RootFS `json:"rootfs"`
// History describes the history of each layer.
History []History `json:"history,omitempty"`
}Then all this copying wouldn't be needed, and we could just do
| imgPlatform := platforms.Normalize(ocispec.Platform{ | |
| OS: i.OS, | |
| Architecture: i.Architecture, | |
| Variant: i.Variant, | |
| OSVersion: i.OSVersion, | |
| OSFeatures: i.OSFeatures, | |
| }) | |
| imgPlatform := platforms.Normalize(i.Platform) |
There was a problem hiding this comment.
Violent agreement! 😅
There's probably a pretty decent argument to be made for the OCI's
Imagetype to embedPlatformdirectly (which would make this more straightforward) and/or to offer a helper function that appropriately extracts aPlatformobject from anImageobject, but I didn't want the perfect to be the enemy of the good, and this seemed like a good place to start.
👀 ❤️ 😄
There was a problem hiding this comment.
It would also be technically correct in that case to swap back to using Image in all these cases, but it feels like a huge amount of overkill to process the entire Image object, extract all the data, and then throw away all but at most five fields of it 😅
There was a problem hiding this comment.
Oh! Missed your last comments; I was updating my fork of the image-spec; opencontainers/image-spec#949
😂
I agree that just marshaling/unmarshaling the platform makes a lot of sense; but indeed more "correct" if it's actually embedded, which ties them together to be the same thing.
There was a problem hiding this comment.
Given opencontainers/image-spec#949 is merged (which further legitimizes this PR's implementation), is this ready for re-review or do we want to do #7382 first and rebase this on top of that? 🙇
pkg/unpack/unpacker.go
Outdated
| var unpack *Platform | ||
|
|
||
| imgPlatform := platforms.Normalize(ocispec.Platform{OS: i.OS, Architecture: i.Architecture}) | ||
| imgPlatform := platforms.Normalize(ocispec.Platform{ |
There was a problem hiding this comment.
This can just be i.Platform now, I think?
There was a problem hiding this comment.
Yeah, that's #7382 😅
I guess I could import that change and take over from @thaJeztah if you'd like me to? (he seems busy enough that I bet he wouldn't mind 😂)
|
Rebased and rolled in #7382 (with an update to the merged version of opencontainers/image-spec#949 and to use |
|
(rebased and resolved conflicts) |
|
The project checks want |
|
Line 460 in f7f2be7 |
|
/retest |
1 similar comment
|
/retest |
Several bits of code unmarshal image config JSON into an `ocispec.Image`, and then immediately create an `ocispec.Platform` out of it, but then discard the original image *and* miss several potential platform fields (most notably, `variant`). Because `ocispec.Platform` is a strict subset of `ocispec.Image`, most of these can be updated to simply unmarshal the image config directly to `ocispec.Platform` instead, which allows these additional fields to be picked up appropriately. We can use `tianon/raspbian` as a concrete reproducer to demonstrate. Before: ```console $ ctr content fetch docker.io/tianon/raspbian:bullseye-slim ... $ ctr image ls REF TYPE DIGEST SIZE PLATFORMS LABELS docker.io/tianon/raspbian:bullseye-slim application/vnd.docker.distribution.manifest.v2+json sha256:66e96f8af40691b335acc54e5f69711584ef7f926597b339e7d12ab90cc394ce 28.6 MiB linux/arm/v7 - ``` (Note that the `PLATFORMS` column lists `linux/arm/v7` -- the image itself is actually `linux/arm/v6`, but one of these bits of code leads to only `linux/arm` being extracted from the image config, which `platforms.Normalize` then updates to an explicit `v7`.) After: ```console $ ctr image ls REF TYPE DIGEST SIZE PLATFORMS LABELS docker.io/tianon/raspbian:bullseye-slim application/vnd.docker.distribution.manifest.v2+json sha256:66e96f8af40691b335acc54e5f69711584ef7f926597b339e7d12ab90cc394ce 28.6 MiB linux/arm/v6 - ``` Signed-off-by: Tianon Gravi <admwiggin@gmail.com> Co-authored-by: Sebastiaan van Stijn <github@gone.nl>
|
Rebased and resolved discussion points 👍 |
Several bits of code unmarshal image config JSON into an
ocispec.Image, and then immediately create anocispec.Platformout of it, but then discard the original image and miss several potential platform fields (most notably,variant).Because
ocispec.Platformis a strict subset ofocispec.Image, most of these can be updated to simply unmarshal the image config directly toocispec.Platforminstead, which allows these additional fields to be picked up appropriately.We can use
tianon/raspbianas a concrete reproducer to demonstrate.Before:
(Note that the
PLATFORMScolumn listslinux/arm/v7-- the image itself is actuallylinux/arm/v6, but one of these bits of code leads to onlylinux/armbeing extracted from the image config, whichplatforms.Normalizethen updates to an explicitv7.)After:
(Tianon's back on his BS 😇 ❤️)
There's probably a pretty decent argument to be made for the OCI's
Imagetype to embedPlatformdirectly (which would make this more straightforward) and/or to offer a helper function that appropriately extracts aPlatformobject from anImageobject, but I didn't want the perfect to be the enemy of the good, and this seemed like a good place to start.