commit
a8ec7865a7
11 changed files with 106 additions and 86 deletions
|
@ -2,7 +2,7 @@ import bcrypt
|
|||
import logging
|
||||
import json
|
||||
import uuid
|
||||
from flask.ext.login import UserMixin
|
||||
from flask_login import UserMixin
|
||||
|
||||
from peewee import JOIN_LEFT_OUTER, IntegrityError, fn
|
||||
from uuid import uuid4
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -26,7 +26,7 @@ boto
|
|||
cachetools==1.1.6
|
||||
cryptography
|
||||
flask
|
||||
flask-restful==0.2.12
|
||||
flask-restful
|
||||
gevent
|
||||
gipc
|
||||
gunicorn<19.0
|
||||
|
|
151
requirements.txt
151
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
|
||||
|
|
|
@ -3,7 +3,7 @@ import os
|
|||
import pytest
|
||||
import shutil
|
||||
from flask import Flask, jsonify
|
||||
from flask.ext.login import LoginManager
|
||||
from flask_login import LoginManager
|
||||
from peewee import SqliteDatabase
|
||||
|
||||
from app import app as application
|
||||
|
|
|
@ -3,7 +3,7 @@ import requests
|
|||
import unittest
|
||||
|
||||
from flask import Flask
|
||||
from flask.ext.testing import LiveServerTestCase
|
||||
from flask_testing import LiveServerTestCase
|
||||
|
||||
from initdb import setup_database_for_testing, finished_database_for_testing
|
||||
from storage import Storage
|
||||
|
|
|
@ -3,7 +3,7 @@ import os
|
|||
import pytest
|
||||
import shutil
|
||||
from flask import Flask, jsonify
|
||||
from flask.ext.login import LoginManager
|
||||
from flask_login import LoginManager
|
||||
from peewee import SqliteDatabase
|
||||
|
||||
from app import app as application
|
||||
|
|
11
util/http.py
11
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
|
||||
|
|
Reference in a new issue