Another huge batch of registry v2 changes
Add patch support and resumeable sha Implement all actual registry methods Add a simple database generation option
This commit is contained in:
parent
5ba3521e67
commit
e1b3e9e6ae
29 changed files with 1095 additions and 430 deletions
|
@ -4,7 +4,8 @@ import dateutil.parser
|
|||
from peewee import JOIN_LEFT_OUTER, fn
|
||||
from datetime import datetime
|
||||
|
||||
from data.model import DataModelException, db_transaction, _basequery, storage
|
||||
from data.model import (DataModelException, db_transaction, _basequery, storage,
|
||||
InvalidImageException)
|
||||
from data.database import (Image, Repository, ImageStoragePlacement, Namespace, ImageStorage,
|
||||
ImageStorageLocation, RepositoryPermission, db_for_update)
|
||||
|
||||
|
@ -247,7 +248,7 @@ def find_create_or_link_image(docker_image_id, repo_obj, username, translations,
|
|||
return repo_image
|
||||
|
||||
logger.debug('Creating new storage for docker id: %s', docker_image_id)
|
||||
new_storage = storage.create_storage(preferred_location)
|
||||
new_storage = storage.create_v1_storage(preferred_location)
|
||||
|
||||
return Image.create(docker_image_id=docker_image_id,
|
||||
repository=repo_obj, storage=new_storage,
|
||||
|
@ -255,7 +256,7 @@ def find_create_or_link_image(docker_image_id, repo_obj, username, translations,
|
|||
|
||||
|
||||
def set_image_metadata(docker_image_id, namespace_name, repository_name, created_date_str, comment,
|
||||
command, parent=None):
|
||||
command, v1_json_metadata, parent=None):
|
||||
with db_transaction():
|
||||
query = (Image
|
||||
.select(Image, ImageStorage)
|
||||
|
@ -273,7 +274,7 @@ def set_image_metadata(docker_image_id, namespace_name, repository_name, created
|
|||
|
||||
# We cleanup any old checksum in case it's a retry after a fail
|
||||
fetched.storage.checksum = None
|
||||
fetched.storage.created = datetime.now()
|
||||
fetched.created = datetime.now()
|
||||
|
||||
if created_date_str is not None:
|
||||
try:
|
||||
|
@ -282,14 +283,14 @@ def set_image_metadata(docker_image_id, namespace_name, repository_name, created
|
|||
# parse raises different exceptions, so we cannot use a specific kind of handler here.
|
||||
pass
|
||||
|
||||
fetched.storage.comment = comment
|
||||
fetched.storage.command = command
|
||||
fetched.comment = comment
|
||||
fetched.command = command
|
||||
fetched.v1_json_metadata = v1_json_metadata
|
||||
|
||||
if parent:
|
||||
fetched.ancestors = '%s%s/' % (parent.ancestors, parent.id)
|
||||
|
||||
fetched.save()
|
||||
fetched.storage.save()
|
||||
return fetched
|
||||
|
||||
|
||||
|
@ -334,8 +335,65 @@ def set_image_size(docker_image_id, namespace_name, repository_name, image_size,
|
|||
return image
|
||||
|
||||
|
||||
def get_image(repo, dockerfile_id):
|
||||
def get_image(repo, docker_image_id):
|
||||
try:
|
||||
return Image.get(Image.docker_image_id == dockerfile_id, Image.repository == repo)
|
||||
return Image.get(Image.docker_image_id == docker_image_id, Image.repository == repo)
|
||||
except Image.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
def get_repo_image_by_storage_checksum(namespace, repository_name, storage_checksum):
|
||||
try:
|
||||
return (Image
|
||||
.select()
|
||||
.join(ImageStorage)
|
||||
.switch(Image)
|
||||
.join(Repository)
|
||||
.join(Namespace, on=(Namespace.id == Repository.namespace_user))
|
||||
.where(Repository.name == repository_name, Namespace.username == namespace,
|
||||
ImageStorage.checksum == storage_checksum, ImageStorage.uploading == False)
|
||||
.get())
|
||||
except Image.DoesNotExist:
|
||||
msg = 'Image with storage checksum {0} does not exist in repo {1}/{2}'.format(storage_checksum,
|
||||
namespace,
|
||||
repository_name)
|
||||
raise InvalidImageException(msg)
|
||||
|
||||
|
||||
def synthesize_v1_image(namespace, repository_name, storage_checksum, docker_image_id,
|
||||
created_date_str, comment, command, v1_json_metadata, parent_docker_id):
|
||||
""" Find an existing image with this docker image id, and if none exists, write one with the
|
||||
specified metadata.
|
||||
"""
|
||||
|
||||
repo = _basequery.get_existing_repository(namespace, repository_name)
|
||||
# Sometimes the manifest may reference an image that already exists
|
||||
|
||||
found = get_image(repo, docker_image_id)
|
||||
if found is not None:
|
||||
# The image already exists, nothing to do
|
||||
return found
|
||||
|
||||
the_bits = storage.get_repo_storage_by_checksum(namespace, repository_name, storage_checksum)
|
||||
|
||||
ancestors = '/'
|
||||
if parent_docker_id is not None:
|
||||
parent = get_repo_image(namespace, repository_name, parent_docker_id)
|
||||
if parent is None:
|
||||
msg = 'Parent not found with docker image id {0} in repo {1}/{2}'.format(parent_docker_id,
|
||||
namespace,
|
||||
repository_name)
|
||||
raise InvalidImageException(msg)
|
||||
ancestors = '{0}{1}/'.format(parent.ancestors, parent.id)
|
||||
|
||||
created = None
|
||||
if created_date_str is not None:
|
||||
try:
|
||||
created = dateutil.parser.parse(created_date_str).replace(tzinfo=None)
|
||||
except:
|
||||
# parse raises different exceptions, so we cannot use a specific kind of handler here.
|
||||
pass
|
||||
|
||||
return Image.create(docker_image_id=docker_image_id, ancestors=ancestors, comment=comment,
|
||||
command=command, v1_json_metadata=v1_json_metadata, created=created,
|
||||
storage=the_bits, repository=repo)
|
||||
|
|
Reference in a new issue