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:
Joseph Schorr 2018-12-06 12:40:34 -05:00
parent a35982f2be
commit 3c2e050593
14 changed files with 215 additions and 15 deletions

View file

@ -20,6 +20,7 @@ from test.registry.protocols import Failures, Image, layer_bytes_for_contents, P
from app import instance_keys
from data.model.tag import list_repository_tags
from image.docker.schema1 import DOCKER_SCHEMA1_MANIFEST_CONTENT_TYPE
from image.docker.schema2 import DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE
from image.docker.schema2.list import DockerSchema2ManifestListBuilder
from image.docker.schema2.manifest import DockerSchema2ManifestBuilder
from util.security.registry_jwt import decode_bearer_header
@ -1728,3 +1729,47 @@ def test_geo_blocking(pusher, puller, basic_images, liveserver_session,
puller.pull(liveserver_session, 'devtable', 'newrepo', 'latest', basic_images,
credentials=credentials, options=options,
expected_failure=Failures.GEO_BLOCKED)
@pytest.mark.parametrize('has_amd64_linux', [
False,
True,
])
def test_pull_manifest_list_schema2_only(v22_protocol, basic_images, different_images,
liveserver_session, app_reloader, data_model,
has_amd64_linux):
""" Test: Push a new tag with a manifest list containing two manifests, one schema2 (possibly)
amd64 and one not, and pull it when only accepting a schema2 manifest type. Since the manifest
list content type is not being sent, this should return just the manifest (or none if no
linux+amd64 is present.)
"""
if data_model != 'oci_model':
return
credentials = ('devtable', 'password')
# Build the manifests that will go in the list.
options = ProtocolOptions()
blobs = {}
first_manifest = v22_protocol.build_schema2(basic_images, blobs, options)
second_manifest = v22_protocol.build_schema2(different_images, blobs, options)
# Create and push the manifest list.
builder = DockerSchema2ManifestListBuilder()
builder.add_manifest(first_manifest, 'amd64' if has_amd64_linux else 'amd32', 'linux')
builder.add_manifest(second_manifest, 'arm', 'linux')
manifestlist = builder.build()
v22_protocol.push_list(liveserver_session, 'devtable', 'newrepo', 'latest', manifestlist,
[first_manifest, second_manifest], blobs,
credentials=credentials)
# Pull and verify the manifest.
options.accept_mimetypes = [DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE]
result = v22_protocol.pull(liveserver_session, 'devtable', 'newrepo', 'latest', basic_images,
credentials=credentials, options=options,
expected_failure=None if has_amd64_linux else Failures.UNKNOWN_TAG)
if has_amd64_linux:
assert result.manifests['latest'].media_type == DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE