diff --git a/data/registry_model/shared.py b/data/registry_model/shared.py index 8b62d86fd..ebed550af 100644 --- a/data/registry_model/shared.py +++ b/data/registry_model/shared.py @@ -12,6 +12,7 @@ from data.registry_model.datatype import FromDictionaryException from data.registry_model.datatypes import (RepositoryReference, Blob, TorrentInfo, BlobUpload, LegacyImage, ManifestLayer, DerivedImage) from image.docker.schema1 import ManifestException, DockerSchema1ManifestBuilder +from image.docker.schema2 import EMPTY_LAYER_BLOB_DIGEST logger = logging.getLogger(__name__) @@ -344,14 +345,21 @@ class SharedModel: working towards the leaf, including the associated Blob and its placements (if specified). Returns None if the manifest could not be parsed and validated. """ + retriever = RepositoryContentRetriever(repo_id, storage) + requires_empty_blob = parsed.get_requires_empty_layer_blob(retriever) + storage_map = {} - if parsed.local_blob_digests: + blob_digests = list(parsed.local_blob_digests) + if requires_empty_blob: + blob_digests.append(EMPTY_LAYER_BLOB_DIGEST) + + if blob_digests: blob_query = model.storage.lookup_repo_storages_by_content_checksum(repo_id, - parsed.local_blob_digests, + blob_digests, by_manifest=by_manifest) storage_map = {blob.content_checksum: blob for blob in blob_query} - retriever = RepositoryContentRetriever(repo_id, storage) + layers = parsed.get_layers(retriever) if layers is None: logger.error('Could not load layers for manifest `%s`', parsed.digest) diff --git a/endpoints/api/manifest.py b/endpoints/api/manifest.py index 3183796d5..32012d4cf 100644 --- a/endpoints/api/manifest.py +++ b/endpoints/api/manifest.py @@ -1,5 +1,6 @@ """ Manage the manifests of a repository. """ import json +import logging from flask import request @@ -20,6 +21,9 @@ BASE_MANIFEST_ROUTE = '/v1/repository//manifest/