From a0817bfd59f5e9c1ddf2b15d56ba0cf8854c6620 Mon Sep 17 00:00:00 2001 From: Jake Moshenko Date: Tue, 4 Apr 2017 23:28:49 -0400 Subject: [PATCH] Refresh dependencies and fix tests. --- endpoints/api/error.py | 2 +- endpoints/exception.py | 2 +- endpoints/verbs/__init__.py | 11 ++- endpoints/web.py | 5 +- requirements-nover.txt | 2 +- requirements.txt | 151 +++++++++++++++++++----------------- util/http.py | 11 ++- 7 files changed, 102 insertions(+), 82 deletions(-) diff --git a/endpoints/api/error.py b/endpoints/api/error.py index 23d95ed32..bfa80efe2 100644 --- a/endpoints/api/error.py +++ b/endpoints/api/error.py @@ -7,7 +7,7 @@ from endpoints.exception import NotFound, ApiErrorType, ERROR_DESCRIPTION def error_view(error_type): return { - 'type': url_for('error', error_type=error_type, _external=True), + 'type': url_for('api.error', error_type=error_type, _external=True), 'title': error_type, 'description': ERROR_DESCRIPTION[error_type] } diff --git a/endpoints/exception.py b/endpoints/exception.py index dc37fd0fb..59fe45ea9 100644 --- a/endpoints/exception.py +++ b/endpoints/exception.py @@ -71,7 +71,7 @@ class ApiException(Exception): rv['error_type'] = self.error_type.value # TODO: deprecate rv['title'] = self.error_type.value - rv['type'] = url_for('error', error_type=self.error_type.value, _external=True) + rv['type'] = url_for('api.error', error_type=self.error_type.value, _external=True) rv['status'] = self.status_code return rv diff --git a/endpoints/verbs/__init__.py b/endpoints/verbs/__init__.py index 8e784aedb..35a919cbb 100644 --- a/endpoints/verbs/__init__.py +++ b/endpoints/verbs/__init__.py @@ -18,6 +18,7 @@ from endpoints.v2.blob import BLOB_DIGEST_ROUTE from image.appc import AppCImageFormatter from image.docker.squashed import SquashedDockerImageFormatter from storage import Storage +from util.http import exact_abort from util.registry.filelike import wrap_with_handler from util.registry.queuefile import QueueFile from util.registry.queueprocess import QueueProcess @@ -31,6 +32,9 @@ verbs = Blueprint('verbs', __name__) license_validator.enforce_license_before_request(verbs) +LAYER_MIMETYPE = 'binary/octet-stream' + + def _open_stream(formatter, repo_image, tag, derived_image_id, handlers): """ This method generates a stream of data which will be replicated and read from the queue files. @@ -119,7 +123,7 @@ def _torrent_for_blob(blob, is_public): expires_in=app.config['BITTORRENT_WEBSEED_LIFETIME']) if webseed is None: # We cannot support webseeds for storages that cannot provide direct downloads. - abort(make_response('Storage engine does not support seeding.', 501)) + exact_abort(501, 'Storage engine does not support seeding.') # Build the filename for the torrent. if is_public: @@ -242,7 +246,8 @@ def _repo_verb(namespace, repository, tag, verb, formatter, sign=False, checker= database.close_db_filter(None) logger.debug('Sending cached derived %s image %s', verb, derived_image.ref) - return send_file(storage.stream_read_file(derived_image.blob.locations, derived_layer_path)) + return send_file(storage.stream_read_file(derived_image.blob.locations, derived_layer_path), + mimetype=LAYER_MIMETYPE) logger.debug('Building and returning derived %s image %s', verb, derived_image.ref) @@ -292,7 +297,7 @@ def _repo_verb(namespace, repository, tag, verb, formatter, sign=False, checker= database.close_db_filter(None) # Return the client's data. - return send_file(client_queue_file) + return send_file(client_queue_file, mimetype=LAYER_MIMETYPE) def os_arch_checker(os, arch): diff --git a/endpoints/web.py b/endpoints/web.py index 43abd133b..34be2eac0 100644 --- a/endpoints/web.py +++ b/endpoints/web.py @@ -38,6 +38,9 @@ from util.systemlogs import build_logs_archive from util.useremails import send_email_changed +PGP_KEY_MIMETYPE = 'application/pgp-keys' + + @lru_cache(maxsize=1) def _get_route_data(): return swagger_route_data(include_internal=True, compact=True) @@ -92,7 +95,7 @@ def aci_signing_key(): if not signer.name: abort(404) - return send_file(signer.open_public_key_file()) + return send_file(signer.open_public_key_file(), mimetype=PGP_KEY_MIMETYPE) @web.route('/plans/') @no_cache diff --git a/requirements-nover.txt b/requirements-nover.txt index af5b1f243..d8a243c75 100644 --- a/requirements-nover.txt +++ b/requirements-nover.txt @@ -26,7 +26,7 @@ boto cachetools==1.1.6 cryptography flask -flask-restful==0.2.12 +flask-restful gevent gipc gunicorn<19.0 diff --git a/requirements.txt b/requirements.txt index 3c5f851ff..75d16b8ec 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,128 +1,133 @@ aiowsgi==0.6 -alembic==0.8.8 +alembic==0.9.1 +-e git+https://github.com/coreos/mockldap.git@59a46efbe8c7cd8146a87a7c4f2b09746b953e11#egg=mockldap +-e git+https://github.com/coreos/py-bitbucket.git@07a80f63388d004f05f58441983bdf195f9b666e#egg=py_bitbucket +-e git+https://github.com/coreos/pyapi-gitlab.git@136c3970d591136a4f766a846c5d22aad52e124f#egg=pyapi_gitlab +-e git+https://github.com/coreos/resumablehashlib.git@b1b631249589b07adf40e0ee545b323a501340b4#egg=resumablehashlib -e git+https://github.com/DevTable/aniso8601-fake.git@bd7762c7dea0498706d3f57db60cd8a8af44ba90#egg=aniso8601 -e git+https://github.com/DevTable/anunidecode.git@d59236a822e578ba3a0e5e5abbd3855873fa7a88#egg=anunidecode -e git+https://github.com/app-registry/appr-server.git@c2ef3b88afe926a92ef5f2e11e7d4a259e286a17#egg=cnr_server +-e git+https://github.com/DevTable/container-cloud-config.git@bce675537904175f6975024a4c89269027ea6792#egg=container_cloud_config +-e git+https://github.com/DevTable/python-etcd.git@f1168cb02a2a8c83bec1108c6fcd8615ef463b14#egg=python_etcd +-e git+https://github.com/jarus/flask-testing.git@18baff32969a0634a414ce61d2dd4a77433817a8#egg=Flask_Testing +-e git+https://github.com/jepcastelein/marketo-rest-python.git@e26af0c5acd3d4ad899383442703a053120aa7ab#egg=marketorestpython +-e git+https://github.com/NateFerrero/oauth2lib.git@d161b010f8a596826050a09e5e94d59443cc12d9#egg=oauth2lib +appdirs==1.4.3 APScheduler==3.0.5 +asn1crypto==0.22.0 autobahn==0.9.3.post3 -Babel==2.3.4 -beautifulsoup4==4.5.1 +Babel==2.4.0 +beautifulsoup4==4.5.3 bencode==1.0 -bintrees==2.0.4 +bintrees==2.0.6 bitmath==1.3.1.2 blinker==1.4 -boto==2.43.0 +boto==2.46.1 cachetools==1.1.6 -cffi==1.8.3 -click==6.6 --e git+https://github.com/DevTable/container-cloud-config.git@bce675537904175f6975024a4c89269027ea6792#egg=container_cloud_config +cffi==1.10.0 +click==6.7 contextlib2==0.5.4 -cryptography==1.5.2 -debtcollector==1.8.0 -decorator==4.0.10 +cryptography==1.8.1 +debtcollector==1.13.0 +decorator==4.0.11 enum34==1.1.6 -Flask==0.11.1 -Flask-Login==0.3.2 +Flask-Login==0.4.0 Flask-Mail==0.9.1 Flask-Principal==0.4.0 -Flask-RESTful==0.2.12 --e git+https://github.com/jarus/flask-testing.git@d60d431b3f2bc1b4b335579633e65978efa0a755#egg=Flask-Testing +Flask-RESTful==0.3.5 +Flask==0.12.1 funcparserlib==0.3.6 funcsigs==1.0.2 functools32==3.2.3.post2 -future==0.15.2 +furl==1.0.0 +future==0.16.0 futures==3.0.5 -gevent==1.1.2 +gevent==1.2.1 gipc==0.6.0 -greenlet==0.4.10 +greenlet==0.4.12 gunicorn==18.0 hiredis==0.2.0 html5lib==0.9999999 -httmock==1.2.5 +httmock==1.2.6 httpretty==0.8.10 -idna==2.1 -ipaddress==1.0.17 +idna==2.5 +ipaddress==1.0.18 iso8601==0.1.11 itsdangerous==0.24 -Jinja2==2.8 +Jinja2==2.9.6 jsonpath-rw==1.4.0 -jsonschema==2.5.1 -keystoneauth1==2.14.0 -Mako==1.0.4 -marisa-trie==0.7.2 --e git+https://github.com/jepcastelein/marketo-rest-python.git@1ba6dfee030b192f0930dd8c3b6d53b52d886c65#egg=marketorestpython-master -MarkupSafe==0.23 -mixpanel==4.3.1 +jsonschema==2.6.0 +keystoneauth1==2.19.0 +Mako==1.0.6 +marisa-trie==0.7.4 +MarkupSafe==1.0 +mixpanel==4.3.2 mock==2.0.0 mockredispy==2.9.3 --e git+https://github.com/coreos/mockldap.git@59a46efbe8c7cd8146a87a7c4f2b09746b953e11#egg=mockldap -monotonic==1.2 +monotonic==1.3 moto==0.4.25 msgpack-python==0.4.8 namedlist==1.7 ndg-httpsclient==0.4.2 -netaddr==0.7.18 +netaddr==0.7.19 netifaces==0.10.5 --e git+https://github.com/NateFerrero/oauth2lib.git@d161b010f8a596826050a09e5e94d59443cc12d9#egg=oauth2lib -oauthlib==2.0.0 -oslo.config==3.17.0 -oslo.i18n==3.9.0 -oslo.serialization==2.13.0 -oslo.utils==3.16.0 -pathvalidate==0.13.0 -pbr==1.10.0 +oauthlib==2.0.2 +olefile==0.44 +orderedmultidict==0.7.11 +oslo.config==3.24.0 +oslo.i18n==3.15.0 +oslo.serialization==2.18.0 +oslo.utils==3.25.0 +packaging==16.8 +pathvalidate==0.15.0 +pbr==2.0.0 peewee==2.8.1 -Pillow==3.4.2 -ply==3.9 +Pillow==4.1.0 +ply==3.10 positional==1.1.1 -psutil==4.3.1 -psycopg2==2.6.2 +psutil==5.2.1 +psycopg2==2.7.1 py-bcrypt==0.4 --e git+https://github.com/coreos/py-bitbucket.git@07a80f63388d004f05f58441983bdf195f9b666e#egg=py_bitbucket --e git+https://github.com/coreos/pyapi-gitlab.git@136c3970d591136a4f766a846c5d22aad52e124f#egg=pyapi_gitlab -pyasn1==0.1.9 -pycparser==2.16 -pycryptodome==3.4.3 -pycryptodomex==3.4.3 -PyGithub==1.29 +pycparser==2.17 +pycryptodome==3.4.5 +pycryptodomex==3.4.5 +PyGithub==1.34 pygpgme==0.3 -pyjwkest==1.3.1 +pyjwkest==1.3.2 PyJWT==1.4.2 PyMySQL==0.6.7 pyOpenSSL==16.2.0 -pyparsing==2.1.10 +pyparsing==2.2.0 PyPDF2==1.26.0 -python-dateutil==2.5.3 -python-editor==1.0.1 --e git+https://github.com/DevTable/python-etcd.git@f1168cb02a2a8c83bec1108c6fcd8615ef463b14#egg=python_etcd -python-keystoneclient==3.6.0 -python-ldap==2.4.27 -python-magic==0.4.12 -python-swiftclient==3.1.0 -pytz==2016.7 +python-dateutil==2.6.0 +python-editor==1.0.3 +python-keystoneclient==3.10.0 +python-ldap==2.4.32 +python-magic==0.4.13 +python-swiftclient==3.3.0 +pytz==2017.2 PyYAML==3.12 -raven==5.29.0 +raven==6.0.0 recaptcha2==0.1 redis==2.10.5 redlock==1.2.0 reportlab==2.7 -requests==2.11.1 -requests-oauthlib==0.7.0 --e git+https://github.com/coreos/resumablehashlib.git@b1b631249589b07adf40e0ee545b323a501340b4#egg=resumablehashlib +requests-oauthlib==0.8.0 +requests==2.13.0 rfc3986==0.4.1 semantic-version==2.6.0 six==1.10.0 SQLAlchemy==1.1.5 -stevedore==1.17.1 +stevedore==1.21.0 stringscore==0.1.0 -stripe==1.41.0 -toposort==1.4 +stripe==1.51.0 +toposort==1.5 trollius==2.1 tzlocal==1.3 -urllib3==1.18 -waitress==1.0.0 -WebOb==1.6.2 -Werkzeug==0.11.11 -wrapt==1.10.8 +urllib3==1.20 +waitress==1.0.2 +WebOb==1.7.2 +Werkzeug==0.12.1 +wrapt==1.10.10 xhtml2pdf==0.0.6 xmltodict==0.10.2 diff --git a/util/http.py b/util/http.py index 981e6364d..836a737dd 100644 --- a/util/http.py +++ b/util/http.py @@ -1,8 +1,10 @@ import logging import json +from flask import request, make_response, current_app +from werkzeug.exceptions import HTTPException + from app import analytics -from flask import request, abort as flask_abort, make_response, current_app from auth.auth_context import get_authenticated_user, get_validated_token logger = logging.getLogger(__name__) @@ -28,7 +30,11 @@ def _abort(status_code, data_object, headers): resp = make_response(json.dumps(data_object), status_code, headers) # Report the abort to the user. - flask_abort(resp) + # Raising HTTPException as workaround for https://github.com/pallets/werkzeug/issues/1098 + new_exception = HTTPException(response=resp) + new_exception.code = status_code + raise new_exception + def exact_abort(status_code, message=None): data = {} @@ -38,6 +44,7 @@ def exact_abort(status_code, message=None): _abort(status_code, data, {}) + def abort(status_code, message=None, issue=None, headers=None, **kwargs): message = (str(message) % kwargs if message else