From 92b19dbf6966a9b884ebb08a651c819a14d93a87 Mon Sep 17 00:00:00 2001 From: Brandon Mitchell Date: Fri, 29 Mar 2024 16:18:55 -0400 Subject: [PATCH] Clarify mediaType and artifactType syntax Signed-off-by: Brandon Mitchell --- descriptor.md | 7 ++----- image-index.md | 5 +---- manifest.md | 9 +++------ media-types.md | 18 ++++++++++++++++-- schema/defs-descriptor.json | 2 +- schema/descriptor_test.go | 13 +++++++++++++ schema/manifest_test.go | 24 ++++++++++++++++++++++++ 7 files changed, 60 insertions(+), 18 deletions(-) diff --git a/descriptor.md b/descriptor.md index 455db1efa..81c1b2302 100644 --- a/descriptor.md +++ b/descriptor.md @@ -19,7 +19,7 @@ The following fields contain the primary properties that constitute a Descriptor - **`mediaType`** *string* This REQUIRED property contains the media type of the referenced content. - Values MUST comply with [RFC 6838][rfc6838], including the [naming requirements in its section 4.2][rfc6838-s4.2]. + Values MUST comply with the [media type syntax](media-types.md#media-type-syntax). The OCI image specification defines [several of its own MIME types](media-types.md) for resources defined in the specification. @@ -56,7 +56,7 @@ The following fields contain the primary properties that constitute a Descriptor This OPTIONAL property contains the type of an artifact when the descriptor points to an artifact. This is the value of the config descriptor `mediaType` when the descriptor references an [image manifest](manifest.md). - If defined, the value MUST comply with [RFC 6838][rfc6838], including the [naming requirements in its section 4.2][rfc6838-s4.2], and MAY be registered with [IANA][iana]. + If defined, the value MUST comply with the [media type syntax](media-types.md#media-type-syntax). Descriptors pointing to [`application/vnd.oci.image.manifest.v1+json`](manifest.md) SHOULD include the extended field `platform`, see [Image Index Property Descriptions](image-index.md#image-index-property-descriptions) for details. @@ -214,8 +214,5 @@ In the following example, the descriptor indicates the type of artifact it is re [rfc4634-s4.1]: https://tools.ietf.org/html/rfc4634#section-4.1 [rfc4634-s4.2]: https://tools.ietf.org/html/rfc4634#section-4.2 [rfc4648-s4]: https://tools.ietf.org/html/rfc4648#section-4 -[rfc6838]: https://tools.ietf.org/html/rfc6838 -[rfc6838-s4.2]: https://tools.ietf.org/html/rfc6838#section-4.2 [rfc7230-s2.7]: https://tools.ietf.org/html/rfc7230#section-2.7 [sha256-vs-sha512]: https://groups.google.com/a/opencontainers.org/forum/#!topic/dev/hsMw7cAwrZE -[iana]: https://www.iana.org/assignments/media-types/media-types.xhtml diff --git a/image-index.md b/image-index.md index 7cd44ea2e..9866be07b 100644 --- a/image-index.md +++ b/image-index.md @@ -25,7 +25,7 @@ For the media type(s) that this document is compatible with, see the [matrix][ma - **`artifactType`** *string* This OPTIONAL property contains the type of an artifact when the manifest is used for an artifact. - If defined, the value MUST comply with [RFC 6838][rfc6838], including the [naming requirements in its section 4.2][rfc6838-s4.2], and MAY be registered with [IANA][iana]. + If defined, the value MUST comply with the [media type syntax](media-types.md#media-type-syntax). - **`manifests`** *array of objects* @@ -183,8 +183,5 @@ These values SHOULD match (or be similar to) their analog listed in [the Go Lang [dag]: https://en.wikipedia.org/wiki/Merkle_tree [go-environment2]: https://golang.org/doc/install/source#environment -[iana]: https://www.iana.org/assignments/media-types/media-types.xhtml [matrix]: media-types.md#compatibility-matrix [referrers-api]: https://github.com/opencontainers/distribution-spec/blob/main/spec.md#listing-referrers -[rfc6838]: https://tools.ietf.org/html/rfc6838 -[rfc6838-s4.2]: https://tools.ietf.org/html/rfc6838#section-4.2 diff --git a/manifest.md b/manifest.md index 7430f515b..690d637fc 100644 --- a/manifest.md +++ b/manifest.md @@ -30,7 +30,7 @@ Unlike the [image index](image-index.md), which contains information about a set This OPTIONAL property contains the type of an artifact when the manifest is used for an artifact. This MUST be set when `config.mediaType` is set to the [empty value](#guidance-for-an-empty-descriptor). - If defined, the value MUST comply with [RFC 6838][rfc6838], including the [naming requirements in its section 4.2][rfc6838-s4.2], and MAY be registered with [IANA][iana]. + If defined, the value MUST comply with the [media type syntax](media-types.md#media-type-syntax). Implementations storing or copying image manifests MUST NOT error on encountering an `artifactType` that is unknown to the implementation. - **`config`** *[descriptor](descriptor.md)* @@ -53,7 +53,7 @@ Unlike the [image index](image-index.md), which contains information about a set Manifests for container images concerned with portability SHOULD use one of the above media types. Manifests for artifacts concerned with portability SHOULD use `config.mediaType` as described in [Guidelines for Artifact Usage](#guidelines-for-artifact-usage). - If the manifest uses a different media type than the above, it MUST comply with [RFC 6838][rfc6838], including the [naming requirements in its section 4.2][rfc6838-s4.2], and MAY be registered with [IANA][iana]. + If the manifest uses a different media type than the above, it MUST comply with the [media type syntax](media-types.md#media-type-syntax). To set an effectively null or empty config and maintain portability see the [guidance for an empty descriptor](#guidance-for-an-empty-descriptor) below, and `DescriptorEmptyJSON` of the reference code. @@ -89,7 +89,7 @@ Unlike the [image index](image-index.md), which contains information about a set Entries in this field will frequently use the `+gzip` types. - If the manifest uses a different media type than the above, it MUST comply with [RFC 6838][rfc6838], including the [naming requirements in its section 4.2][rfc6838-s4.2], and MAY be registered with [IANA][iana]. + If the manifest uses a different media type than the above, it MUST comply with the [media type syntax](media-types.md#media-type-syntax). See [Guidelines for Artifact Usage](#guidelines-for-artifact-usage) for other uses of the `layers`. @@ -260,7 +260,4 @@ The decision tree below and the associated examples MAY be used to design new ar _Implementers note:_ artifacts have historically been created without an `artifactType` field, and tooling to work with artifacts should fallback to the `config.mediaType` value. [dag]: https://en.wikipedia.org/wiki/Merkle_tree -[iana]: https://www.iana.org/assignments/media-types/media-types.xhtml [referrers-api]: https://github.com/opencontainers/distribution-spec/blob/main/spec.md#listing-referrers -[rfc6838]: https://tools.ietf.org/html/rfc6838 -[rfc6838-s4.2]: https://tools.ietf.org/html/rfc6838#section-4.2 diff --git a/media-types.md b/media-types.md index 31377d990..3b98b195c 100644 --- a/media-types.md +++ b/media-types.md @@ -18,6 +18,17 @@ The following media types identify a ["Layer" with distribution restrictions](la - `application/vnd.oci.image.layer.nondistributable.v1.tar+gzip`: ["Layer", as a tar archive with distribution restrictions](layer.md#gzip-media-types) compressed with [gzip][rfc1952] - `application/vnd.oci.image.layer.nondistributable.v1.tar+zstd`: ["Layer", as a tar archive with distribution restrictions](layer.md#zstd-media-types) compressed with [zstd][rfc8478] +## Media Type Syntax + +Media types values MUST comply with [RFC 6838][rfc6838], including the [naming requirements in its section 4.2][rfc6838-s4.2], and MAY be registered with [IANA][iana]. +Media types values MUST have a top-level type and subtype name, separated by a `/`, without any parameters. + +The following regular expression may be used to validate media types: + +```regexp +^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}$ +``` + ## Media Type Conflicts [Blob](image-layout.md) retrieval methods MAY return media type metadata. @@ -86,5 +97,8 @@ The following figure shows how the above media types reference each other: [Descriptors](descriptor.md) are used for all references. The image-index being a "fat manifest" references a list of image manifests per target platform. An image manifest references exactly one target configuration and possibly many layers. -[rfc1952]: https://tools.ietf.org/html/rfc1952 -[rfc8478]: https://tools.ietf.org/html/rfc8478 +[iana]: https://www.iana.org/assignments/media-types/media-types.xhtml +[rfc1952]: https://tools.ietf.org/html/rfc1952 +[rfc6838]: https://tools.ietf.org/html/rfc6838 +[rfc6838-s4.2]: https://tools.ietf.org/html/rfc6838#section-4.2 +[rfc8478]: https://tools.ietf.org/html/rfc8478 diff --git a/schema/defs-descriptor.json b/schema/defs-descriptor.json index dad2b0a3f..056a7999f 100644 --- a/schema/defs-descriptor.json +++ b/schema/defs-descriptor.json @@ -4,7 +4,7 @@ "mediaType": { "id": "https://opencontainers.org/schema/image/descriptor/mediaType", "type": "string", - "pattern": "^[A-Za-z0-9][A-Za-z0-9!#$&-^_.+]{0,126}/[A-Za-z0-9][A-Za-z0-9!#$&-^_.+]{0,126}$" + "pattern": "^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}$" }, "digest": { "description": "the cryptographic checksum digest of the object, in the pattern ':'", diff --git a/schema/descriptor_test.go b/schema/descriptor_test.go index c3bce28f7..823f5e1eb 100644 --- a/schema/descriptor_test.go +++ b/schema/descriptor_test.go @@ -259,6 +259,19 @@ func TestDescriptor(t *testing.T) { fail: true, }, + // expected failure: artifactType does not match pattern (parameters not allowed) + { + descriptor: ` + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "artifactType": "foo/star.bar;version=1.0", + "size": 7682, + "digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270" + } + `, + fail: true, + }, + // expected success: data field is present and has base64 content { descriptor: ` diff --git a/schema/manifest_test.go b/schema/manifest_test.go index 732b1561a..29459c6c9 100644 --- a/schema/manifest_test.go +++ b/schema/manifest_test.go @@ -336,6 +336,30 @@ func TestManifest(t *testing.T) { `, fail: false, }, + + // invalid artifactType value + { + manifest: ` +{ + "schemaVersion": 2, + "mediaType" : "application/vnd.oci.image.manifest.v1+json", + "artifactType": "application/vnd.example+type;revision=1.5", + "config": { + "mediaType": "application/vnd.oci.empty.v1+json", + "size": 2, + "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a" + }, + "layers": [ + { + "mediaType": "application/vnd.example+type;revision=1.5", + "size": 675598, + "digest": "sha256:9d3dd9504c685a304985025df4ed0283e47ac9ffa9bd0326fddf4d59513f0827" + } + ] +} +`, + fail: true, + }, } { r := strings.NewReader(tt.manifest) err := schema.ValidatorMediaTypeManifest.Validate(r)