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
|
@ -16,6 +16,7 @@ from data.registry_model import registry_model
|
|||
from endpoints.decorators import anon_protect, anon_allowed, route_show_if, parse_repository_name
|
||||
from endpoints.v2.blob import BLOB_DIGEST_ROUTE
|
||||
from image.appc import AppCImageFormatter
|
||||
from image.docker import ManifestException
|
||||
from image.docker.squashed import SquashedDockerImageFormatter
|
||||
from storage import Storage
|
||||
from util.audit import track_and_log, wrap_repository
|
||||
|
@ -42,7 +43,7 @@ class VerbReporter(TarLayerFormatterReporter):
|
|||
metric_queue.verb_action_passes.Inc(labelvalues=[self.kind, pass_count])
|
||||
|
||||
|
||||
def _open_stream(formatter, tag, manifest, derived_image_id, handlers, reporter):
|
||||
def _open_stream(formatter, tag, manifest, schema1_manifest, derived_image_id, handlers, reporter):
|
||||
"""
|
||||
This method generates a stream of data which will be replicated and read from the queue files.
|
||||
This method runs in a separate process.
|
||||
|
@ -68,7 +69,7 @@ def _open_stream(formatter, tag, manifest, derived_image_id, handlers, reporter)
|
|||
for layer in reversed(layers):
|
||||
yield image_stream_getter(store, layer.blob)
|
||||
|
||||
stream = formatter.build_stream(tag, manifest, derived_image_id, layers,
|
||||
stream = formatter.build_stream(tag, schema1_manifest, derived_image_id, layers,
|
||||
tar_stream_getter_iterator, reporter=reporter)
|
||||
|
||||
for handler_fn in handlers:
|
||||
|
@ -220,9 +221,21 @@ def _verify_repo_verb(_, namespace, repo_name, tag_name, verb, checker=None):
|
|||
logger.debug('Could not get manifest on %s/%s:%s::%s', namespace, repo_name, tag.name, verb)
|
||||
abort(404)
|
||||
|
||||
# Ensure the manifest is not a list.
|
||||
try:
|
||||
schema1_manifest = registry_model.get_schema1_parsed_manifest(manifest, namespace,
|
||||
repo_name, tag.name,
|
||||
storage)
|
||||
except ManifestException:
|
||||
logger.exception('Could not get manifest on %s/%s:%s::%s', namespace, repo_name, tag.name, verb)
|
||||
abort(400)
|
||||
|
||||
if schema1_manifest is None:
|
||||
abort(404)
|
||||
|
||||
# If there is a data checker, call it first.
|
||||
if checker is not None:
|
||||
if not checker(tag, manifest):
|
||||
if not checker(tag, schema1_manifest):
|
||||
logger.debug('Check mismatch on %s/%s:%s, verb %s', namespace, repo_name, tag.name, verb)
|
||||
abort(404)
|
||||
|
||||
|
@ -230,12 +243,12 @@ def _verify_repo_verb(_, namespace, repo_name, tag_name, verb, checker=None):
|
|||
assert tag.repository.namespace_name
|
||||
assert tag.repository.name
|
||||
|
||||
return tag, manifest
|
||||
return tag, manifest, schema1_manifest
|
||||
|
||||
|
||||
def _repo_verb_signature(namespace, repository, tag_name, verb, checker=None, **kwargs):
|
||||
# Verify that the tag exists and that we have access to it.
|
||||
tag, manifest = _verify_repo_verb(storage, namespace, repository, tag_name, verb, checker)
|
||||
tag, manifest, _ = _verify_repo_verb(storage, namespace, repository, tag_name, verb, checker)
|
||||
|
||||
# Find the derived image storage for the verb.
|
||||
derived_image = registry_model.lookup_derived_image(manifest, verb,
|
||||
|
@ -261,7 +274,8 @@ def _repo_verb(namespace, repository, tag_name, verb, formatter, sign=False, che
|
|||
# Verify that the image exists and that we have access to it.
|
||||
logger.debug('Verifying repo verb %s for repository %s/%s with user %s with mimetype %s',
|
||||
verb, namespace, repository, get_authenticated_user(), request.accept_mimetypes.best)
|
||||
tag, manifest = _verify_repo_verb(storage, namespace, repository, tag_name, verb, checker)
|
||||
tag, manifest, schema1_manifest = _verify_repo_verb(storage, namespace, repository,
|
||||
tag_name, verb, checker)
|
||||
|
||||
# Load the repository for later.
|
||||
repo = model.repository.get_repository(namespace, repository)
|
||||
|
@ -323,7 +337,7 @@ def _repo_verb(namespace, repository, tag_name, verb, formatter, sign=False, che
|
|||
# and send the results to the client and storage.
|
||||
handlers = [hasher.update]
|
||||
reporter = VerbReporter(verb)
|
||||
args = (formatter, tag, manifest, derived_image.unique_id, handlers, reporter)
|
||||
args = (formatter, tag, manifest, schema1_manifest, derived_image.unique_id, handlers, reporter)
|
||||
queue_process = QueueProcess(
|
||||
_open_stream,
|
||||
8 * 1024,
|
||||
|
@ -360,7 +374,7 @@ def _repo_verb(namespace, repository, tag_name, verb, formatter, sign=False, che
|
|||
def os_arch_checker(os, arch):
|
||||
def checker(tag, manifest):
|
||||
try:
|
||||
image_json = json.loads(manifest.get_parsed_manifest().leaf_layer.raw_v1_metadata)
|
||||
image_json = json.loads(manifest.leaf_layer.raw_v1_metadata)
|
||||
except ValueError:
|
||||
logger.exception('Could not parse leaf layer JSON for manifest %s', manifest)
|
||||
return False
|
||||
|
|
Reference in a new issue