Properly handle the empty layer when pushing schema 2 manifests
Docker doesn't send us the contents of this layer, so we are forced to synthesize it ourselves
This commit is contained in:
parent
947c029afa
commit
4985040d31
13 changed files with 173 additions and 25 deletions
|
@ -1,3 +1,5 @@
|
|||
import logging
|
||||
|
||||
from datetime import datetime
|
||||
from uuid import uuid4
|
||||
|
||||
|
@ -7,6 +9,9 @@ from data.database import (Repository, Namespace, ImageStorage, Image, ImageStor
|
|||
BlobUpload, ImageStorageLocation, db_random_func)
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_repository_blob_by_digest(repository, blob_digest):
|
||||
""" Find the content-addressable blob linked to the specified repository.
|
||||
"""
|
||||
|
@ -157,3 +162,31 @@ def initiate_upload(namespace, repo_name, uuid, location_name, storage_metadata)
|
|||
location = storage_model.get_image_location_for_name(location_name)
|
||||
return BlobUpload.create(repository=repo, location=location.id, uuid=uuid,
|
||||
storage_metadata=storage_metadata)
|
||||
|
||||
|
||||
def get_or_create_shared_blob(digest, byte_data, storage):
|
||||
""" Returns the ImageStorage blob with the given digest or, if not present,
|
||||
adds a row and writes the given byte data to the storage engine.
|
||||
This method is *only* to be used for shared blobs that are globally
|
||||
accessible, such as the special empty gzipped tar layer that Docker
|
||||
no longer pushes to us.
|
||||
"""
|
||||
try:
|
||||
return ImageStorage.get(content_checksum=digest, uploading=False)
|
||||
except ImageStorage.DoesNotExist:
|
||||
record = ImageStorage.create(image_size=len(byte_data), content_checksum=digest,
|
||||
cas_path=True, uploading=True)
|
||||
preferred = storage.preferred_locations[0]
|
||||
location_obj = ImageStorageLocation.get(name=preferred)
|
||||
try:
|
||||
storage.put_content([preferred], storage_model.get_layer_path(record), byte_data)
|
||||
ImageStoragePlacement.create(storage=record, location=location_obj)
|
||||
|
||||
record.uploading = False
|
||||
record.save()
|
||||
except:
|
||||
logger.exception('Exception when trying to write special layer %s', digest)
|
||||
record.delete_instance()
|
||||
raise
|
||||
|
||||
return record
|
||||
|
|
Reference in a new issue