Change V1 to use the manifest builder and new registry data model
This commit is contained in:
parent
65d5be23c7
commit
4520f9e842
12 changed files with 291 additions and 689 deletions
|
@ -1,3 +1,4 @@
|
|||
import logging
|
||||
import json
|
||||
import uuid
|
||||
|
||||
|
@ -9,11 +10,11 @@ from data import model
|
|||
from data.database import db_transaction
|
||||
from data.registry_model import registry_model
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
ManifestLayer = namedtuple('ManifestLayer', ['layer_id', 'v1_metadata', 'db_id'])
|
||||
ManifestLayer = namedtuple('ManifestLayer', ['layer_id', 'v1_metadata_string', 'db_id'])
|
||||
_BuilderState = namedtuple('_BuilderState', ['builder_id', 'images', 'tags', 'checksums'])
|
||||
|
||||
|
||||
_SESSION_KEY = '__manifestbuilder'
|
||||
|
||||
|
||||
|
@ -61,7 +62,8 @@ class _ManifestBuilder(object):
|
|||
return [registry_model.get_repo_tag(self._repository_ref, tag_name, include_legacy_image=True)
|
||||
for tag_name in self._builder_state.tags.keys()]
|
||||
|
||||
def start_layer(self, layer_id, v1_metadata, location_name, calling_user, temp_tag_expiration):
|
||||
def start_layer(self, layer_id, v1_metadata_string, location_name, calling_user,
|
||||
temp_tag_expiration):
|
||||
""" Starts a new layer with the given ID to be placed into a manifest. Returns the layer
|
||||
started or None if an error occurred.
|
||||
"""
|
||||
|
@ -73,6 +75,15 @@ class _ManifestBuilder(object):
|
|||
namespace_name = repository.namespace_user.username
|
||||
repo_name = repository.name
|
||||
|
||||
try:
|
||||
v1_metadata = json.loads(v1_metadata_string)
|
||||
except ValueError:
|
||||
logger.exception('Exception when trying to parse V1 metadata JSON for layer %s', layer_id)
|
||||
return None
|
||||
except TypeError:
|
||||
logger.exception('Exception when trying to parse V1 metadata JSON for layer %s', layer_id)
|
||||
return None
|
||||
|
||||
# Sanity check that the ID matches the v1 metadata.
|
||||
if layer_id != v1_metadata['id']:
|
||||
return None
|
||||
|
@ -91,7 +102,7 @@ class _ManifestBuilder(object):
|
|||
if existing_image is not None:
|
||||
self._builder_state.images[layer_id] = existing_image.id
|
||||
self._save_to_session()
|
||||
return ManifestLayer(layer_id, v1_metadata, existing_image.id)
|
||||
return ManifestLayer(layer_id, v1_metadata_string, existing_image.id)
|
||||
|
||||
with db_transaction():
|
||||
# Otherwise, create a new legacy image and point a temporary tag at it.
|
||||
|
@ -117,7 +128,7 @@ class _ManifestBuilder(object):
|
|||
self._builder_state.images[layer_id] = created.id
|
||||
self._save_to_session()
|
||||
|
||||
return ManifestLayer(layer_id, v1_metadata, created.id)
|
||||
return ManifestLayer(layer_id, v1_metadata_string, created.id)
|
||||
|
||||
def lookup_layer(self, layer_id):
|
||||
""" Returns a layer with the given ID under this builder. If none exists, returns None. """
|
||||
|
@ -128,7 +139,7 @@ class _ManifestBuilder(object):
|
|||
if image is None:
|
||||
return None
|
||||
|
||||
return ManifestLayer(layer_id, json.loads(image.v1_json_metadata), image.id)
|
||||
return ManifestLayer(layer_id, image.v1_json_metadata, image.id)
|
||||
|
||||
def assign_layer_blob(self, layer, blob, computed_checksums):
|
||||
""" Assigns a blob to a layer. """
|
||||
|
@ -151,7 +162,18 @@ class _ManifestBuilder(object):
|
|||
def validate_layer_checksum(self, layer, checksum):
|
||||
""" Returns whether the checksum for a layer matches that specified.
|
||||
"""
|
||||
return checksum in self._builder_state.checksums.get(layer.layer_id)
|
||||
return checksum in self.get_layer_checksums(layer)
|
||||
|
||||
def get_layer_checksums(self, layer):
|
||||
""" Returns the registered defined for the layer, if any. """
|
||||
return self._builder_state.checksums.get(layer.layer_id) or []
|
||||
|
||||
def save_precomputed_checksum(self, layer, checksum):
|
||||
""" Saves a precomputed checksum for a layer. """
|
||||
checksums = self._builder_state.checksums.get(layer.layer_id) or []
|
||||
checksums.append(checksum)
|
||||
self._builder_state.checksums[layer.layer_id] = checksums
|
||||
self._save_to_session()
|
||||
|
||||
def commit_tag_and_manifest(self, tag_name, layer):
|
||||
""" Commits a new tag + manifest for that tag to the repository with the given name,
|
||||
|
@ -171,7 +193,7 @@ class _ManifestBuilder(object):
|
|||
|
||||
def done(self):
|
||||
""" Marks the manifest builder as complete and disposes of any state. This call is optional
|
||||
and it is expected manifest builders will eventually time out if unusued for an
|
||||
and it is expected manifest builders will eventually time out if unused for an
|
||||
extended period of time.
|
||||
"""
|
||||
session.pop(_SESSION_KEY, None)
|
||||
|
|
Reference in a new issue