Skip to content

Commit 9b62d49

Browse files
committed
Add s3 upload storage method
Signed-off-by: Mike Perez <thingee@gmail.com>
1 parent 3ed5cdf commit 9b62d49

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

chacra/controllers/binaries/archs.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import logging
22
import os
3+
import boto3
4+
from botocore.exceptions import ClientError
35
import pecan
46
from pecan import response
57
from pecan.secure import secure
@@ -89,7 +91,7 @@ def index_post(self):
8991
if request.POST.get('force', False) is False:
9092
error('/errors/invalid', 'resource already exists and "force" key was not used')
9193

92-
full_path = self.save_file(file_obj)
94+
full_path, size = self.save_file(file_obj)
9395

9496
if self.binary is None:
9597
path = full_path
@@ -102,14 +104,19 @@ def index_post(self):
102104
self.binary = Binary(
103105
self.binary_name, self.project, arch=arch,
104106
distro=distro, distro_version=distro_version,
105-
ref=ref, sha1=sha1, path=path, size=os.path.getsize(path)
107+
ref=ref, sha1=sha1, path=path, size=size
106108
)
107109
else:
108110
self.binary.path = full_path
109111

110112
# check if this binary is interesting for other configured projects,
111113
# and if so, then mark those other repos so that they can be re-built
112114
self.mark_related_repos()
115+
116+
# Remove the local file after S3 upload
117+
if pecan.conf.storage_method == 's3':
118+
os.remove(full_path)
119+
113120
return dict()
114121

115122
def mark_related_repos(self):
@@ -175,8 +182,21 @@ def save_file(self, file_obj):
175182
for chunk in file_iterable:
176183
f.write(chunk)
177184

185+
if pecan.conf.storage_method == 's3':
186+
bucket = pecan.conf.bucket
187+
object_name = os.path.basename(self.binary_name)
188+
189+
s3_client = boto3.client('s3')
190+
try:
191+
with open(destination, 'rb') as f:
192+
s3_client.upload_fileobj(f, bucket, object_name)
193+
except ClientError as e:
194+
error('/errors/error/', 'file object upload to S3 failed with error %s' % e)
195+
196+
size = os.path.getsize(destination)
197+
178198
# return the full path to the saved object:
179-
return destination
199+
return destination, size
180200

181201
@expose()
182202
def _lookup(self, name, *remainder):

config/dev.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,17 @@
6363
'encoding': 'utf-8'
6464
}
6565

66+
# Where to store the data. Options are 's3' or 'local'
67+
storage_method = 'local'
68+
6669
# location for storing uploaded binaries
6770
binary_root = '%(confdir)s/public'
6871
repos_root = '%(confdir)s/repos'
6972
distributions_root = '%(confdir)s/distributions'
7073

74+
# If storage method is s3, provide a bucket name
75+
bucket = ''
76+
7177
# When True it will set the headers so that Nginx can serve the download
7278
# instead of Pecan.
7379
delegate_downloads = False

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ alembic
88
ipython
99
python-statsd
1010
requests
11+
boto3
1112
importlib_metadata<=3.6; python_version<'3.8'

0 commit comments

Comments
 (0)