-
Notifications
You must be signed in to change notification settings - Fork 808
Begin adjustments on the imported specs #12
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
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 |
|---|---|---|
|
|
@@ -4,124 +4,101 @@ draft = true | |
| +++ | ||
| <![end-metadata]--> | ||
|
|
||
| # Image Manifest Version 2, Schema 2 | ||
|
|
||
| This document outlines the format of of the V2 image manifest, schema version 2. | ||
| The original (and provisional) image manifest for V2 (schema 1), was introduced | ||
| in the Docker daemon in the [v1.3.0 | ||
| release](https://github.com/docker/docker/commit/9f482a66ab37ec396ac61ed0c00d59122ac07453) | ||
| and is specified in the [schema 1 manifest definition](./manifest-v2-1.md) | ||
| # Image Manifest | ||
|
|
||
| This second schema version has two primary goals. The first is to allow | ||
| multi-architecture images, through a "fat manifest" which references image | ||
| manifests for platform-specific versions of an image. The second is to | ||
| move the Docker engine towards content-addressable images, by supporting | ||
| an image model where the image's configuration can be hashed to generate | ||
| an ID for the image. | ||
| 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) | ||
|
|
||
| # Media Types | ||
|
|
||
| The following media types are used by the manifest formats described here, and | ||
| the resources they reference: | ||
| The following media types are used by the manifest formats described here, and the resources they reference: | ||
|
|
||
| - `application/vnd.docker.distribution.manifest.v1+json`: schema1 (existing manifest format) | ||
| - `application/vnd.docker.distribution.manifest.v2+json`: New image manifest format (schemaVersion = 2) | ||
| - `application/vnd.docker.distribution.manifest.list.v2+json`: Manifest list, aka "fat manifest" | ||
| - `application/vnd.docker.image.rootfs.diff.tar.gzip`: "Layer", as a gzipped tar | ||
| - `application/vnd.docker.container.image.v1+json`: Container config JSON | ||
| - `application/vnd.oci.image.manifest.list.v1+json`: Manifest list, aka "fat manifest" | ||
| - `application/vnd.oci.image.manifest.v1+json`: Image manifest format | ||
| - `application/vnd.oci.image.rootfs.tar.gzip`: "Layer", as a gzipped tar archive | ||
| - `application/vnd.oci.image.serialization.v1+json`: Container config JSON | ||
|
|
||
| ## Manifest List | ||
|
|
||
| The manifest list is the "fat manifest" which points to specific image manifests | ||
| for one or more platforms. Its use is optional, and relatively few images will | ||
| use one of these manifests. A client will distinguish a manifest list from an | ||
| image manifest based on the Content-Type returned in the HTTP response. | ||
| 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* Field Descriptions | ||
|
|
||
| - **`schemaVersion`** *int* | ||
| This field specifies the image manifest schema version as an integer. This | ||
| schema uses the version `2`. | ||
|
|
||
| This REQUIRED property specifies the image manifest schema version. | ||
|
Contributor
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. This reset will make the format incompatible with Docker's manifest format. I'd rather we maintain this at 2 and deprecate the field.
Member
Author
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. k. changed. On Fri, Apr 8, 2016 at 2:21 PM, Stephen Day [email protected]
Contributor
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. We will need a note as to why it is at 2. Leaving it at 2 is fine by me.
Member
Author
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. perhaps as a part of the compatibility matrix/table On Fri, Apr 8, 2016 at 2:43 PM, Brandon Philips [email protected]
|
||
| This schema uses the version `2`. | ||
|
|
||
| - **`mediaType`** *string* | ||
|
|
||
| The MIME type of the manifest list. This should be set to | ||
| `application/vnd.docker.distribution.manifest.list.v2+json`. | ||
| This REQUIRED property contains the MIME type of the manifest list. | ||
| For this version of the specification, this MUST be set to `application/vnd.oci.image.manifest.list.v1+json`. | ||
|
|
||
| - **`manifests`** *array* | ||
|
|
||
| The manifests field contains a list of manifests for specific platforms. | ||
| 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. | ||
|
|
||
| Fields of a object in the manifests list are: | ||
|
|
||
| - **`mediaType`** *string* | ||
|
|
||
| The MIME type of the referenced object. This will generally be | ||
| `application/vnd.docker.image.manifest.v2+json`, but it could also | ||
| be `application/vnd.docker.image.manifest.v1+json` if the manifest | ||
| list references a legacy schema-1 manifest. | ||
|
|
||
| - **`size`** *int* | ||
|
|
||
| The size in bytes of the object. This field exists so that a client | ||
| will have an expected size for the content before validating. If the | ||
| length of the retrieved content does not match the specified length, | ||
| the content should not be trusted. | ||
|
|
||
| - **`digest`** *string* | ||
| Fields of each object in the manifests list are: | ||
|
Collaborator
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. This seems to assume that there is no in-lining of the referenced images - meaning, we're not defining a way for someone to download a single entity that contains the fat manifest plus all referenced images. Was this intentional? I think it would be good to allow for the sharing of single entities instead of forcing people to always break things up.
Member
Author
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. Are you saying that the
Collaborator
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. This wasn't really a statement about the manifests array itself, its just that this is where I was in the doc when it dawned on me that downloading this manifest json by itself feels like the main usecase being promoted - so I started to wonder about the "big bundle" case. So, should we consider creating a blob (tar) containing this manifest and all referenced images as files in there?
Member
Author
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. This is the confusion around having 0 mapping to even an OPTIONAL api, like On Wed, Apr 13, 2016 at 11:03 AM, Doug Davis [email protected]
Contributor
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. If we do embedding, it should probably be with a |
||
|
|
||
| - **`mediaType`** *string* | ||
|
|
||
| The digest of the content, as defined by the | ||
| [Registry V2 HTTP API Specificiation](https://docs.docker.com/registry/spec/api/#digest-parameter). | ||
| This REQUIRED property contains the MIME type of the referenced object. | ||
| (i.e. `application/vnd.oci.image.manifest.v1+json`) | ||
|
|
||
| - **`platform`** *object* | ||
| - **`size`** *int* | ||
|
|
||
| The platform object 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) | ||
| This REQUIRED property specifies the size in bytes of the object. | ||
| This field exists so that a client will have an expected size for the content before validating. | ||
| If the length of the retrieved content does not match the specified length, the content should not be trusted. | ||
|
|
||
| - **`architecture`** *string* | ||
| - **`digest`** *string* | ||
|
|
||
| The architecture field specifies the CPU architecture, for example | ||
| `amd64` or `ppc64le`. | ||
| The digest of the content, as defined by the [Registry V2 HTTP API Specificiation](https://docs.docker.com/registry/spec/api/#digest-parameter). | ||
|
|
||
| - **`os`** *string* | ||
| - **`platform`** *object* | ||
|
|
||
| The os field specifies the operating system, for example | ||
| `linux` or `windows`. | ||
| 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) | ||
|
|
||
| - **`os.version`** *string* | ||
| - **`architecture`** *string* | ||
|
|
||
| The optional os.version field specifies the operating system version, | ||
| for example `10.0.10586`. | ||
| This REQUIRED property specified the CPU architecture, for example `amd64` or `ppc64le`. | ||
|
|
||
| - **`os.features`** *array* | ||
| - **`os`** *string* | ||
|
|
||
| The optional os.features field specifies an array of strings, | ||
| each listing a required OS feature (for example on Windows | ||
| `win32k`). | ||
| This REQUIRED property specifies the operating system, for example `linux` or `windows`. | ||
|
|
||
| - **`variant`** *string* | ||
| - **`os.version`** *string* | ||
|
|
||
| The optional variant field specifies a variant of the CPU, for | ||
| example `armv6l` to specify a particular CPU variant of the ARM CPU. | ||
| This optional property specifies the operating system version, for example `10.0.10586`. | ||
|
|
||
| - **`features`** *array* | ||
| - **`os.features`** *array* | ||
|
|
||
| The optional features field specifies an array of strings, each | ||
| listing a required CPU feature (for example `sse4` or `aes`). | ||
| 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`). | ||
|
|
||
| ## Example Manifest List | ||
|
|
||
| *Example showing a simple manifest list pointing to image manifests for two platforms:* | ||
| ```json | ||
| { | ||
| "schemaVersion": 2, | ||
| "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", | ||
| "mediaType": "application/vnd.oci.image.manifest.list.v1+json", | ||
| "manifests": [ | ||
| { | ||
| "mediaType": "application/vnd.docker.image.manifest.v2+json", | ||
| "mediaType": "application/vnd.oci.image.manifest.v1+json", | ||
| "size": 7143, | ||
| "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f", | ||
| "platform": { | ||
|
|
@@ -130,7 +107,7 @@ image manifest based on the Content-Type returned in the HTTP response. | |
| } | ||
| }, | ||
| { | ||
| "mediaType": "application/vnd.docker.image.manifest.v2+json", | ||
| "mediaType": "application/vnd.oci.image.manifest.v1+json", | ||
| "size": 7682, | ||
| "digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270", | ||
| "platform": { | ||
|
|
@@ -147,96 +124,89 @@ image manifest based on the Content-Type returned in the HTTP response. | |
|
|
||
| # Image Manifest | ||
|
|
||
| The image manifest provides a configuration and a set of layers for a container | ||
| image. It's the direct replacement for the schema-1 manifest. | ||
| The image manifest provides a configuration and a set of layers for a container image. | ||
|
|
||
| ## *Image Manifest* Field Descriptions | ||
|
|
||
| - **`schemaVersion`** *int* | ||
| This field specifies the image manifest schema version as an integer. This | ||
| schema uses version `2`. | ||
|
|
||
| This REQUIRED property specifies the image manifest schema version. | ||
| This schema uses version `2`. | ||
|
|
||
| - **`mediaType`** *string* | ||
|
|
||
| The MIME type of the manifest. This should be set to | ||
| `application/vnd.docker.distribution.manifest.v2+json`. | ||
| This REQUIRED property contains the MIME type of the image manifest. | ||
| For this version of the specification, this MUST be set to `application/vnd.oci.image.manifest.v1+json`. | ||
|
|
||
| - **`config`** *object* | ||
|
|
||
| The config field references a configuration object for a container, by | ||
| digest. This configuration item is a JSON blob that the runtime uses | ||
| to set up the container. This new schema uses a tweaked version | ||
| of this configuration to allow image content-addressability on the | ||
| daemon side. | ||
| The config field references a configuration object for a container, by digest. | ||
| This configuration item is a JSON blob that the runtime uses to set up the container. | ||
| This new schema uses a tweaked version of this configuration to allow image content-addressability on the daemon side. | ||
|
|
||
| Fields of a config object are: | ||
|
|
||
| - **`mediaType`** *string* | ||
| The MIME type of the referenced object. This should generally be | ||
| `application/vnd.docker.container.image.v1+json`. | ||
|
|
||
| This REQUIRED property contains the MIME type of the referenced object. | ||
| (i.e. `application/vnd.oci.image.serialization.v1+json`) | ||
|
|
||
| - **`size`** *int* | ||
|
|
||
| The size in bytes of the object. This field exists so that a client | ||
| will have an expected size for the content before validating. If the | ||
| length of the retrieved content does not match the specified length, | ||
| the content should not be trusted. | ||
|
|
||
|
|
||
| This REQUIRED property specifies the size in bytes of the object. | ||
| This field exists so that a client will have an expected size for the content before validating. | ||
| If the length of the retrieved content does not match the specified length, the content should not be trusted. | ||
|
|
||
| - **`digest`** *string* | ||
|
|
||
| The digest of the content, as defined by the | ||
| [Registry V2 HTTP API Specificiation](https://docs.docker.com/registry/spec/api/#digest-parameter). | ||
| The digest of the content, as defined by the [Registry V2 HTTP API Specificiation](https://docs.docker.com/registry/spec/api/#digest-parameter). | ||
|
|
||
| - **`layers`** *array* | ||
|
|
||
| The layer list is ordered starting from the base image (opposite order of schema1). | ||
|
|
||
| Fields of an item in the layers list are: | ||
|
|
||
| - **`mediaType`** *string* | ||
| The MIME type of the referenced object. This should | ||
| generally be `application/vnd.docker.image.rootfs.diff.tar.gzip`. | ||
|
|
||
| This REQUIRED property contains the MIME type of the referenced object. | ||
| (i.e. `application/vnd.oci.image.rootfs.tar.gzip`) | ||
|
|
||
| - **`size`** *int* | ||
|
|
||
| The size in bytes of the object. This field exists so that a client | ||
| will have an expected size for the content before validating. If the | ||
| length of the retrieved content does not match the specified length, | ||
| the content should not be trusted. | ||
|
|
||
|
|
||
| This REQUIRED property specifies the size in bytes of the object. | ||
| This field exists so that a client will have an expected size for the content before validating. | ||
| If the length of the retrieved content does not match the specified length, the content should not be trusted. | ||
|
|
||
| - **`digest`** *string* | ||
|
|
||
| The digest of the content, as defined by the | ||
| [Registry V2 HTTP API Specificiation](https://docs.docker.com/registry/spec/api/#digest-parameter). | ||
| The digest of the content, as defined by the [Registry V2 HTTP API Specificiation](https://docs.docker.com/registry/spec/api/#digest-parameter). | ||
|
|
||
| ## Example Image Manifest | ||
|
|
||
| *Example showing an image manifest:* | ||
| ```json | ||
| { | ||
| "schemaVersion": 2, | ||
| "mediaType": "application/vnd.docker.distribution.manifest.v2+json", | ||
| "mediaType": "application/vnd.oci.image.manifest.v1+json", | ||
| "config": { | ||
| "mediaType": "application/vnd.docker.container.image.v1+json", | ||
| "mediaType": "application/vnd.oci.image.serialization.v1+json", | ||
| "size": 7023, | ||
| "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" | ||
| }, | ||
| "layers": [ | ||
| { | ||
| "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", | ||
| "mediaType": "application/vnd.oci.image.rootfs.tar.gzip", | ||
| "size": 32654, | ||
| "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f" | ||
| }, | ||
| { | ||
| "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", | ||
| "mediaType": "application/vnd.oci.image.rootfs.tar.gzip", | ||
| "size": 16724, | ||
| "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b" | ||
| }, | ||
| { | ||
| "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", | ||
| "mediaType": "application/vnd.oci.image.rootfs.tar.gzip", | ||
| "size": 73109, | ||
| "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736" | ||
| } | ||
|
|
@@ -246,39 +216,22 @@ image. It's the direct replacement for the schema-1 manifest. | |
|
|
||
| # Backward compatibility | ||
|
|
||
| The registry will continue to accept uploads of manifests in both the old and | ||
| new formats. | ||
|
|
||
| When pushing images, clients which support the new manifest format should first | ||
| construct a manifest in the new format. If uploading this manifest fails, | ||
| presumably because the registry only supports the old format, the client may | ||
| fall back to uploading a manifest in the old format. | ||
|
|
||
| When pulling images, clients indicate support for this new version of the | ||
| manifest format by sending the | ||
| `application/vnd.docker.distribution.manifest.v2+json` and | ||
| `application/vnd.docker.distribution.manifest.list.v2+json` media types in an | ||
| `Accept` header when making a request to the `manifests` endpoint. Updated | ||
| clients should check the `Content-Type` header to see whether the manifest | ||
| returned from the endpoint is in the old format, or is an image manifest or | ||
| manifest list in the new format. | ||
|
|
||
| If the manifest being requested uses the new format, and the appropriate media | ||
| type is not present in an `Accept` header, the registry will assume that the | ||
| client cannot handle the manifest as-is, and rewrite it on the fly into the old | ||
| format. If the object that would otherwise be returned is a manifest list, the | ||
| registry will look up the appropriate manifest for the amd64 platform and | ||
| linux OS, rewrite that manifest into the old format if necessary, and return | ||
| the result to the client. If no suitable manifest is found in the manifest | ||
| list, the registry will return a 404 error. | ||
|
|
||
| One of the challenges in rewriting manifests to the old format is that the old | ||
| format involves an image configuration for each layer in the manifest, but the | ||
| new format only provides one image configuration. To work around this, the | ||
| registry will create synthetic image configurations for all layers except the | ||
| top layer. These image configurations will not result in runnable images on | ||
| their own, but only serve to fill in the parent chain in a compatible way. | ||
| The IDs in these synthetic configurations will be derived from hashes of their | ||
| respective blobs. The registry will create these configurations and their IDs | ||
| using the same scheme as Docker 1.10 when it creates a legacy manifest to push | ||
| to a registry which doesn't support the new format. | ||
| The registry will continue to accept uploads of manifests in both the old and new formats. | ||
|
Contributor
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 some thought, we may need to word this in a way that doesn't assume the existence of a registry. We can use the The behavior here is going to be very important to ensure we have a specification that is beneficial to the community of users. Part of the problem here is that content-addressability (content security, really), needs to be balanced against backwards compatibility and usability.
Contributor
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.
Contributor
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. We really need to add distribution-agnostic fallback. A mimetype table and optional distribution layer aren't really sufficient for describing fallback that will work across transports. Otherwise, we risk losing compatibility across transports. Perhaps, this section should describe the structure of the table.
Contributor
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. @stevvooe It is a bit hard to design with a strawman of "distribution-agnostic". Do you have a concrete example?
Contributor
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. I'm not sure if "distribution-agnostic" or "transport-agnostic" is a "strawman". It simply means to describe mediatype fallback outside of the context of http, which may refer to Another issue is expressing a fallback precedence. For example, one might declare they can handle
Contributor
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. Do you have an example transport in mind? I am confused what you are trying to ask for here. Perhaps we can move it to a separate issue? Do you just want language like what is in the HTTP spec about quality factors?
Contributor
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. This section discusses fallback in the context of http. Let's remove the transport-specific items and describe what was here generically. I'm really confused as to why this is an unreasonable request for this stage of the specification process. If you believe this is outside the scope of this PR, we can file a separate issue, but let's make sure it is followed up. |
||
|
|
||
| When pushing images, clients which support the new manifest format should first construct a manifest in the new format. | ||
| If uploading this manifest fails, presumably because the registry only supports the old format, the client may fall back to uploading a manifest in the old format. | ||
|
|
||
| When pulling images, clients indicate support for this new version of the manifest format by sending the | ||
| `application/vnd.oci.image.manifest.v1+json` and | ||
| `application/vnd.oci.image.manifest.list.v1+json` media types in an `Accept` header when making a request to the `manifests` endpoint. | ||
| Updated clients should check the `Content-Type` header to see whether the manifest returned from the endpoint is in the old format, or is an image manifest or manifest list in the new format. | ||
|
|
||
| If the manifest being requested uses the new format, and the appropriate media type is not present in an `Accept` header, the registry will assume that the client cannot handle the manifest as-is, and rewrite it on the fly into the old format. | ||
| If the object that would otherwise be returned is a manifest list, the registry will look up the appropriate manifest for the amd64 platform and linux OS, rewrite that manifest into the old format if necessary, and return the result to the client. | ||
| If no suitable manifest is found in the manifest list, the registry will return a 404 error. | ||
|
|
||
| One of the challenges in rewriting manifests to the old format is that the old format involves an image configuration for each layer in the manifest, but the new format only provides one image configuration. | ||
| To work around this, the registry will create synthetic image configurations for all layers except the top layer. | ||
| These image configurations will not result in runnable images on their own, but only serve to fill in the parent chain in a compatible way. | ||
| The IDs in these synthetic configurations will be derived from hashes of their respective blobs. | ||
| The registry will create these configurations and their IDs using the same scheme as Docker 1.10 when it creates a legacy manifest to push to a registry which doesn't support the new format. | ||
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.
We can deprecate the term "fat manifest". I'm not sure if it helps the understanding here.