Skip to content
This repository was archived by the owner on Sep 12, 2018. It is now read-only.

Commit 6732a5f

Browse files
committed
Merge pull request #293 from jonasfj/direct-s3-download-via-redirect
Direct s3 download via redirect
2 parents 46d7577 + 86ae7e4 commit 6732a5f

File tree

8 files changed

+48
-3
lines changed

8 files changed

+48
-3
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ Available configuration options
104104
*non*-Amazon S3-compliant object store, in one of the boto config files'
105105
`[Credentials]` section, set `boto_host`, `boto_port` as appropriate for the
106106
service you are using.
107+
1. `storage_redirect`: Redirect resource requested if storage engine supports
108+
this, e.g. S3 will redirect signed URLs, this can be used to offload the
109+
server.
107110
108111
### Authentication options
109112
@@ -127,6 +130,7 @@ to `s3`.
127130
1. `s3_access_key`: string, S3 access key
128131
1. `s3_secret_key`: string, S3 secret key
129132
1. `s3_bucket`: string, S3 bucket name
133+
1. `s3_region`: S3 region where the bucket is located
130134
1. `s3_encrypt`: boolean, if true, the container will be encrypted on the
131135
server-side by S3 and will be stored in an encrypted form while at rest
132136
in S3.
@@ -305,7 +309,7 @@ is already taken, find out which container is already using it by running "docke
305309
Install the system requirements for building a Python library:
306310
307311
```
308-
sudo apt-get install build-essential python-dev libevent-dev python-pip libssl-dev liblzma-dev
312+
sudo apt-get install build-essential python-dev libevent-dev python-pip libssl-dev liblzma-dev libffi-dev
309313
```
310314
311315
Then install the Registry app:

config/config_s3.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ prod:
1515
secret_key: REPLACEME
1616
s3_encrypt: true
1717
s3_secure: true
18-
storage_path: /images
18+
storage_path: /images
19+
storage_redirect: False # Redirect signed URL for image files

config/config_test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ test:
1010
s3_bucket: _env:S3_BUCKET
1111
s3_encrypt: _env:S3_ENCRYPT
1212
s3_secure: _env:S3_SECURE
13+
storage_redirect: False
1314

1415
gs_access_key: _env:GS_ACCESS_KEY
1516
gs_secret_key: _env:GS_SECRET_KEY

lib/storage/__init__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,17 @@ def put_content(self, path, content):
9494
def stream_read(self, path, bytes_range=None):
9595
raise NotImplementedError
9696

97+
def content_redirect_url(self, path):
98+
"""Get a URL for content at path
99+
100+
Get a URL to which client can be redirected to get the content from
101+
the path. Return None if not supported by this engine.
102+
103+
Note, this feature will only be used if the `storage_redirect`
104+
configuration key is set to `True`.
105+
"""
106+
return None
107+
97108
def stream_write(self, path, fp):
98109
raise NotImplementedError
99110

lib/storage/boto_base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ def __init__(self, config):
105105
self._boto_conn = self.makeConnection()
106106
self._boto_bucket = self._boto_conn.get_bucket(
107107
self._config.boto_bucket)
108+
logger.info("Boto based storage initialized")
108109

109110
def _build_connection_params(self):
110111
kwargs = {'is_secure': (self._config.boto_secure is True)}

lib/storage/s3.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import cStringIO as StringIO
66
import logging
77

8+
import boto.s3
89
import boto.s3.connection
910
import boto.s3.key
1011

@@ -29,6 +30,14 @@ def _build_connection_params(self):
2930

3031
def makeConnection(self):
3132
kwargs = self._build_connection_params()
33+
if self._config.s3_region is not None:
34+
return boto.s3.connect_to_region(
35+
region_name=self._config.s3_region,
36+
aws_access_key_id=self._config.s3_access_key,
37+
aws_secret_access_key=self._config.s3_secret_key,
38+
**kwargs)
39+
logger.warn("No S3 region specified, using boto default region, " +
40+
"this may affect performance and stability.")
3241
return boto.s3.connection.S3Connection(
3342
self._config.s3_access_key,
3443
self._config.s3_secret_key,
@@ -66,3 +75,13 @@ def stream_write(self, path, fp):
6675
except IOError:
6776
pass
6877
mp.complete_upload()
78+
79+
def content_redirect_url(self, path):
80+
path = self._init_path(path)
81+
key = self.makeKey(path)
82+
if not key.exists():
83+
raise IOError('No such key: \'{0}\''.format(path))
84+
return key.generate_url(
85+
expires_in=1200,
86+
method='GET',
87+
query_auth=True)

registry/images.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ def _get_image_layer(image_id, headers=None, bytes_range=None):
7171
else:
7272
logger.warn('nginx_x_accel_redirect config set,'
7373
' but storage is not LocalStorage')
74+
75+
# If store allows us to just redirect the client let's do that, we'll
76+
# offload a lot of expensive I/O and get faster I/O
77+
if cfg.storage_redirect:
78+
content_redirect_url = store.content_redirect_url(path)
79+
if content_redirect_url:
80+
return flask.redirect(content_redirect_url, 302)
81+
7482
status = None
7583
layer_size = 0
7684

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
boto==2.19.0
1+
boto==2.27.0
22
backports.lzma==0.0.2
33
Flask==0.9
44
PyYAML==3.10

0 commit comments

Comments
 (0)