From 61a6db236f87579936327bda84697c830fc2bcee Mon Sep 17 00:00:00 2001 From: jakedt Date: Fri, 11 Apr 2014 18:34:47 -0400 Subject: [PATCH] Finish the implementation of local userfiles. Strip charsets from mimetypes in the build worker. Add canonical name ordering to the build queue. Port all queues to the canonical naming version. --- config.py | 2 +- data/database.py | 2 +- data/queue.py | 52 ++++++++++++++++++------- data/userfiles.py | 78 ++++++++++++++++++++++++++++--------- endpoints/api/discovery.py | 3 +- endpoints/common.py | 2 +- endpoints/index.py | 2 +- endpoints/registry.py | 4 +- endpoints/webhooks.py | 1 - requirements-nover.txt | 3 +- requirements.txt | 1 + test/data/test.db | Bin 200704 -> 200704 bytes workers/dockerfilebuild.py | 3 ++ 13 files changed, 112 insertions(+), 41 deletions(-) diff --git a/config.py b/config.py index 8c30b2acb..45e6ae0bb 100644 --- a/config.py +++ b/config.py @@ -97,7 +97,7 @@ class DefaultConfig(object): # Userfiles USERFILES_TYPE = 'LocalUserfiles' - USERFILES_PATH = 'test/data/userfiles' + USERFILES_PATH = 'test/data/registry/userfiles' # Analytics ANALYTICS_TYPE = "FakeAnalytics" diff --git a/data/database.py b/data/database.py index 6fe6760ec..c4a96c0d0 100644 --- a/data/database.py +++ b/data/database.py @@ -275,7 +275,7 @@ class RepositoryBuild(BaseModel): class QueueItem(BaseModel): - queue_name = CharField(index=True) + queue_name = CharField(index=True, max_length=1024) body = TextField() available_after = DateTimeField(default=datetime.now, index=True) available = BooleanField(default=True, index=True) diff --git a/data/queue.py b/data/queue.py index 09e90f1a1..b4b53faa5 100644 --- a/data/queue.py +++ b/data/queue.py @@ -8,17 +8,26 @@ transaction_factory = app.config['DB_TRANSACTION_FACTORY'] class WorkQueue(object): - def __init__(self, queue_name): + def __init__(self, queue_name, canonical_name_match_list=None): self.queue_name = queue_name - def put(self, message, available_after=0, retries_remaining=5): + if canonical_name_match_list is None: + self.canonical_name_match_list = [] + else: + self.canonical_name_match_list = canonical_name_match_list + + @staticmethod + def _canonical_name(name_list): + return '/'.join(name_list) + '/' + + def put(self, canonical_name_list, message, available_after=0, retries_remaining=5): """ Put an item, if it shouldn't be processed for some number of seconds, specify that amount as available_after. """ params = { - 'queue_name': self.queue_name, + 'queue_name': self._canonical_name([self.queue_name] + canonical_name_list), 'body': message, 'retries_remaining': retries_remaining, } @@ -35,16 +44,25 @@ class WorkQueue(object): minutes. """ now = datetime.now() - available_or_expired = ((QueueItem.available == True) | - (QueueItem.processing_expires <= now)) + + name_match_query = '%s%%' % self._canonical_name([self.queue_name] + + self.canonical_name_match_list) with transaction_factory(db): - avail = QueueItem.select().where(QueueItem.queue_name == self.queue_name, - QueueItem.available_after <= now, - available_or_expired, - QueueItem.retries_remaining > 0) + running = (QueueItem + .select(QueueItem.queue_name) + .where(QueueItem.available == False, + QueueItem.processing_expires > now, + QueueItem.queue_name ** name_match_query)) - found = list(avail.limit(1).order_by(QueueItem.available_after)) + avail = QueueItem.select().where(QueueItem.queue_name ** name_match_query, + QueueItem.available_after <= now, + ((QueueItem.available == True) | + (QueueItem.processing_expires <= now)), + QueueItem.retries_remaining > 0, + ~(QueueItem.queue_name << running)) + + found = list(avail.limit(1).order_by(QueueItem.id)) if found: item = found[0] @@ -57,16 +75,24 @@ class WorkQueue(object): return None - def complete(self, completed_item): + @staticmethod + def complete(completed_item): completed_item.delete_instance() - def incomplete(self, incomplete_item, retry_after=300): + @staticmethod + def incomplete(incomplete_item, retry_after=300): retry_date = datetime.now() + timedelta(seconds=retry_after) incomplete_item.available_after = retry_date incomplete_item.available = True incomplete_item.save() + @staticmethod + def extend_processing(queue_item, seconds_from_now): + new_expiration = datetime.now() + timedelta(seconds=seconds_from_now) + queue_item.processing_expires = new_expiration + queue_item.save() + image_diff_queue = WorkQueue('imagediff') -dockerfile_build_queue = WorkQueue('dockerfilebuild3') +dockerfile_build_queue = WorkQueue('dockerfilebuild') webhook_queue = WorkQueue('webhook') diff --git a/data/userfiles.py b/data/userfiles.py index 7d1f8b69b..8722803ca 100644 --- a/data/userfiles.py +++ b/data/userfiles.py @@ -2,10 +2,12 @@ import boto import os import logging import hashlib +import magic from boto.s3.key import Key from uuid import uuid4 -from flask import url_for +from flask import url_for, request, send_file +from flask.views import View logger = logging.getLogger(__name__) @@ -88,43 +90,84 @@ class S3Userfiles(object): return k.etag[1:-1][:7] -def upload_userfile_endpoint(file_id): - raise NotImplementedError() +class UserfilesHandlers(View): + methods = ['GET', 'PUT'] + def __init__(self, local_userfiles): + self._userfiles = local_userfiles + self._magic = magic.Magic(mime=True) -def download_userfile_endpoint(file_id): - raise NotImplementedError() + def get(self, file_id): + path = self._userfiles.file_path(file_id) + logger.debug('Sending path: %s' % path) + return send_file(path, mimetype=self._magic.from_file(path)) + + def put(self, file_id): + input_stream = request.stream + if request.headers.get('transfer-encoding') == 'chunked': + # Careful, might work only with WSGI servers supporting chunked + # encoding (Gunicorn) + input_stream = request.environ['wsgi.input'] + + self._userfiles.store_stream(input_stream, file_id) + + def dispatch_request(self, file_id): + if request.method == 'GET': + return self.get(file_id) + elif request.method == 'PUT': + return self.put(file_id) class LocalUserfiles(object): - def __init__(self, path): + def __init__(self, app, path): self._root_path = path self._buffer_size = 64 * 1024 # 64 KB + self._app = app + + def _build_url_adapter(self): + return self._app.url_map.bind(self._app.config['SERVER_HOSTNAME'], + script_name=self._app.config['APPLICATION_ROOT'] or '/', + url_scheme=self._app.config['PREFERRED_URL_SCHEME']) def prepare_for_drop(self, mime_type): file_id = str(uuid4()) - return (url_for('upload_userfile_endpoint', file_id=file_id), file_id) + with self._app.app_context() as ctx: + ctx.url_adapter = self._build_url_adapter() + return (url_for('userfiles_handlers', file_id=file_id, _external=True), file_id) + + def file_path(self, file_id): + if '..' in file_id or file_id.startswith('/'): + raise RuntimeError('Invalid Filename') + return os.path.join(self._root_path, file_id) + + def store_stream(self, stream, file_id): + path = self.file_path(file_id) + dirname = os.path.dirname(path) + if not os.path.exists(dirname): + os.makedirs(dirname) - def store_file(self, file_like_obj, content_type): - file_id = str(uuid4()) - path = os.path.join(self._root_path, file_id) with open(path, 'w') as to_write: while True: try: - buf = file_like_obj.read(self._buffer_size) + buf = stream.read(self._buffer_size) if not buf: break to_write.write(buf) except IOError: break + def store_file(self, file_like_obj, content_type): + file_id = str(uuid4()) + self.store_stream(file_like_obj, content_type) return file_id def get_file_url(self, file_id, expires_in=300): - return url_for('download_userfile_endpoint', file_id=file_id) + with self._app.app_context() as ctx: + ctx.url_adapter = self._build_url_adapter() + return url_for('userfiles_handlers', file_id=file_id, _external=True) def get_file_checksum(self, file_id): - path = os.path.join(self._root_path, file_id) + path = self.file_path(file_id) sha_hash = hashlib.sha256() with open(path, 'r') as to_hash: while True: @@ -148,11 +191,10 @@ class Userfiles(object): path = app.config.get('USERFILES_PATH', '') if storage_type == 'LocalUserfiles': - app.add_url_rule('/userfiles/', 'upload_userfile_endpoint', - upload_userfile_endpoint, methods=['PUT']) - app.add_url_rule('/userfiles/', 'download_userfile_endpoint', - download_userfile_endpoint, methods=['GET']) - userfiles = LocalUserfiles(path) + userfiles = LocalUserfiles(app, path) + app.add_url_rule('/userfiles/', + view_func=UserfilesHandlers.as_view('userfiles_handlers', + local_userfiles=userfiles)) elif storage_type == 'S3Userfiles': access_key = app.config.get('USERFILES_AWS_ACCESS_KEY', '') diff --git a/endpoints/api/discovery.py b/endpoints/api/discovery.py index a9dc48298..6e7eb3f5a 100644 --- a/endpoints/api/discovery.py +++ b/endpoints/api/discovery.py @@ -28,8 +28,7 @@ SERVER_HOSTNAME = app.config['SERVER_HOSTNAME'] def fully_qualified_name(method_view_class): - inst = method_view_class() - return '%s.%s' % (inst.__module__, inst.__class__.__name__) + return '%s.%s' % (method_view_class.__module__, method_view_class.__name__) def swagger_route_data(include_internal=False, compact=False): diff --git a/endpoints/common.py b/endpoints/common.py index 6d201d911..33986fd8d 100644 --- a/endpoints/common.py +++ b/endpoints/common.py @@ -160,7 +160,7 @@ def start_build(repository, dockerfile_id, tags, build_name, subdir, manual, dockerfile_id, build_name, trigger, pull_robot_name = pull_robot_name) - dockerfile_build_queue.put(json.dumps({ + dockerfile_build_queue.put([repository.namespace, repository.name], json.dumps({ 'build_uuid': build_request.uuid, 'namespace': repository.namespace, 'repository': repository.name, diff --git a/endpoints/index.py b/endpoints/index.py index 0ff64709b..8271dda73 100644 --- a/endpoints/index.py +++ b/endpoints/index.py @@ -315,7 +315,7 @@ def update_images(namespace, repository): 'pushed_image_count': len(image_with_checksums), 'pruned_image_count': num_removed, } - webhook_queue.put(json.dumps(webhook_data)) + webhook_queue.put([namespace, repository], json.dumps(webhook_data)) return make_response('Updated', 204) diff --git a/endpoints/registry.py b/endpoints/registry.py index 8e381a1bd..9d981ba08 100644 --- a/endpoints/registry.py +++ b/endpoints/registry.py @@ -179,7 +179,7 @@ def put_image_layer(namespace, repository, image_id): # The layer is ready for download, send a job to the work queue to # process it. logger.debug('Queing diffs job for image: %s' % image_id) - image_diff_queue.put(json.dumps({ + image_diff_queue.put([namespace, repository, image_id], json.dumps({ 'namespace': namespace, 'repository': repository, 'image_id': image_id, @@ -232,7 +232,7 @@ def put_image_checksum(namespace, repository, image_id): # The layer is ready for download, send a job to the work queue to # process it. logger.debug('Queing diffs job for image: %s' % image_id) - image_diff_queue.put(json.dumps({ + image_diff_queue.put([namespace, repository, image_id], json.dumps({ 'namespace': namespace, 'repository': repository, 'image_id': image_id, diff --git a/endpoints/webhooks.py b/endpoints/webhooks.py index df5988750..4bba9a25f 100644 --- a/endpoints/webhooks.py +++ b/endpoints/webhooks.py @@ -5,7 +5,6 @@ from flask import request, make_response, Blueprint from app import billing as stripe from data import model -from data.queue import dockerfile_build_queue from auth.auth import process_auth from auth.permissions import ModifyRepositoryPermission from util.invoice import renderInvoiceToHtml diff --git a/requirements-nover.txt b/requirements-nover.txt index 439bf714d..2d0d91c34 100644 --- a/requirements-nover.txt +++ b/requirements-nover.txt @@ -28,4 +28,5 @@ flask-restful jsonschema git+https://github.com/NateFerrero/oauth2lib.git alembic -sqlalchemy \ No newline at end of file +sqlalchemy +python-magic diff --git a/requirements.txt b/requirements.txt index 06f341226..45afa158b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -42,6 +42,7 @@ pycrypto==2.6.1 python-daemon==1.6 python-dateutil==2.2 python-digitalocean==0.7 +python-magic==0.4.6 pytz==2014.2 redis==2.9.1 reportlab==2.7 diff --git a/test/data/test.db b/test/data/test.db index 6471bc3e4f40a74abe27f9e3398ea95232896337..fc0078c61d2a0c80647b8bf6bcb608e5c937279c 100644 GIT binary patch delta 6149 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 delta 6097 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 diff --git a/workers/dockerfilebuild.py b/workers/dockerfilebuild.py index 4d7b0e306..b16008ba1 100644 --- a/workers/dockerfilebuild.py +++ b/workers/dockerfilebuild.py @@ -397,6 +397,9 @@ class DockerfileBuildWorker(Worker): docker_resource = requests.get(resource_url, stream=True) c_type = docker_resource.headers['content-type'] + if ';' in c_type: + c_type = c_type.split(';')[0] + filetype_msg = ('Request to build type: %s with repo: %s and tags: %s' % (c_type, repo, tag_names)) logger.info(filetype_msg)