Inconsistent media type handling during manifest pushes
Context
While working on a workaround for #407 (closed), I realized that the way we're handling media types during manifest pushes is inconsistent and misleading.
Problem
-
We've deprecated and removed support for schema 1 manifests a while ago, but we're still defaulting to the schema 1 parser when no
Content-Typemedia type is provided, which leads to obscure and misleadingmissing signature keyerrors; -
There is no consistency in error messages for all possible combinations of payload and
Content-Typemedia types. In !712 (merged), we have introduced a series of tests to cover this part of the API functionality. We should now review the current behavior and decide how we want to proceed.
Current behavior
For brevity, we will refer to the following media types in this table:
-
schema2:application/vnd.docker.distribution.manifest.v2+json -
oci:application/vnd.oci.image.manifest.v1+json -
unknown:application/vnd.foo.manifest.v1+json
| Payload (manifest JSON) media type |
Content-Type request header media type |
Status code | Error detail | Notes |
|---|---|---|---|---|
schema2 |
schema2 |
201 Created |
N.A. | |
schema2 |
400 Bad Request |
missing signature key |
Defaults to schema 1 parser. | |
schema2 |
400 Bad Request |
mediaType in manifest should be 'schema2' not '' |
||
oci |
oci |
201 Created |
N.A. | |
oci |
400 Bad Request |
missing signature key |
Defaults to schema 1 parser. | |
oci |
201 Created |
N.A. | ||
400 Bad Request |
missing signature key |
Defaults to schema 1 parser. | ||
schema2 |
oci |
400 Bad Request |
if present, mediaType in manifest should be 'oci' not 'schema2' | |
oci |
schema2 |
400 Bad Request |
mediaType in manifest should be 'schema2' not 'oci' |
|
unknown |
schema2 |
400 Bad Request |
mediaType in manifest should be 'schema2' not 'unknown' |
|
unknown |
oci |
400 Bad Request |
if present, mediaType in manifest should be 'oci' not 'unknown' |
|
unknown |
unknown |
400 Bad Request |
missing signature key |
Defaults to schema 1 parser. |
unknown |
400 Bad Request |
missing signature key |
Defaults to schema 1 parser. |
Proposal
We need to:
- Stop defaulting to the schema 1 parser, as we have already deprecated and removed support for schema 1 manifests;
- Choose a new default parser;
- The behavior should be consistent.
I did some tests against GCR and ECR to see how they behave with the above combination of media types and described my findings in #426 (comment 641993145) and #426 (comment 642025800), respectively. ECR behaved in a weird way, rejecting many combinations with a 401 Unauthorized response. GCR behaves similar to us, but defaults to schema 2. I think we should do the same.
Based on this, the proposal is to modify the above behavior into the following:
| Payload (manifest JSON) media type |
Content-Type request header media type |
Status code | Error detail | Notes |
|---|---|---|---|---|
schema2 |
schema2 |
201 Created |
N.A. | |
schema2 |
201 Created |
N.A. | Different status code and error detail. | |
schema2 |
400 Bad Request |
no mediaType in manifest |
Different error detail. | |
oci |
oci |
201 Created |
N.A. | |
oci |
400 Bad Request |
mediaType in manifest should be 'schema2' not 'oci' |
Different error detail. | |
oci |
201 Created |
N.A. | ||
400 Bad Request |
no mediaType in manifest |
Different error detail. | ||
schema2 |
oci |
400 Bad Request |
if present, mediaType in manifest should be 'oci' not 'schema2' | |
oci |
schema2 |
400 Bad Request |
mediaType in manifest should be 'schema2' not 'oci' |
|
unknown |
schema2 |
400 Bad Request |
mediaType in manifest should be 'schema2' not 'unknown' |
|
unknown |
oci |
400 Bad Request |
if present, mediaType in manifest should be 'oci' not 'unknown' |
|
unknown |
unknown |
400 Bad Request |
mediaType in manifest should be 'schema2' not 'unknown' |
Different error detail. |
unknown |
400 Bad Request |
mediaType in manifest should be 'schema2' not 'unknown' |
Different error detail. |
Next Steps
Once we're done with manifests, we should do a similar exercise for manifest lists/indexes.