Skip to content

Commit

Permalink
manifest.GuessMIMEType(): recognize self-described OCI manifests
Browse files Browse the repository at this point in the history
Newer versions of the OCI spec include the mediaType field in image
manifests and image indexes, and if they include them, save ourselves
some work by using that information.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
  • Loading branch information
nalind committed Nov 29, 2021
1 parent 4f6d0b4 commit 886a2ed
Show file tree
Hide file tree
Showing 23 changed files with 96 additions and 5 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ require (
github.com/morikuni/aec v1.0.0 // indirect
github.com/mtrmac/gpgme v0.1.2
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283
github.com/opencontainers/image-spec v1.0.2-0.20211123152302-43a7dee1ec31
github.com/opencontainers/selinux v1.10.0
github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913
github.com/pkg/errors v0.9.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,8 @@ github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283 h1:TVzvdjOalkJBNkbpPVMAr4KV9QRf2IjfxdyxwAK78Gs=
github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2-0.20211123152302-43a7dee1ec31 h1:Wh4aR2I6JFwySre9m3iHJYuMnvUFE/HT6qAXozRWi/E=
github.com/opencontainers/image-spec v1.0.2-0.20211123152302-43a7dee1ec31/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
Expand Down
1 change: 1 addition & 0 deletions image/fixtures/oci1-all-media-types.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 4651,
Expand Down
1 change: 1 addition & 0 deletions image/fixtures/oci1.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 5940,
Expand Down
1 change: 1 addition & 0 deletions image/fixtures/oci1index.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
Expand Down
1 change: 1 addition & 0 deletions image/fixtures/schema1-to-oci1.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": -1,
Expand Down
1 change: 1 addition & 0 deletions image/fixtures/schema2-all-media-types-to-oci1.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 4651,
Expand Down
1 change: 1 addition & 0 deletions image/fixtures/schema2-to-oci1.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 4651,
Expand Down
1 change: 1 addition & 0 deletions manifest/fixtures/ociv1.artifact.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.custom.artifact.config.v1+json",
"digest": "",
Expand Down
1 change: 1 addition & 0 deletions manifest/fixtures/ociv1.image.index.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
Expand Down
1 change: 1 addition & 0 deletions manifest/fixtures/ociv1.manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 7023,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 7023,
Expand Down
1 change: 1 addition & 0 deletions manifest/fixtures/ociv1.nondistributable.manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 7023,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 7023,
Expand Down
1 change: 1 addition & 0 deletions manifest/fixtures/ociv1.uncompressed.manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 7023,
Expand Down
1 change: 1 addition & 0 deletions manifest/fixtures/ociv1.zstd.manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 7023,
Expand Down
9 changes: 9 additions & 0 deletions manifest/fixtures/ociv1nomime.artifact.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"schemaVersion": 2,
"config": {
"mediaType": "application/vnd.oci.custom.artifact.config.v1+json",
"digest": "",
"size": 0
},
"layers": null
}
30 changes: 30 additions & 0 deletions manifest/fixtures/ociv1nomime.image.index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 7143,
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
"platform": {
"architecture": "ppc64le",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 7682,
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
"platform": {
"architecture": "amd64",
"os": "linux",
"os.features": [
"sse4"
]
}
}
],
"annotations": {
"com.example.key1": "value1",
"com.example.key2": "value2"
}
}
29 changes: 29 additions & 0 deletions manifest/fixtures/ociv1nomime.manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"schemaVersion": 2,
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 7023,
"digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7"
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 32654,
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f"
},
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 16724,
"digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b"
},
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 73109,
"digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736"
}
],
"annotations": {
"com.example.key1": "value1",
"com.example.key2": "value2"
}
}
9 changes: 5 additions & 4 deletions manifest/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ func GuessMIMEType(manifest []byte) string {
}

switch meta.MediaType {
case DockerV2Schema2MediaType, DockerV2ListMediaType: // A recognized type.
case DockerV2Schema2MediaType, DockerV2ListMediaType,
imgspecv1.MediaTypeImageManifest, imgspecv1.MediaTypeImageIndex: // A recognized type.
return meta.MediaType
}
// this is the only way the function can return DockerV2Schema1MediaType, and recognizing that is essential for stripping the JWS signatures = computing the correct manifest digest.
Expand All @@ -121,9 +122,9 @@ func GuessMIMEType(manifest []byte) string {
}
return DockerV2Schema1MediaType
case 2:
// best effort to understand if this is an OCI image since mediaType
// isn't in the manifest for OCI anymore
// for docker v2s2 meta.MediaType should have been set. But given the data, this is our best guess.
// Best effort to understand if this is an OCI image since mediaType
// wasn't in the manifest for OCI image-spec < 1.0.2.
// For docker v2s2 meta.MediaType should have been set. But given the data, this is our best guess.
ociMan := struct {
Config struct {
MediaType string `json:"mediaType"`
Expand Down
3 changes: 3 additions & 0 deletions manifest/manifest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ func TestGuessMIMEType(t *testing.T) {
{"ociv1.manifest.json", imgspecv1.MediaTypeImageManifest},
{"ociv1.artifact.json", imgspecv1.MediaTypeImageManifest},
{"ociv1.image.index.json", imgspecv1.MediaTypeImageIndex},
{"ociv1nomime.manifest.json", imgspecv1.MediaTypeImageManifest},
{"ociv1nomime.artifact.json", imgspecv1.MediaTypeImageManifest},
{"ociv1nomime.image.index.json", imgspecv1.MediaTypeImageIndex},
}

for _, c := range cases {
Expand Down
1 change: 1 addition & 0 deletions manifest/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func OCI1FromComponents(config imgspecv1.Descriptor, layers []imgspecv1.Descript
return &OCI1{
imgspecv1.Manifest{
Versioned: specs.Versioned{SchemaVersion: 2},
MediaType: imgspecv1.MediaTypeImageManifest,
Config: config,
Layers: layers,
},
Expand Down
2 changes: 2 additions & 0 deletions manifest/oci_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ func OCI1IndexFromComponents(components []imgspecv1.Descriptor, annotations map[
index := OCI1Index{
imgspecv1.Index{
Versioned: imgspec.Versioned{SchemaVersion: 2},
MediaType: imgspecv1.MediaTypeImageIndex,
Manifests: make([]imgspecv1.Descriptor, len(components)),
Annotations: dupStringStringMap(annotations),
},
Expand Down Expand Up @@ -195,6 +196,7 @@ func OCI1IndexFromManifest(manifest []byte) (*OCI1Index, error) {
index := OCI1Index{
Index: imgspecv1.Index{
Versioned: imgspec.Versioned{SchemaVersion: 2},
MediaType: imgspecv1.MediaTypeImageIndex,
Manifests: []imgspecv1.Descriptor{},
Annotations: make(map[string]string),
},
Expand Down

0 comments on commit 886a2ed

Please sign in to comment.