Skip to content
This repository has been archived by the owner on Dec 7, 2022. It is now read-only.

Enable S3 storage. #433

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/4456.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enable S3 as alternative storage.
2 changes: 1 addition & 1 deletion docs/_scripts/recursive_add_tag.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env bash

echo "Retrieve the href of Tag latest in the synced repository."
echo "Retrieve the href of Tag manifest_a in the synced repository."
export TAG_HREF=$(http $BASE_ADDR'/pulp/api/v3/content/docker/tags/?repository_version='$REPOVERSION_HREF'&name=manifest_a' \
| jq -r '.results | first | .pulp_href')

Expand Down
2 changes: 1 addition & 1 deletion docs/_static/api.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/workflows/host.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ images in it, that content can be consumed by container clients.
Podman
^^^^^^

``$ podman pull localhost:24816/foo``
``$ podman pull localhost:24816/test:<tag_name>``

If SSL has not been setup for your Pulp, configure podman to work with the insecure registry:

Expand Down
35 changes: 22 additions & 13 deletions pulp_docker/app/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os

from aiohttp import web
from aiohttp.web_exceptions import HTTPFound
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from multidict import MultiDict
Expand Down Expand Up @@ -67,30 +68,41 @@ def _base_paths(path):
return [path]

@staticmethod
async def _dispatch(path, headers):
async def _dispatch(file, headers):
"""
Stream a file back to the client.

Stream the bits.

Args:
path (str): The fully qualified path to the file to be served.
headers (dict):
file (:class:`django.db.models.fields.files.FieldFile`): File to respond with
headers (dict): A dictionary of response headers.

Raises:
:class:`aiohttp.web_exceptions.HTTPFound`: When we need to redirect to the file
NotImplementedError: If file is stored in a file storage we can't handle

Returns:
StreamingHttpResponse: Stream the requested content.
The :class:`aiohttp.web.FileResponse` for the file.

"""
full_headers = MultiDict()

full_headers['Content-Type'] = headers['Content-Type']
full_headers['Docker-Content-Digest'] = headers['Docker-Content-Digest']
full_headers['Docker-Distribution-API-Version'] = 'registry/2.0'
full_headers['Content-Length'] = os.path.getsize(path)
full_headers['Content-Length'] = str(file.size)
full_headers['Content-Disposition'] = 'attachment; filename={n}'.format(
n=os.path.basename(path))
file_response = web.FileResponse(path, headers=full_headers)
return file_response
n=os.path.basename(file.name))

if settings.DEFAULT_FILE_STORAGE == 'pulpcore.app.models.storage.FileSystem':
path = os.path.join(settings.MEDIA_ROOT, file.name)
file_response = web.FileResponse(path, headers=full_headers)
return file_response
elif settings.DEFAULT_FILE_STORAGE == 'storages.backends.s3boto3.S3Boto3Storage':
raise HTTPFound(file.url, headers=full_headers)
else:
raise NotImplementedError()

@staticmethod
async def serve_v2(request):
Expand Down Expand Up @@ -187,8 +199,7 @@ async def dispatch_tag(tag, response_headers):
except ObjectDoesNotExist:
raise ArtifactNotFound(tag.name)
else:
return await Registry._dispatch(os.path.join(settings.MEDIA_ROOT, artifact.file.name),
response_headers)
return await Registry._dispatch(artifact.file, response_headers)

async def get_by_digest(self, request):
"""
Expand All @@ -209,8 +220,6 @@ async def get_by_digest(self, request):
else:
artifact = ca.artifact
if artifact:
return await Registry._dispatch(os.path.join(settings.MEDIA_ROOT,
artifact.file.name),
headers)
return await Registry._dispatch(artifact.file, headers)
else:
return await self._stream_content_artifact(request, web.StreamResponse(), ca)