Support pulling of schema2 manifests directly via a manifest list tag
This change ensures that if a manifest list is requested with an accepts header for a *schema 2* manifest, the legacy manifest (if any) is returned as schema 2 if it was pushed as a schema 2 manifest (rather than being auto-converted to schema 1)
This commit is contained in:
parent
a35982f2be
commit
3c2e050593
14 changed files with 215 additions and 15 deletions
|
@ -322,3 +322,10 @@ class RegistryDataInterface(object):
|
|||
""" Returns a cached set of ISO country codes blacklisted for pulls for the namespace
|
||||
or None if the list could not be loaded.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def convert_manifest(self, manifest, namespace_name, repo_name, tag_name, allowed_mediatypes,
|
||||
storage):
|
||||
""" Attempts to convert the specified into a parsed manifest with a media type
|
||||
in the allowed_mediatypes set. If not possible, or an error occurs, returns None.
|
||||
"""
|
||||
|
|
|
@ -482,6 +482,22 @@ class OCIModel(SharedModel, RegistryDataInterface):
|
|||
retriever = RepositoryContentRetriever(manifest_row.repository_id, storage)
|
||||
return parsed.get_schema1_manifest(namespace_name, repo_name, tag_name, retriever)
|
||||
|
||||
def convert_manifest(self, manifest, namespace_name, repo_name, tag_name, allowed_mediatypes,
|
||||
storage):
|
||||
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
|
||||
|
||||
retriever = RepositoryContentRetriever(manifest_row.repository_id, storage)
|
||||
return parsed.convert_manifest(allowed_mediatypes, namespace_name, repo_name, tag_name,
|
||||
retriever)
|
||||
|
||||
def create_manifest_with_temp_tag(self, repository_ref, manifest_interface_instance,
|
||||
expiration_sec, storage):
|
||||
""" Creates a manifest under the repository and sets a temporary tag to point to it.
|
||||
|
|
|
@ -549,6 +549,18 @@ class PreOCIModel(SharedModel, RegistryDataInterface):
|
|||
except ManifestException:
|
||||
return None
|
||||
|
||||
def convert_manifest(self, manifest, namespace_name, repo_name, tag_name, allowed_mediatypes,
|
||||
storage):
|
||||
try:
|
||||
parsed = manifest.get_parsed_manifest()
|
||||
except ManifestException:
|
||||
return None
|
||||
|
||||
try:
|
||||
return parsed.convert_manifest(allowed_mediatypes, namespace_name, repo_name, tag_name, None)
|
||||
except ManifestException:
|
||||
return None
|
||||
|
||||
def create_manifest_with_temp_tag(self, repository_ref, manifest_interface_instance,
|
||||
expiration_sec, storage):
|
||||
""" Creates a manifest under the repository and sets a temporary tag to point to it.
|
||||
|
|
|
@ -23,7 +23,7 @@ from data.registry_model.datatypes import RepositoryReference
|
|||
from data.registry_model.blobuploader import upload_blob, BlobUploadSettings
|
||||
from data.registry_model.modelsplitter import SplitModel
|
||||
from image.docker.types import ManifestImageLayer
|
||||
from image.docker.schema1 import DockerSchema1ManifestBuilder
|
||||
from image.docker.schema1 import DockerSchema1ManifestBuilder, DOCKER_SCHEMA1_CONTENT_TYPES
|
||||
from image.docker.schema2.manifest import DockerSchema2ManifestBuilder
|
||||
|
||||
from test.fixtures import *
|
||||
|
@ -780,6 +780,18 @@ def test_get_schema1_parsed_manifest(registry_model):
|
|||
assert registry_model.get_schema1_parsed_manifest(manifest, '', '', '', storage)
|
||||
|
||||
|
||||
def test_convert_manifest(registry_model):
|
||||
repository_ref = registry_model.lookup_repository('devtable', 'simple')
|
||||
latest_tag = registry_model.get_repo_tag(repository_ref, 'latest', include_legacy_image=True)
|
||||
manifest = registry_model.get_manifest_for_tag(latest_tag)
|
||||
|
||||
mediatypes = DOCKER_SCHEMA1_CONTENT_TYPES
|
||||
assert registry_model.convert_manifest(manifest, '', '', '', mediatypes, storage)
|
||||
|
||||
mediatypes = []
|
||||
assert registry_model.convert_manifest(manifest, '', '', '', mediatypes, storage) is None
|
||||
|
||||
|
||||
def test_create_manifest_and_retarget_tag_with_labels(registry_model):
|
||||
repository_ref = registry_model.lookup_repository('devtable', 'simple')
|
||||
latest_tag = registry_model.get_repo_tag(repository_ref, 'latest', include_legacy_image=True)
|
||||
|
|
Reference in a new issue