From 86cd830fb39c94ece91378eac42bfe6160ddb56a Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 29 Nov 2022 22:41:01 +0100 Subject: [PATCH 1/2] Descriptor: align field order with OCI image specification I am looking at aligning the types defined in this repository with the OCI image specification, and potentially exchanging local types with those from the specification. This patch is a stepping-stone towards that effort, but as this changes the format of the serialized JSON, I wanted to put this up first before proceeding with the other work in case there are concerns. Signed-off-by: Sebastiaan van Stijn --- blobs.go | 6 +++--- docs/notifications.md | 8 ++++---- docs/spec/manifest-v2-2.md | 20 ++++++++++---------- manifest/manifestlist/manifestlist_test.go | 10 +++++----- manifest/ocischema/manifest_test.go | 4 ++-- manifest/schema2/manifest_test.go | 8 ++++---- notifications/event_test.go | 6 +++--- 7 files changed, 31 insertions(+), 31 deletions(-) diff --git a/blobs.go b/blobs.go index d07299343..b7583cc7b 100644 --- a/blobs.go +++ b/blobs.go @@ -63,13 +63,13 @@ type Descriptor struct { // encoded as utf-8. MediaType string `json:"mediaType,omitempty"` - // Size in bytes of content. - Size int64 `json:"size,omitempty"` - // Digest uniquely identifies the content. A byte stream can be verified // against this digest. Digest digest.Digest `json:"digest,omitempty"` + // Size in bytes of content. + Size int64 `json:"size,omitempty"` + // URLs contains the source URLs of this content. URLs []string `json:"urls,omitempty"` diff --git a/docs/notifications.md b/docs/notifications.md index 443605054..69ac90d0e 100644 --- a/docs/notifications.md +++ b/docs/notifications.md @@ -93,8 +93,8 @@ manifest: "action": "pull", "target": { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "size": 708, "digest": "sha256:fea8895f450959fa676bcc1df0611ea93823a735a01205fd8622846041d0c7cf", + "size": 708, "length": 708, "repository": "hello-world", "url": "http://192.168.100.227:5000/v2/hello-world/manifests/sha256:fea8895f450959fa676bcc1df0611ea93823a735a01205fd8622846041d0c7cf", @@ -171,8 +171,8 @@ Content-Type: application/vnd.docker.distribution.events.v1+json "action": "push", "target": { "mediaType": "application/vnd.docker.distribution.manifest.v1+json", - "length": 1, "digest": "sha256:fea8895f450959fa676bcc1df0611ea93823a735a01205fd8622846041d0c7cf", + "length": 1, "repository": "library/test", "url": "https://example.com/v2/library/test/manifests/sha256:c3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5" }, @@ -196,8 +196,8 @@ Content-Type: application/vnd.docker.distribution.events.v1+json "action": "push", "target": { "mediaType": "application/vnd.docker.container.image.rootfs.diff+x-gtar", - "length": 2, "digest": "sha256:c3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5", + "length": 2, "repository": "library/test", "url": "https://example.com/v2/library/test/blobs/sha256:c3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5" }, @@ -221,8 +221,8 @@ Content-Type: application/vnd.docker.distribution.events.v1+json "action": "push", "target": { "mediaType": "application/vnd.docker.container.image.rootfs.diff+x-gtar", - "length": 3, "digest": "sha256:c3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5", + "length": 3, "repository": "library/test", "url": "https://example.com/v2/library/test/blobs/sha256:c3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5" }, diff --git a/docs/spec/manifest-v2-2.md b/docs/spec/manifest-v2-2.md index f8a4671ed..81f40a396 100644 --- a/docs/spec/manifest-v2-2.md +++ b/docs/spec/manifest-v2-2.md @@ -124,8 +124,8 @@ image manifest based on the Content-Type returned in the HTTP response. "manifests": [ { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "size": 7143, "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f", + "size": 7143, "platform": { "architecture": "ppc64le", "os": "linux" @@ -133,8 +133,8 @@ image manifest based on the Content-Type returned in the HTTP response. }, { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "size": 7682, "digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270", + "size": 7682, "platform": { "architecture": "amd64", "os": "linux", @@ -232,24 +232,24 @@ image. It's the direct replacement for the schema-1 manifest. "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "config": { "mediaType": "application/vnd.docker.container.image.v1+json", - "size": 7023, - "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 7023 }, "layers": [ { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 32654, - "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f" + "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f", + "size": 32654 }, { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 16724, - "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b" + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 }, { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 73109, - "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736" + "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736", + "size": 73109 } ] } diff --git a/manifest/manifestlist/manifestlist_test.go b/manifest/manifestlist/manifestlist_test.go index 9aacd54a7..a7b90c07b 100644 --- a/manifest/manifestlist/manifestlist_test.go +++ b/manifest/manifestlist/manifestlist_test.go @@ -18,8 +18,8 @@ const expectedManifestListSerialization = `{ "manifests": [ { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "size": 985, "digest": "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", + "size": 985, "platform": { "architecture": "amd64", "os": "linux", @@ -30,8 +30,8 @@ const expectedManifestListSerialization = `{ }, { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "size": 2392, "digest": "sha256:6346340964309634683409684360934680934608934608934608934068934608", + "size": 2392, "platform": { "architecture": "sun4m", "os": "sunos" @@ -142,8 +142,8 @@ const expectedOCIImageIndexSerialization = `{ "manifests": [ { "mediaType": "application/vnd.oci.image.manifest.v1+json", - "size": 985, "digest": "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", + "size": 985, "platform": { "architecture": "amd64", "os": "linux", @@ -154,8 +154,8 @@ const expectedOCIImageIndexSerialization = `{ }, { "mediaType": "application/vnd.oci.image.manifest.v1+json", - "size": 985, "digest": "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", + "size": 985, "annotations": { "platform": "none" }, @@ -166,8 +166,8 @@ const expectedOCIImageIndexSerialization = `{ }, { "mediaType": "application/vnd.oci.image.manifest.v1+json", - "size": 2392, "digest": "sha256:6346340964309634683409684360934680934608934608934608934068934608", + "size": 2392, "annotations": { "what": "for" }, diff --git a/manifest/ocischema/manifest_test.go b/manifest/ocischema/manifest_test.go index 528e303cc..6b7a7028a 100644 --- a/manifest/ocischema/manifest_test.go +++ b/manifest/ocischema/manifest_test.go @@ -18,8 +18,8 @@ const expectedManifestSerialization = `{ "mediaType": "application/vnd.oci.image.manifest.v1+json", "config": { "mediaType": "application/vnd.oci.image.config.v1+json", - "size": 985, "digest": "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", + "size": 985, "annotations": { "apple": "orange" } @@ -27,8 +27,8 @@ const expectedManifestSerialization = `{ "layers": [ { "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", - "size": 153263, "digest": "sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b", + "size": 153263, "annotations": { "lettuce": "wrap" } diff --git a/manifest/schema2/manifest_test.go b/manifest/schema2/manifest_test.go index da7f43fd8..463137448 100644 --- a/manifest/schema2/manifest_test.go +++ b/manifest/schema2/manifest_test.go @@ -15,14 +15,14 @@ const expectedManifestSerialization = `{ "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "config": { "mediaType": "application/vnd.docker.container.image.v1+json", - "size": 985, - "digest": "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b" + "digest": "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", + "size": 985 }, "layers": [ { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 153263, - "digest": "sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b" + "digest": "sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b", + "size": 153263 } ] }` diff --git a/notifications/event_test.go b/notifications/event_test.go index 44f64c6e7..7eea08f7a 100644 --- a/notifications/event_test.go +++ b/notifications/event_test.go @@ -22,8 +22,8 @@ func TestEventEnvelopeJSONFormat(t *testing.T) { "action": "push", "target": { "mediaType": "application/vnd.docker.distribution.manifest.v1+prettyjws", - "size": 1, "digest": "sha256:0123456789abcdef0", + "size": 1, "length": 1, "repository": "library/test", "url": "http://example.com/v2/library/test/manifests/latest" @@ -48,8 +48,8 @@ func TestEventEnvelopeJSONFormat(t *testing.T) { "action": "push", "target": { "mediaType": "application/vnd.docker.container.image.rootfs.diff+x-gtar", - "size": 2, "digest": "sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5", + "size": 2, "length": 2, "repository": "library/test", "url": "http://example.com/v2/library/test/manifests/latest" @@ -74,8 +74,8 @@ func TestEventEnvelopeJSONFormat(t *testing.T) { "action": "push", "target": { "mediaType": "application/vnd.docker.container.image.rootfs.diff+x-gtar", - "size": 3, "digest": "sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d6", + "size": 3, "length": 3, "repository": "library/test", "url": "http://example.com/v2/library/test/manifests/latest" From 19233195b752c67a5fbf4a32a50cea96b298c210 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 29 Nov 2022 22:59:06 +0100 Subject: [PATCH 2/2] Align code to match order of fields This is just cosmetic; alighn the fields with the order in which they appear in the struct (and JSON output). Signed-off-by: Sebastiaan van Stijn --- manifest/manifestlist/manifestlist_test.go | 10 +++++----- manifest/ocischema/builder_test.go | 6 +++--- manifest/ocischema/manifest_test.go | 4 ++-- manifest/schema1/config_builder_test.go | 2 +- manifest/schema1/manifest.go | 2 +- manifest/schema2/builder_test.go | 8 ++++---- manifest/schema2/manifest_test.go | 4 ++-- notifications/bridge.go | 4 ++-- notifications/event_test.go | 18 +++++++++--------- 9 files changed, 29 insertions(+), 29 deletions(-) diff --git a/manifest/manifestlist/manifestlist_test.go b/manifest/manifestlist/manifestlist_test.go index a7b90c07b..842ae310b 100644 --- a/manifest/manifestlist/manifestlist_test.go +++ b/manifest/manifestlist/manifestlist_test.go @@ -44,9 +44,9 @@ func makeTestManifestList(t *testing.T, mediaType string) ([]ManifestDescriptor, manifestDescriptors := []ManifestDescriptor{ { Descriptor: distribution.Descriptor{ + MediaType: "application/vnd.docker.distribution.manifest.v2+json", Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Size: 985, - MediaType: "application/vnd.docker.distribution.manifest.v2+json", }, Platform: PlatformSpec{ Architecture: "amd64", @@ -56,9 +56,9 @@ func makeTestManifestList(t *testing.T, mediaType string) ([]ManifestDescriptor, }, { Descriptor: distribution.Descriptor{ + MediaType: "application/vnd.docker.distribution.manifest.v2+json", Digest: "sha256:6346340964309634683409684360934680934608934608934608934068934608", Size: 2392, - MediaType: "application/vnd.docker.distribution.manifest.v2+json", }, Platform: PlatformSpec{ Architecture: "sun4m", @@ -183,9 +183,9 @@ func makeTestOCIImageIndex(t *testing.T, mediaType string) ([]ManifestDescriptor manifestDescriptors := []ManifestDescriptor{ { Descriptor: distribution.Descriptor{ + MediaType: "application/vnd.oci.image.manifest.v1+json", Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Size: 985, - MediaType: "application/vnd.oci.image.manifest.v1+json", }, Platform: PlatformSpec{ Architecture: "amd64", @@ -195,17 +195,17 @@ func makeTestOCIImageIndex(t *testing.T, mediaType string) ([]ManifestDescriptor }, { Descriptor: distribution.Descriptor{ + MediaType: "application/vnd.oci.image.manifest.v1+json", Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Size: 985, - MediaType: "application/vnd.oci.image.manifest.v1+json", Annotations: map[string]string{"platform": "none"}, }, }, { Descriptor: distribution.Descriptor{ + MediaType: "application/vnd.oci.image.manifest.v1+json", Digest: "sha256:6346340964309634683409684360934680934608934608934608934068934608", Size: 2392, - MediaType: "application/vnd.oci.image.manifest.v1+json", Annotations: map[string]string{"what": "for"}, }, Platform: PlatformSpec{ diff --git a/manifest/ocischema/builder_test.go b/manifest/ocischema/builder_test.go index e1fe516c0..b147111cb 100644 --- a/manifest/ocischema/builder_test.go +++ b/manifest/ocischema/builder_test.go @@ -92,20 +92,20 @@ func TestBuilder(t *testing.T) { descriptors := []distribution.Descriptor{ { + MediaType: v1.MediaTypeImageLayerGzip, Digest: digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"), Size: 5312, - MediaType: v1.MediaTypeImageLayerGzip, Annotations: map[string]string{"apple": "orange", "lettuce": "wrap"}, }, { + MediaType: v1.MediaTypeImageLayerGzip, Digest: digest.Digest("sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa"), Size: 235231, - MediaType: v1.MediaTypeImageLayerGzip, }, { + MediaType: v1.MediaTypeImageLayerGzip, Digest: digest.Digest("sha256:b4ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"), Size: 639152, - MediaType: v1.MediaTypeImageLayerGzip, }, } annotations := map[string]string{"hot": "potato"} diff --git a/manifest/ocischema/manifest_test.go b/manifest/ocischema/manifest_test.go index 6b7a7028a..a906eab9e 100644 --- a/manifest/ocischema/manifest_test.go +++ b/manifest/ocischema/manifest_test.go @@ -46,16 +46,16 @@ func makeTestManifest(mediaType string) Manifest { MediaType: mediaType, }, Config: distribution.Descriptor{ + MediaType: v1.MediaTypeImageConfig, Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Size: 985, - MediaType: v1.MediaTypeImageConfig, Annotations: map[string]string{"apple": "orange"}, }, Layers: []distribution.Descriptor{ { + MediaType: v1.MediaTypeImageLayerGzip, Digest: "sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b", Size: 153263, - MediaType: v1.MediaTypeImageLayerGzip, Annotations: map[string]string{"lettuce": "wrap"}, }, }, diff --git a/manifest/schema1/config_builder_test.go b/manifest/schema1/config_builder_test.go index 688e73eb0..32b7c1f57 100644 --- a/manifest/schema1/config_builder_test.go +++ b/manifest/schema1/config_builder_test.go @@ -29,9 +29,9 @@ func (bs *mockBlobService) Stat(ctx context.Context, dgst digest.Digest) (distri func (bs *mockBlobService) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) { d := distribution.Descriptor{ + MediaType: mediaType, Digest: digest.FromBytes(p), Size: int64(len(p)), - MediaType: mediaType, } bs.descriptors[d.Digest] = d return d, nil diff --git a/manifest/schema1/manifest.go b/manifest/schema1/manifest.go index c99a48be4..7feeef7c5 100644 --- a/manifest/schema1/manifest.go +++ b/manifest/schema1/manifest.go @@ -35,9 +35,9 @@ func init() { } desc := distribution.Descriptor{ + MediaType: MediaTypeSignedManifest, Digest: digest.FromBytes(sm.Canonical), Size: int64(len(sm.Canonical)), - MediaType: MediaTypeSignedManifest, } return sm, desc, err } diff --git a/manifest/schema2/builder_test.go b/manifest/schema2/builder_test.go index 81b0ea052..aa9f17c14 100644 --- a/manifest/schema2/builder_test.go +++ b/manifest/schema2/builder_test.go @@ -23,9 +23,9 @@ func (bs *mockBlobService) Stat(ctx context.Context, dgst digest.Digest) (distri func (bs *mockBlobService) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) { d := distribution.Descriptor{ + MediaType: "application/octet-stream", Digest: digest.FromBytes(p), Size: int64(len(p)), - MediaType: "application/octet-stream", } bs.descriptors[d.Digest] = d return d, nil @@ -134,19 +134,19 @@ func TestBuilder(t *testing.T) { descriptors := []distribution.Descriptor{ { + MediaType: MediaTypeLayer, Digest: digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"), Size: 5312, - MediaType: MediaTypeLayer, }, { + MediaType: MediaTypeLayer, Digest: digest.Digest("sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa"), Size: 235231, - MediaType: MediaTypeLayer, }, { + MediaType: MediaTypeLayer, Digest: digest.Digest("sha256:b4ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"), Size: 639152, - MediaType: MediaTypeLayer, }, } diff --git a/manifest/schema2/manifest_test.go b/manifest/schema2/manifest_test.go index 463137448..23d69f032 100644 --- a/manifest/schema2/manifest_test.go +++ b/manifest/schema2/manifest_test.go @@ -34,15 +34,15 @@ func makeTestManifest(mediaType string) Manifest { MediaType: mediaType, }, Config: distribution.Descriptor{ + MediaType: MediaTypeImageConfig, Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Size: 985, - MediaType: MediaTypeImageConfig, }, Layers: []distribution.Descriptor{ { + MediaType: MediaTypeLayer, Digest: "sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b", Size: 153263, - MediaType: MediaTypeLayer, }, }, } diff --git a/notifications/bridge.go b/notifications/bridge.go index 58a1d3fc3..ff5a7980c 100644 --- a/notifications/bridge.go +++ b/notifications/bridge.go @@ -150,9 +150,9 @@ func (b *bridge) createManifestEvent(action string, repo reference.Named, sm dis } event.Target.MediaType = mt - event.Target.Length = desc.Size - event.Target.Size = desc.Size event.Target.Digest = desc.Digest + event.Target.Size = desc.Size + event.Target.Length = desc.Size if b.includeReferences { event.Target.References = append(event.Target.References, manifest.References()...) } diff --git a/notifications/event_test.go b/notifications/event_test.go index 7eea08f7a..415627177 100644 --- a/notifications/event_test.go +++ b/notifications/event_test.go @@ -116,28 +116,28 @@ func TestEventEnvelopeJSONFormat(t *testing.T) { manifestPush := prototype manifestPush.ID = "asdf-asdf-asdf-asdf-0" - manifestPush.Target.Digest = "sha256:0123456789abcdef0" - manifestPush.Target.Length = 1 - manifestPush.Target.Size = 1 manifestPush.Target.MediaType = schema1.MediaTypeSignedManifest + manifestPush.Target.Digest = "sha256:0123456789abcdef0" + manifestPush.Target.Size = 1 + manifestPush.Target.Length = 1 manifestPush.Target.Repository = "library/test" manifestPush.Target.URL = "http://example.com/v2/library/test/manifests/latest" layerPush0 := prototype layerPush0.ID = "asdf-asdf-asdf-asdf-1" - layerPush0.Target.Digest = "sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5" - layerPush0.Target.Length = 2 - layerPush0.Target.Size = 2 layerPush0.Target.MediaType = layerMediaType + layerPush0.Target.Digest = "sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5" + layerPush0.Target.Size = 2 + layerPush0.Target.Length = 2 layerPush0.Target.Repository = "library/test" layerPush0.Target.URL = "http://example.com/v2/library/test/manifests/latest" layerPush1 := prototype layerPush1.ID = "asdf-asdf-asdf-asdf-2" - layerPush1.Target.Digest = "sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d6" - layerPush1.Target.Length = 3 - layerPush1.Target.Size = 3 layerPush1.Target.MediaType = layerMediaType + layerPush1.Target.Digest = "sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d6" + layerPush1.Target.Size = 3 + layerPush1.Target.Length = 3 layerPush1.Target.Repository = "library/test" layerPush1.Target.URL = "http://example.com/v2/library/test/manifests/latest"