Merge remote-tracking branch 'origin/resume'

This commit is contained in:
Jake Moshenko 2014-07-07 18:09:10 -04:00
commit f40b7dbc54
4 changed files with 47 additions and 2 deletions

View file

@ -88,6 +88,38 @@ def set_cache_headers(f):
return wrapper
@registry.route('/images/<image_id>/layer', methods=['HEAD'])
@process_auth
@extract_namespace_repo_from_session
@require_completion
@set_cache_headers
def head_image_layer(namespace, repository, image_id, headers):
permission = ReadRepositoryPermission(namespace, repository)
profile.debug('Checking repo permissions')
if permission.can() or model.repository_is_public(namespace, repository):
profile.debug('Looking up repo image')
repo_image = model.get_repo_image(namespace, repository, image_id)
if not repo_image:
profile.debug('Image not found')
abort(404, 'Image %(image_id)s not found', issue='unknown-image',
image_id=image_id)
extra_headers = {}
# Add the Accept-Ranges header if the storage engine supports resumeable
# downloads.
if store.get_supports_resumeable_downloads(repo_image.storage.locations):
profile.debug('Storage supports resumeable downloads')
extra_headers['Accept-Ranges'] = 'bytes';
resp = make_response('')
resp.headers.extend(extra_headers)
return resp
abort(403)
@registry.route('/images/<image_id>/layer', methods=['GET'])
@process_auth
@extract_namespace_repo_from_session
@ -110,10 +142,11 @@ def get_image_layer(namespace, repository, image_id, headers):
if direct_download_url:
profile.debug('Returning direct download URL')
return redirect(direct_download_url)
resp = redirect(direct_download_url)
return resp
profile.debug('Streaming layer data')
return Response(store.stream_read(repo_image.storage.locations, path), headers=headers)
return Response(store.stream_read(repo_image.storage.locations, path), headers=dict(headers, **extra_headers))
except (IOError, AttributeError):
profile.debug('Image not found')
abort(404, 'Image %(image_id)s not found', issue='unknown-image',
@ -374,6 +407,11 @@ def put_image_json(namespace, repository, image_id):
profile.debug('Looking up repo image')
repo_image = model.get_repo_image(namespace, repository, image_id)
if not repo_image:
profile.debug('Image not found')
abort(404, 'Image %(image_id)s not found', issue='unknown-image',
image_id=image_id)
uuid = repo_image.storage.uuid
if image_id != data['id']:

View file

@ -57,6 +57,9 @@ class BaseStorage(StoragePaths):
def get_direct_download_url(self, path, expires_in=60):
return None
def get_supports_resumeable_downloads(self):
return False
def get_content(self, path):
raise NotImplementedError

View file

@ -39,3 +39,4 @@ class DistributedStorage(StoragePaths):
list_directory = _location_aware(BaseStorage.list_directory)
exists = _location_aware(BaseStorage.exists)
remove = _location_aware(BaseStorage.remove)
get_supports_resumeable_downloads = _location_aware(BaseStorage.get_supports_resumeable_downloads)

View file

@ -83,6 +83,9 @@ class S3Storage(BaseStorage):
key.set_contents_from_string(content, encrypt_key=True)
return path
def get_supports_resumeable_downloads(self):
return True
def get_direct_download_url(self, path, expires_in=60):
self._initialize_s3()
path = self._init_path(path)