Fix conversion of schema 2 manifests to schema 1 manifests
Also adds a number of conversion tests and clarify the interfaces a bit more
This commit is contained in:
parent
bd79eaa38f
commit
c233760007
11 changed files with 457 additions and 183 deletions
|
|
@ -6,7 +6,7 @@ from image.docker.schema1 import (DockerSchema1ManifestBuilder,
|
|||
DOCKER_SCHEMA1_SIGNED_MANIFEST_CONTENT_TYPE,
|
||||
DOCKER_SCHEMA1_MANIFEST_CONTENT_TYPE)
|
||||
from image.docker.schema2.manifest import (MalformedSchema2Manifest, DockerSchema2Manifest,
|
||||
DockerSchema2ManifestBuilder)
|
||||
DockerSchema2ManifestBuilder, EMPTY_BLOB_DIGEST)
|
||||
from image.docker.schema2.test.test_config import CONFIG_BYTES
|
||||
from image.docker.schemautil import ContentRetrieverForTesting
|
||||
|
||||
|
|
@ -96,6 +96,7 @@ def test_valid_manifest():
|
|||
assert str(manifest.config.digest) == 'sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7'
|
||||
assert manifest.media_type == "application/vnd.docker.distribution.manifest.v2+json"
|
||||
assert not manifest.has_remote_layer
|
||||
assert manifest.has_legacy_image
|
||||
|
||||
assert len(manifest.layers) == 4
|
||||
assert manifest.layers[0].compressed_size == 1234
|
||||
|
|
@ -111,6 +112,36 @@ def test_valid_manifest():
|
|||
assert blob_digests == expected
|
||||
assert list(manifest.local_blob_digests) == expected
|
||||
|
||||
retriever = ContentRetrieverForTesting.for_config({
|
||||
"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"
|
||||
},
|
||||
],
|
||||
}, 'sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7', 1885)
|
||||
|
||||
manifest_image_layers = list(manifest._manifest_image_layers(retriever))
|
||||
assert len(manifest_image_layers) == len(list(manifest.layers))
|
||||
for index in range(0, 4):
|
||||
assert manifest_image_layers[index].blob_digest == str(manifest.layers[index].digest)
|
||||
|
||||
|
||||
def test_valid_remote_manifest():
|
||||
manifest = DockerSchema2Manifest(REMOTE_MANIFEST_BYTES)
|
||||
|
|
@ -138,8 +169,8 @@ def test_valid_remote_manifest():
|
|||
assert local_digests == (expected - {manifest.layers[0].digest})
|
||||
|
||||
assert manifest.has_remote_layer
|
||||
assert manifest.leaf_layer_v1_image_id is None
|
||||
assert manifest.legacy_image_ids is None
|
||||
assert manifest.get_leaf_layer_v1_image_id(None) is None
|
||||
assert manifest.get_legacy_image_ids(None) is None
|
||||
|
||||
|
||||
def test_schema2_builder():
|
||||
|
|
@ -179,26 +210,13 @@ def test_build_schema1():
|
|||
})
|
||||
|
||||
builder = DockerSchema1ManifestBuilder('somenamespace', 'somename', 'sometag')
|
||||
manifest.populate_schema1_builder(builder, retriever)
|
||||
manifest._populate_schema1_builder(builder, retriever)
|
||||
schema1 = builder.build(docker_v2_signing_key)
|
||||
|
||||
assert schema1.media_type == DOCKER_SCHEMA1_SIGNED_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])
|
||||
|
||||
manifest_layers = list(manifest.layers_with_v1_ids)
|
||||
for index, layer in enumerate(schema1.layers):
|
||||
assert layer.digest == manifest_layers[index].layer.digest
|
||||
assert layer.v1_metadata.image_id == manifest_layers[index].v1_id
|
||||
assert layer.v1_metadata.parent_image_id == manifest_layers[index].v1_parent_id
|
||||
|
||||
for index, digest in enumerate(schema1.blob_digests):
|
||||
assert digest == str(list(manifest.blob_digests)[index])
|
||||
|
||||
|
||||
def test_get_v1_compatible_manifest():
|
||||
def test_get_schema1_manifest():
|
||||
retriever = ContentRetrieverForTesting.for_config({
|
||||
"config": {
|
||||
"Labels": {},
|
||||
|
|
@ -225,13 +243,9 @@ def test_get_v1_compatible_manifest():
|
|||
}, 'sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7', 1885)
|
||||
|
||||
manifest = DockerSchema2Manifest(MANIFEST_BYTES)
|
||||
schema1 = manifest.get_v1_compatible_manifest('somenamespace', 'somename', 'sometag', retriever)
|
||||
schema1 = manifest.get_schema1_manifest('somenamespace', 'somename', 'sometag', retriever)
|
||||
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():
|
||||
|
|
@ -248,29 +262,39 @@ def test_generate_legacy_layers():
|
|||
"history": [
|
||||
{
|
||||
"created": "2018-04-03T18:37:09.284840891Z",
|
||||
"created_by": "foo"
|
||||
"created_by": "base"
|
||||
},
|
||||
{
|
||||
"created": "2018-04-06T18:37:09.284840891Z",
|
||||
"created_by": "middle",
|
||||
"empty_layer": True,
|
||||
},
|
||||
{
|
||||
"created": "2018-04-12T18:37:09.284840891Z",
|
||||
"created_by": "bar"
|
||||
"created_by": "leaf"
|
||||
},
|
||||
],
|
||||
}, 'sha256:def456', 2000)
|
||||
|
||||
legacy_layers = list(manifest.generate_legacy_layers({}, retriever))
|
||||
assert len(legacy_layers) == 2
|
||||
assert len(legacy_layers) == 3
|
||||
assert legacy_layers[0].content_checksum == 'sha256:abc123'
|
||||
assert legacy_layers[1].content_checksum == 'sha256:def456'
|
||||
assert legacy_layers[1].content_checksum == EMPTY_BLOB_DIGEST
|
||||
assert legacy_layers[2].content_checksum == 'sha256:def456'
|
||||
|
||||
assert legacy_layers[0].created == "2018-04-03T18:37:09.284840891Z"
|
||||
assert legacy_layers[1].created == "2018-04-12T18:37:09.284840891Z"
|
||||
assert legacy_layers[1].created == "2018-04-06T18:37:09.284840891Z"
|
||||
assert legacy_layers[2].created == "2018-04-12T18:37:09.284840891Z"
|
||||
|
||||
assert legacy_layers[0].command == '"foo"'
|
||||
assert legacy_layers[1].command == '"bar"'
|
||||
assert legacy_layers[0].command == '["base"]'
|
||||
assert legacy_layers[1].command == '["middle"]'
|
||||
assert legacy_layers[2].command == '["leaf"]'
|
||||
|
||||
assert legacy_layers[2].parent_image_id == legacy_layers[1].image_id
|
||||
assert legacy_layers[1].parent_image_id == legacy_layers[0].image_id
|
||||
assert legacy_layers[0].parent_image_id is None
|
||||
|
||||
assert legacy_layers[1].image_id != legacy_layers[2]
|
||||
assert legacy_layers[0].image_id != legacy_layers[1]
|
||||
|
||||
|
||||
|
|
@ -283,10 +307,11 @@ def test_remote_layer_manifest():
|
|||
manifest = builder.build()
|
||||
|
||||
assert manifest.has_remote_layer
|
||||
assert manifest.leaf_layer_v1_image_id is None
|
||||
assert manifest.legacy_image_ids is None
|
||||
assert manifest.get_leaf_layer_v1_image_id(None) is None
|
||||
assert manifest.get_legacy_image_ids(None) is None
|
||||
assert not manifest.has_legacy_image
|
||||
|
||||
schema1 = manifest.get_v1_compatible_manifest('somenamespace', 'somename', 'sometag', None)
|
||||
schema1 = manifest.get_schema1_manifest('somenamespace', 'somename', 'sometag', None)
|
||||
assert schema1 is None
|
||||
|
||||
assert set(manifest.blob_digests) == {'sha256:adef', 'sha256:abcd', 'sha256:1352', 'sha256:1353'}
|
||||
|
|
|
|||
Reference in a new issue