Add method for retrieving a V1-compatible manifest for any manifest or manifest list

This is used to serve older clients that don't support the V2 schema format
This commit is contained in:
Joseph Schorr 2018-11-13 10:40:57 +02:00
parent d77d383e46
commit 1b3daac3c3
7 changed files with 119 additions and 7 deletions

View file

@ -50,6 +50,22 @@ MANIFESTLIST_BYTES = json.dumps({
]
})
NO_AMD_MANIFESTLIST_BYTES = json.dumps({
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 983,
"digest": "sha256:e6",
"platform": {
"architecture": "ppc64le",
"os": "linux",
}
},
]
})
def test_valid_manifestlist():
def _get_manifest(digest):
if digest == 'sha256:e6':
@ -75,13 +91,33 @@ def test_valid_manifestlist():
assert isinstance(manifest.manifest_obj, DockerSchema1Manifest)
assert manifest.manifest_obj.schema_version == 1
assert manifestlist.get_v1_compatible_manifest(_get_manifest).manifest_obj.schema_version == 1
compatible_manifest = manifestlist.get_v1_compatible_manifest('foo', 'bar', 'baz', _get_manifest)
assert compatible_manifest.schema_version == 1
assert manifestlist.layers is None
assert manifestlist.leaf_layer_v1_image_id is None
assert manifestlist.legacy_image_ids is None
def test_get_v1_compatible_manifest_no_matching_list():
def _get_manifest(digest):
if digest == 'sha256:e6':
return v22_bytes
else:
return v21_bytes
manifestlist = DockerSchema2ManifestList(NO_AMD_MANIFESTLIST_BYTES)
assert len(manifestlist.manifests(_get_manifest)) == 1
assert (manifestlist.digest ==
'sha256:50150251101420a020ab4a3e77e9d167a18b09bd4eeb0cc65e0eafab95cf79cf')
assert manifestlist.media_type == 'application/vnd.docker.distribution.manifest.list.v2+json'
assert manifestlist.bytes == NO_AMD_MANIFESTLIST_BYTES
compatible_manifest = manifestlist.get_v1_compatible_manifest('foo', 'bar', 'baz', _get_manifest)
assert compatible_manifest is None
def test_builder():
def _get_manifest(digest):
if digest == 'sha256:e6':

View file

@ -3,7 +3,8 @@ import pytest
from app import docker_v2_signing_key
from image.docker.schema1 import (DockerSchema1ManifestBuilder,
DOCKER_SCHEMA1_SIGNED_MANIFEST_CONTENT_TYPE)
DOCKER_SCHEMA1_SIGNED_MANIFEST_CONTENT_TYPE,
DOCKER_SCHEMA1_MANIFEST_CONTENT_TYPE)
from image.docker.schema2.manifest import (MalformedSchema2Manifest, DockerSchema2Manifest,
DockerSchema2ManifestBuilder)
from image.docker.schema2.test.test_config import CONFIG_BYTES
@ -132,6 +133,44 @@ def test_build_schema1():
assert digest == str(list(manifest.blob_digests)[index])
def test_get_v1_compatible_manifest():
def _get_config(digest):
config_str = json.dumps({
"config": {
"Labels": {},
},
"rootfs": {"type": "layers", "diff_ids": []},
"history": [
{
"created": "2018-04-03T18:37:09.284840891Z",
"created_by": "foo"
},
{
"created": "2018-04-12T18:37:09.284840891Z",
"created_by": "bar"
},
{
"created": "2018-04-03T18:37:09.284840891Z",
"created_by": "foo"
},
{
"created": "2018-04-12T18:37:09.284840891Z",
"created_by": "bar"
},
],
})
return config_str + ' ' * (1885 - len(config_str))
manifest = DockerSchema2Manifest(MANIFEST_BYTES)
schema1 = manifest.get_v1_compatible_manifest('somenamespace', 'somename', 'sometag', _get_config)
assert schema1 is not None
assert schema1.media_type == DOCKER_SCHEMA1_MANIFEST_CONTENT_TYPE
assert len(schema1.layers) == len(manifest.layers)
assert set(schema1.image_ids) == set([l.v1_id for l in manifest.layers_with_v1_ids])
assert set(schema1.parent_image_ids) == set([l.v1_parent_id for l in
manifest.layers_with_v1_ids if l.v1_parent_id])
def test_generate_legacy_layers():
builder = DockerSchema2ManifestBuilder()
builder.add_layer('sha256:abc123', 123)