def parse_manifest_from_bytes(manifest_bytes, media_type, validate=True): """ Parses and returns a manifest from the given bytes, for the given media type. Raises a ManifestException if the parse fails for some reason. """ assert isinstance(manifest_bytes, Bytes) if media_type == DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE: return DockerSchema2Manifest(manifest_bytes) if media_type == DOCKER_SCHEMA2_MANIFESTLIST_CONTENT_TYPE: return DockerSchema2ManifestList(manifest_bytes) if media_type == OCI_IMAGE_MANIFEST_CONTENT_TYPE: return OCIManifest(manifest_bytes) if media_type == OCI_IMAGE_INDEX_CONTENT_TYPE: return OCIIndex(manifest_bytes) if media_type in DOCKER_SCHEMA1_CONTENT_TYPES: return DockerSchema1Manifest(manifest_bytes, validate=validate) raise ManifestException("Unknown or unsupported manifest media type `%s`" % media_type)
def test_builder(): existing = DockerSchema2ManifestList(Bytes.for_string_or_unicode(MANIFESTLIST_BYTES)) builder = DockerSchema2ManifestListBuilder() for index, manifest in enumerate(existing.manifests(retriever)): builder.add_manifest(manifest.manifest_obj, "amd64", "os") built = builder.build() assert len(built.manifests(retriever)) == 2
def test_get_schema1_manifest_no_matching_list(): manifestlist = DockerSchema2ManifestList(Bytes.for_string_or_unicode(NO_AMD_MANIFESTLIST_BYTES)) assert len(manifestlist.manifests(retriever)) == 1 assert manifestlist.media_type == "application/vnd.docker.distribution.manifest.list.v2+json" assert manifestlist.bytes.as_encoded_str() == NO_AMD_MANIFESTLIST_BYTES compatible_manifest = manifestlist.get_schema1_manifest("foo", "bar", "baz", retriever) assert compatible_manifest is None
def test_valid_manifestlist(): manifestlist = DockerSchema2ManifestList(Bytes.for_string_or_unicode(MANIFESTLIST_BYTES)) assert len(manifestlist.manifests(retriever)) == 2 assert manifestlist.media_type == "application/vnd.docker.distribution.manifest.list.v2+json" assert manifestlist.bytes.as_encoded_str() == MANIFESTLIST_BYTES assert manifestlist.manifest_dict == json.loads(MANIFESTLIST_BYTES) assert manifestlist.get_layers(retriever) is None assert manifestlist.config_media_type is None assert manifestlist.layers_compressed_size is None assert not manifestlist.blob_digests for index, manifest in enumerate(manifestlist.manifests(retriever)): if index == 0: assert isinstance(manifest.manifest_obj, DockerSchema2Manifest) assert manifest.manifest_obj.schema_version == 2 else: assert isinstance(manifest.manifest_obj, DockerSchema1Manifest) assert manifest.manifest_obj.schema_version == 1 # Check retrieval of a schema 2 manifest. This should return None, because the schema 2 manifest # is not amd64-compatible. schema2_manifest = manifestlist.convert_manifest( [DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE], "foo", "bar", "baz", retriever ) assert schema2_manifest is None # Check retrieval of a schema 1 manifest. compatible_manifest = manifestlist.get_schema1_manifest("foo", "bar", "baz", retriever) assert compatible_manifest.schema_version == 1 schema1_manifest = manifestlist.convert_manifest( DOCKER_SCHEMA1_CONTENT_TYPES, "foo", "bar", "baz", retriever ) assert schema1_manifest.schema_version == 1 assert schema1_manifest.digest == compatible_manifest.digest # Ensure it validates. manifestlist.validate(retriever) assert manifestlist.amd64_linux_manifest_digest == "sha256:5b"
def test_malformed_manifest_lists(json_data): with pytest.raises(MalformedSchema2ManifestList): DockerSchema2ManifestList(Bytes.for_string_or_unicode(json_data))