Fix manifest UI display for manifests with empty layers
Also fixes the command for schema 2 manifests
This commit is contained in:
parent
4106f5ce51
commit
7fa60d5802
2 changed files with 22 additions and 4 deletions
|
@ -12,6 +12,7 @@ from data.registry_model.datatype import FromDictionaryException
|
||||||
from data.registry_model.datatypes import (RepositoryReference, Blob, TorrentInfo, BlobUpload,
|
from data.registry_model.datatypes import (RepositoryReference, Blob, TorrentInfo, BlobUpload,
|
||||||
LegacyImage, ManifestLayer, DerivedImage)
|
LegacyImage, ManifestLayer, DerivedImage)
|
||||||
from image.docker.schema1 import ManifestException, DockerSchema1ManifestBuilder
|
from image.docker.schema1 import ManifestException, DockerSchema1ManifestBuilder
|
||||||
|
from image.docker.schema2 import EMPTY_LAYER_BLOB_DIGEST
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -344,14 +345,21 @@ class SharedModel:
|
||||||
working towards the leaf, including the associated Blob and its placements (if specified).
|
working towards the leaf, including the associated Blob and its placements (if specified).
|
||||||
Returns None if the manifest could not be parsed and validated.
|
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 = {}
|
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,
|
blob_query = model.storage.lookup_repo_storages_by_content_checksum(repo_id,
|
||||||
parsed.local_blob_digests,
|
blob_digests,
|
||||||
by_manifest=by_manifest)
|
by_manifest=by_manifest)
|
||||||
storage_map = {blob.content_checksum: blob for blob in blob_query}
|
storage_map = {blob.content_checksum: blob for blob in blob_query}
|
||||||
|
|
||||||
retriever = RepositoryContentRetriever(repo_id, storage)
|
|
||||||
layers = parsed.get_layers(retriever)
|
layers = parsed.get_layers(retriever)
|
||||||
if layers is None:
|
if layers is None:
|
||||||
logger.error('Could not load layers for manifest `%s`', parsed.digest)
|
logger.error('Could not load layers for manifest `%s`', parsed.digest)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
""" Manage the manifests of a repository. """
|
""" Manage the manifests of a repository. """
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
|
@ -20,6 +21,9 @@ BASE_MANIFEST_ROUTE = '/v1/repository/<apirepopath:repository>/manifest/<regex("
|
||||||
MANIFEST_DIGEST_ROUTE = BASE_MANIFEST_ROUTE.format(digest_tools.DIGEST_PATTERN)
|
MANIFEST_DIGEST_ROUTE = BASE_MANIFEST_ROUTE.format(digest_tools.DIGEST_PATTERN)
|
||||||
ALLOWED_LABEL_MEDIA_TYPES = ['text/plain', 'application/json']
|
ALLOWED_LABEL_MEDIA_TYPES = ['text/plain', 'application/json']
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def _label_dict(label):
|
def _label_dict(label):
|
||||||
return {
|
return {
|
||||||
'id': label.uuid,
|
'id': label.uuid,
|
||||||
|
@ -31,10 +35,12 @@ def _label_dict(label):
|
||||||
|
|
||||||
|
|
||||||
def _layer_dict(manifest_layer, index):
|
def _layer_dict(manifest_layer, index):
|
||||||
|
# NOTE: The `command` in the layer is either a JSON string of an array (schema 1) or
|
||||||
|
# a single string (schema 2). The block below normalizes it to have the same format.
|
||||||
try:
|
try:
|
||||||
command = json.loads(manifest_layer.command)
|
command = json.loads(manifest_layer.command)
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
command = []
|
command = [manifest_layer.command]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'index': index,
|
'index': index,
|
||||||
|
@ -53,6 +59,10 @@ def _manifest_dict(manifest):
|
||||||
image = image_dict(manifest.legacy_image, with_history=True)
|
image = image_dict(manifest.legacy_image, with_history=True)
|
||||||
|
|
||||||
layers = registry_model.list_manifest_layers(manifest, storage)
|
layers = registry_model.list_manifest_layers(manifest, storage)
|
||||||
|
if layers is None and not manifest.is_manifest_list:
|
||||||
|
logger.debug('Missing layers for manifest `%s`', manifest.digest)
|
||||||
|
abort(404)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'digest': manifest.digest,
|
'digest': manifest.digest,
|
||||||
'is_manifest_list': manifest.is_manifest_list,
|
'is_manifest_list': manifest.is_manifest_list,
|
||||||
|
|
Reference in a new issue