diff --git a/Makefile b/Makefile index 02c3245d9..b2dbf79a5 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,8 @@ DOC_FILES := \ image-layout.md \ layer.md \ config.md \ - manifest.md + manifest.md \ + manifest-list.md FIGURE_FILES := \ img/media-types.png diff --git a/README.md b/README.md index a58cc769b..08c54ae0c 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,8 @@ The OCI Image Format project creates and maintains the software shipping contain - [Image Layout](image-layout.md) - [Filesystem Layers](layer.md) - [Image Configuration](config.md) -- [Manifests and Manifest Lists](manifest.md) +- [Image Manifest](manifest.md) +- [Image Manifest List](manifest-list.md) ## Overview diff --git a/image-layout.md b/image-layout.md index 1946b5592..d77e1e7ae 100644 --- a/image-layout.md +++ b/image-layout.md @@ -5,7 +5,7 @@ This layout MAY be used in a variety of different transport mechanisms: archive Given an image layout and a ref, a tool can create an [OCI Runtime Specification bundle](https://github.com/opencontainers/runtime-spec/blob/v1.0.0-rc2/bundle.md) by: -* Following the ref to find a [manifest](manifest.md#image-manifest), possibly via a [manifest list](manifest.md#manifest-list) +* Following the ref to find a [manifest](manifest.md#image-manifest), possibly via a [manifest list](manifest-list.md#manifest-list) * [Applying the filesystem layers](layers.md#applying) in the specified order * Converting the [image configuration](config.md) into an [OCI Runtime Specification `config.json`](https://github.com/opencontainers/runtime-spec/blob/v1.0.0-rc2/config.md) diff --git a/manifest-list.md b/manifest-list.md new file mode 100644 index 000000000..b3aef15fe --- /dev/null +++ b/manifest-list.md @@ -0,0 +1,119 @@ +# OCI Image Manifest List Specification + +The manifest list is a higher-level manifest which points to specific [image manifests](manifest.md) for one or more platforms. +While the use of a manifest list is OPTIONAL for image providers, image consumers SHOULD be prepared to process them. +A client will distinguish a manifest list from an image manifest based on the Content-Type returned in the HTTP response. + +This section defines the `application/vnd.oci.image.manifest.list.v1+json` [media type](media-types.md). + +## *Manifest List* Property Descriptions + +- **`schemaVersion`** *int* + + This REQUIRED property specifies the image manifest schema version. + For this version of the specification, this MUST be `2` to ensure backward compatibility with older versions of Docker. The value of this field will not change. This field MAY be removed in a future version of the specification. + +- **`mediaType`** *string* + + This REQUIRED property contains the media type of the manifest list. + For this version of the specification, this MUST be set to `application/vnd.oci.image.manifest.list.v1+json`. + For the media type(s) that this is compatible with see the [matrix](media-types.md#compatibility-matrix). + +- **`manifests`** *array* + + This REQUIRED property contains a list of manifests for specific platforms. + While the property MUST be present, the size of the array MAY be zero. + + Each object in the manifest is a [descriptor](descriptor.md) with the following additional properties and restrictions: + + - **`mediaType`** *object* + + This [descriptor property](descriptor.md#properties) has additional restrictions for `manifests`. + Implementations MUST support at least the following media types: + + - [`application/vnd.oci.image.manifest.v1+json`](manifest.md) + + Manifest lists concerned with portability SHOULD use one of the above media types. + + - **`platform`** *object* + + This REQUIRED property describes the platform which the image in the manifest runs on. + A full list of valid operating system and architecture values are listed in the [Go language documentation for `$GOOS` and `$GOARCH`](https://golang.org/doc/install/source#environment) + + - **`architecture`** *string* + + This REQUIRED property specified the CPU architecture, for example `amd64` or `ppc64le`. + + - **`os`** *string* + + This REQUIRED property specifies the operating system, for example `linux` or `windows`. + + - **`os.version`** *string* + + This OPTIONAL property specifies the operating system version, for example `10.0.10586`. + + - **`os.features`** *array* + + This OPTIONAL property specifies an array of strings, each specifying a mandatory OS feature (for example on Windows `win32k`). + + - **`variant`** *string* + + This OPTIONAL property specifies the variant of the CPU, for example `armv6l` to specify a particular CPU variant of the ARM CPU. + + - **`features`** *array* + + This OPTIONAL property specifies an array of strings, each specifying a mandatory CPU feature (for example `sse4` or `aes`). + +- **`annotations`** *string-string map* + + This OPTIONAL property contains arbitrary metadata for the manifest list. + Annotations MUST be a key-value map where both the key and value MUST be strings. + While the value MUST be present, it MAY be an empty string. + Keys MUST be unique within this map, and best practice is to namespace the keys. + Keys SHOULD be named using a reverse domain notation - e.g. `com.example.myKey`. + Keys using the `org.opencontainers` namespace are reserved and MUST NOT be used by other specifications. + If there are no annotations then this property MUST either be absent or be an empty map. + Implementations that are reading/processing manifest lists MUST NOT generate an error if they encounter an unknown annotation key. + + See [Pre-Defined Annotation Keys](manifest.md#pre-defined-annotation-keys). + +### Extensibility +Implementations that are reading/processing manifest lists MUST NOT generate an error if they encounter an unknown property. +Instead they MUST ignore unknown properties. + +## Example Manifest List + +*Example showing a simple manifest list pointing to image manifests for two platforms:* +```json,title=Manifest%20List&mediatype=application/vnd.oci.image.manifest.list.v1%2Bjson +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.image.manifest.list.v1+json", + "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", + "features": [ + "sse4" + ] + } + } + ], + "annotations": { + "com.example.key1": "value1", + "com.example.key2": "value2" + } +} +``` diff --git a/manifest.md b/manifest.md index 94545c9a6..ebaf436c2 100644 --- a/manifest.md +++ b/manifest.md @@ -3,131 +3,14 @@ There are three main goals of the Image Manifest Specification. The first goal is content-addressable images, by supporting an image model where the image's configuration can be hashed to generate a unique ID for the image and its components. The second goal is to allow multi-architecture images, through a "fat manifest" which references image manifests for platform-specific versions of an image. -The third goal is to be translatable to the [OpenContainers/runtime-spec](https://github.com/opencontainers/runtime-spec) +In OCI, this is codified in a [Manifest List](manifest-list.md). +The third goal is to be translatable to the [OCI Runtime Specification](https://github.com/opencontainers/runtime-spec). -This section defines the `application/vnd.oci.image.manifest.list.v1+json` and `application/vnd.oci.image.manifest.v1+json` [media types](media-types.md). - -# Manifest List - -The manifest list is the "fat manifest" which points to specific image manifests for one or more platforms. -While the use of a manifest list is OPTIONAL for image providers, image consumers SHOULD be prepared to process them. -A client will distinguish a manifest list from an image manifest based on the Content-Type returned in the HTTP response. - -## *Manifest List* Property Descriptions - -- **`schemaVersion`** *int* - - This REQUIRED property specifies the image manifest schema version. - For this version of the specification, this MUST be `2` to ensure backward compatibility with older versions of Docker. The value of this field will not change. This field MAY be removed in a future version of the specification. - -- **`mediaType`** *string* - - This REQUIRED property contains the media type of the manifest list. - For this version of the specification, this MUST be set to `application/vnd.oci.image.manifest.list.v1+json`. - For the media type(s) that this is compatible with see the [matrix](media-types.md#compatibility-matrix). - -- **`manifests`** *array* - - This REQUIRED property contains a list of manifests for specific platforms. - While the property MUST be present, the size of the array MAY be zero. - - Each object in the manifest is a [descriptor](descriptor.md) with the following additional properties and restrictions: - - - **`mediaType`** *object* - - This [descriptor property](descriptor.md#properties) has additional restrictions for `manifests`. - Implementations MUST support at least the following media types: - - - [`application/vnd.oci.image.manifest.v1+json`](#image-manifest) - - Manifest lists concerned with portability SHOULD use one of the above media types. - - - **`platform`** *object* - - This REQUIRED property describes the platform which the image in the manifest runs on. - A full list of valid operating system and architecture values are listed in the [Go language documentation for `$GOOS` and `$GOARCH`](https://golang.org/doc/install/source#environment) - - - **`architecture`** *string* - - This REQUIRED property specified the CPU architecture, for example `amd64` or `ppc64le`. - - - **`os`** *string* - - This REQUIRED property specifies the operating system, for example `linux` or `windows`. - - - **`os.version`** *string* - - This OPTIONAL property specifies the operating system version, for example `10.0.10586`. - - - **`os.features`** *array* - - This OPTIONAL property specifies an array of strings, each specifying a mandatory OS feature (for example on Windows `win32k`). - - - **`variant`** *string* - - This OPTIONAL property specifies the variant of the CPU, for example `armv6l` to specify a particular CPU variant of the ARM CPU. - - - **`features`** *array* - - This OPTIONAL property specifies an array of strings, each specifying a mandatory CPU feature (for example `sse4` or `aes`). - -- **`annotations`** *string-string map* - - This OPTIONAL property contains arbitrary metadata for the manifest list. - Annotations MUST be a key-value map where both the key and value MUST be strings. - While the value MUST be present, it MAY be an empty string. - Keys MUST be unique within this map, and best practice is to namespace the keys. - Keys SHOULD be named using a reverse domain notation - e.g. `com.example.myKey`. - Keys using the `org.opencontainers` namespace are reserved and MUST NOT be used by other specifications. - If there are no annotations then this property MUST either be absent or be an empty map. - Implementations that are reading/processing manifest lists MUST NOT generate an error if they encounter an unknown annotation key. - - See [Pre-Defined Annotation Keys](#pre-defined-annotation-keys). - -### Extensibility -Implementations that are reading/processing manifest lists MUST NOT generate an error if they encounter an unknown property. -Instead they MUST ignore unknown properties. - -## Example Manifest List - -*Example showing a simple manifest list pointing to image manifests for two platforms:* -```json,title=Manifest%20List&mediatype=application/vnd.oci.image.manifest.list.v1%2Bjson -{ - "schemaVersion": 2, - "mediaType": "application/vnd.oci.image.manifest.list.v1+json", - "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", - "features": [ - "sse4" - ] - } - } - ], - "annotations": { - "com.example.key1": "value1", - "com.example.key2": "value2" - } -} -``` +This section defines the `application/vnd.oci.image.manifest.v1+json` [media type](media-types.md). # Image Manifest -Unlike the [Manifest List](#manifest-list), which contains information about a set of images that can span a variety of architectures and operating systems, an image manifest provides a configuration and set of layers for a single container image for a specific architecture and operating system. +Unlike the [Manifest List](manifest-list.md), which contains information about a set of images that can span a variety of architectures and operating systems, an image manifest provides a configuration and set of layers for a single container image for a specific architecture and operating system. ## *Image Manifest* Property Descriptions diff --git a/media-types.md b/media-types.md index b1ecfdb55..c3ad19239 100644 --- a/media-types.md +++ b/media-types.md @@ -3,9 +3,9 @@ The following media types identify the formats described here and their referenced resources: - `application/vnd.oci.descriptor.v1+json`: [Content Descriptor](descriptor.md) -- `application/vnd.oci.image.manifest.list.v1+json`: [Manifest list](manifest.md#manifest-list) -- `application/vnd.oci.image.manifest.v1+json`: [Image manifest format](manifest.md#image-manifest) -- `application/vnd.oci.image.config.v1+json`: [Image config JSON](config.md) +- `application/vnd.oci.image.manifest.list.v1+json`: [Manifest list](manifest-list.md#manifest-list) +- `application/vnd.oci.image.manifest.v1+json`: [Image manifest](manifest.md#image-manifest) +- `application/vnd.oci.image.config.v1+json`: [Image config](config.md) - `application/vnd.oci.image.layer.v1.tar+gzip`: ["Layer", as a gzipped tar archive](layer.md) - `application/vnd.oci.image.layer.nondistributable.v1.tar+gzip`: ["Layer", as a gzipped tar archive with distribution restrictions](layer.md#non-distributable-layers) diff --git a/schema/spec_test.go b/schema/spec_test.go index 1e9da5a49..2a6f4a493 100644 --- a/schema/spec_test.go +++ b/schema/spec_test.go @@ -41,6 +41,10 @@ func TestValidateManifest(t *testing.T) { validate(t, "../manifest.md") } +func TestValidateManifestList(t *testing.T) { + validate(t, "../manifest-list.md") +} + func TestValidateConfig(t *testing.T) { validate(t, "../config.md") }