Fixes to ensuring existing code can process schema 2 manifests
This commit is contained in:
parent
9474fb7833
commit
7b9f56eff3
10 changed files with 91 additions and 21 deletions
|
@ -282,7 +282,7 @@ class RegistryDataInterface(object):
|
|||
"""
|
||||
Mounts the blob from another repository into the specified target repository, and adds an
|
||||
expiration before that blob is automatically GCed. This function is useful during push
|
||||
operations if an existing blob from another repositroy is being pushed. Returns False if
|
||||
operations if an existing blob from another repository is being pushed. Returns False if
|
||||
the mounting fails. Note that this function does *not* check security for mounting the blob
|
||||
and the caller is responsible for doing this check (an example can be found in
|
||||
endpoints/v2/blob.py).
|
||||
|
@ -293,3 +293,7 @@ class RegistryDataInterface(object):
|
|||
"""
|
||||
Sets the expiration on all tags that point to the given manifest to that specified.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def get_schema1_parsed_manifest(self, manifest, namespace_name, repo_name, tag_name, storage):
|
||||
""" Returns the schema 1 version of this manifest, or None if none. """
|
||||
|
|
|
@ -8,9 +8,11 @@ from data import model
|
|||
from data.model import oci, DataModelException
|
||||
from data.database import db_transaction, Image
|
||||
from data.registry_model.interface import RegistryDataInterface
|
||||
from data.registry_model.datatypes import Tag, Manifest, LegacyImage, Label, SecurityScanStatus
|
||||
from data.registry_model.datatypes import (Tag, Manifest, LegacyImage, Label, SecurityScanStatus,
|
||||
RepositoryReference)
|
||||
from data.registry_model.shared import SharedModel
|
||||
from data.registry_model.label_handlers import apply_label_to_manifest
|
||||
from image.docker import ManifestException
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -420,5 +422,27 @@ class OCIModel(SharedModel, RegistryDataInterface):
|
|||
"""
|
||||
oci.tag.set_tag_expiration_sec_for_manifest(manifest._db_id, expiration_sec)
|
||||
|
||||
def get_schema1_parsed_manifest(self, manifest, namespace_name, repo_name, tag_name, storage):
|
||||
""" Returns the schema 1 manifest for this manifest, or None if none. """
|
||||
try:
|
||||
parsed = manifest.get_parsed_manifest()
|
||||
except ManifestException:
|
||||
return None
|
||||
|
||||
try:
|
||||
manifest_row = database.Manifest.get(id=manifest._db_id)
|
||||
except database.Manifest.DoesNotExist:
|
||||
return None
|
||||
|
||||
repository_ref = RepositoryReference.for_id(manifest_row.repository_id)
|
||||
|
||||
def _lookup_blob(digest):
|
||||
blob = self.get_repo_blob_by_digest(repository_ref, digest, include_placements=True)
|
||||
if blob is None:
|
||||
return None
|
||||
|
||||
return storage.get_content(blob.placements, blob.storage_path)
|
||||
|
||||
return parsed.get_v1_compatible_manifest(namespace_name, repo_name, tag_name, _lookup_blob)
|
||||
|
||||
oci_model = OCIModel()
|
||||
|
|
|
@ -527,4 +527,12 @@ class PreOCIModel(SharedModel, RegistryDataInterface):
|
|||
|
||||
model.tag.set_tag_expiration_for_manifest(tag_manifest, expiration_sec)
|
||||
|
||||
def get_schema1_parsed_manifest(self, manifest, namespace_name, repo_name, tag_name, storage):
|
||||
""" Returns the schema 1 version of this manifest, or None if none. """
|
||||
try:
|
||||
return manifest.get_parsed_manifest()
|
||||
except ManifestException:
|
||||
return None
|
||||
|
||||
|
||||
pre_oci_model = PreOCIModel()
|
||||
|
|
|
@ -317,7 +317,8 @@ class SharedModel:
|
|||
logger.exception('Could not parse and validate manifest `%s`', manifest._db_id)
|
||||
return None
|
||||
|
||||
blob_query = model.storage.lookup_repo_storages_by_content_checksum(repo_id, parsed.checksums)
|
||||
blob_query = model.storage.lookup_repo_storages_by_content_checksum(repo_id,
|
||||
parsed.blob_digests)
|
||||
storage_map = {blob.content_checksum: blob for blob in blob_query}
|
||||
|
||||
manifest_layers = []
|
||||
|
|
|
@ -95,6 +95,9 @@ def test_lookup_manifests(repo_namespace, repo_name, registry_model):
|
|||
assert found.legacy_image
|
||||
assert found.legacy_image.parents
|
||||
|
||||
schema1_parsed = registry_model.get_schema1_parsed_manifest(found, 'foo', 'bar', 'baz', storage)
|
||||
assert schema1_parsed is not None
|
||||
|
||||
|
||||
def test_lookup_unknown_manifest(registry_model):
|
||||
repo = model.repository.get_repository('devtable', 'simple')
|
||||
|
|
Reference in a new issue