-
Notifications
You must be signed in to change notification settings - Fork 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
Add OCI support to manifest subcommand #3990
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
"variant": "v7" | ||
} | ||
}, | ||
"Raw": "ewogICAic2NoZW1hVmVyc2lvbiI6IDIsCiAgICJtZWRpYVR5cGUiOiAiYXBwbGljYXRpb24vdm5kLmRvY2tlci5kaXN0cmlidXRpb24ubWFuaWZlc3QudjIranNvbiIsCiAgICJjb25maWciOiB7CiAgICAgICJtZWRpYVR5cGUiOiAiYXBwbGljYXRpb24vdm5kLmRvY2tlci5jb250YWluZXIuaW1hZ2UudjEranNvbiIsCiAgICAgICJzaXplIjogMTUyMCwKICAgICAgImRpZ2VzdCI6ICJzaGEyNTY6NzMyOGY2ZjhiNDE4OTA1OTc1NzVjYmFhZGM4ODRlNzM4NmFlMGFjYzUzYjc0NzQwMWViY2U1Y2YwZDYyNDU2MCIKICAgfSwKICAgImxheWVycyI6IFsKICAgICAgewogICAgICAgICAibWVkaWFUeXBlIjogImFwcGxpY2F0aW9uL3ZuZC5kb2NrZXIuaW1hZ2Uucm9vdGZzLmRpZmYudGFyLmd6aXAiLAogICAgICAgICAic2l6ZSI6IDE5OTA0MDIsCiAgICAgICAgICJkaWdlc3QiOiAic2hhMjU2Ojg4Mjg2ZjQxNTMwZTkzZGZmZDRiOTY0ZTFkYjIyY2U0OTM5ZmZmYTRhNGM2NjVkYWI4NTkxZmJhYjAzZDQ5MjYiCiAgICAgIH0KICAgXQp9", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Silly question; would JSON-in-JSON (raw data, but as string) work? I realise this data is not primarily intended for users to read, but having something to hold-onto when looking at it could still be useful (instead of having to decode) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, so we still have the content from the registry in the file as a sub-object, since deprecating that would probably be way more work 😢 As long as we have that, and No super strong preferences here, though I admit I'm not a fan of JSON-in-JSON 👀 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still some discussion happening on base64 vs JSON-in-JSON 😅 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After @neersighted describing a preference for base64 here, I'm convinced -- the data is still available, and the Go struct should mostly match anyways for users. Additionally, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. base64 is great 👍 |
||
"SchemaV2Manifest": { | ||
"schemaVersion": 2, | ||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ import ( | |
|
||
"github.com/docker/distribution" | ||
"github.com/docker/distribution/manifest/manifestlist" | ||
"github.com/docker/distribution/manifest/ocischema" | ||
"github.com/docker/distribution/manifest/schema2" | ||
"github.com/docker/distribution/reference" | ||
"github.com/opencontainers/go-digest" | ||
|
@@ -16,10 +17,12 @@ import ( | |
type ImageManifest struct { | ||
Ref *SerializableNamed | ||
Descriptor ocispec.Descriptor | ||
Raw []byte `json:",omitempty"` | ||
|
||
// SchemaV2Manifest is used for inspection | ||
// TODO: Deprecate this and store manifest blobs | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
SchemaV2Manifest *schema2.DeserializedManifest `json:",omitempty"` | ||
// OCIManifest is used for inspection | ||
OCIManifest *ocischema.DeserializedManifest `json:",omitempty"` | ||
} | ||
|
||
// OCIPlatform creates an OCI platform from a manifest list platform spec | ||
|
@@ -53,8 +56,15 @@ func PlatformSpecFromOCI(p *ocispec.Platform) *manifestlist.PlatformSpec { | |
// Blobs returns the digests for all the blobs referenced by this manifest | ||
func (i ImageManifest) Blobs() []digest.Digest { | ||
digests := []digest.Digest{} | ||
for _, descriptor := range i.SchemaV2Manifest.References() { | ||
digests = append(digests, descriptor.Digest) | ||
switch { | ||
case i.SchemaV2Manifest != nil: | ||
for _, descriptor := range i.SchemaV2Manifest.References() { | ||
digests = append(digests, descriptor.Digest) | ||
} | ||
case i.OCIManifest != nil: | ||
for _, descriptor := range i.OCIManifest.References() { | ||
digests = append(digests, descriptor.Digest) | ||
} | ||
} | ||
return digests | ||
} | ||
|
@@ -65,6 +75,8 @@ func (i ImageManifest) Payload() (string, []byte, error) { | |
switch { | ||
case i.SchemaV2Manifest != nil: | ||
return i.SchemaV2Manifest.Payload() | ||
case i.OCIManifest != nil: | ||
return i.OCIManifest.Payload() | ||
default: | ||
return "", nil, errors.Errorf("%s has no payload", i.Ref) | ||
} | ||
|
@@ -76,6 +88,8 @@ func (i ImageManifest) References() []distribution.Descriptor { | |
switch { | ||
case i.SchemaV2Manifest != nil: | ||
return i.SchemaV2Manifest.References() | ||
case i.OCIManifest != nil: | ||
return i.OCIManifest.References() | ||
default: | ||
return nil | ||
} | ||
|
@@ -84,13 +98,35 @@ func (i ImageManifest) References() []distribution.Descriptor { | |
// NewImageManifest returns a new ImageManifest object. The values for Platform | ||
// are initialized from those in the image | ||
func NewImageManifest(ref reference.Named, desc ocispec.Descriptor, manifest *schema2.DeserializedManifest) ImageManifest { | ||
raw, err := manifest.MarshalJSON() | ||
if err != nil { | ||
raw = nil | ||
} | ||
|
||
return ImageManifest{ | ||
Ref: &SerializableNamed{Named: ref}, | ||
Descriptor: desc, | ||
Raw: raw, | ||
SchemaV2Manifest: manifest, | ||
} | ||
} | ||
|
||
// NewOCIImageManifest returns a new ImageManifest object. The values for | ||
// Platform are initialized from those in the image | ||
func NewOCIImageManifest(ref reference.Named, desc ocispec.Descriptor, manifest *ocischema.DeserializedManifest) ImageManifest { | ||
raw, err := manifest.MarshalJSON() | ||
if err != nil { | ||
raw = nil | ||
} | ||
|
||
return ImageManifest{ | ||
Ref: &SerializableNamed{Named: ref}, | ||
Descriptor: desc, | ||
Raw: raw, | ||
OCIManifest: manifest, | ||
} | ||
} | ||
|
||
// SerializableNamed is a reference.Named that can be serialized and deserialized | ||
// from JSON | ||
type SerializableNamed struct { | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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 just occurred to me; as this is "net new"; should we error in this case (no raw data present) instead of re-constructing the manifest data?
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 I prefer the symmetry with the manifest v2 -- or at the very least, if we reconstruct for one and not the other, we should make it more obvious why that happens in the code.
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.
Agreed, I think the symmetry makes sense.
I'm curious though - here I've used 2-spaces as "the default". In hindsight, 3 spaces might make more sense? BuildKit did used to produce 3-space OCI images, so maybe it makes more sense to use the same 3 spaces as for schema2?
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 guess there's no "good" answer for that one. Quick thoughts;
~/.docker/manifests/..
JSON files would not have OCI manifests, and new files will have theRaw
field propagatedRaw
field propagated;Raw
data (based on the struct), using the "old" formatting (3 spaces).Raw
)I guess it's fine to leave those for a follow-up.