diff --git a/devstack/lib/freezer-api b/devstack/lib/freezer-api index a0e1efde..e434b98a 100644 --- a/devstack/lib/freezer-api +++ b/devstack/lib/freezer-api @@ -143,6 +143,11 @@ function configure_freezer_api { sudo chown $STACK_USER $FREEZER_API_AUTH_CACHE_DIR/registry rm -f $FREEZER_API_AUTH_CACHE_DIR/registry/* + # configure logs + if [ -n "$BASE" ] && [ -d "$BASE/logs" ]; then + sudo ln -sf $FREEZER_API_LOG_DIR/freezer-api.log $BASE/logs/freezer-api-post.log + fi + # set keystone configuration configure_auth_token_middleware $FREEZER_API_CONF freezer $FREEZER_API_AUTH_CACHE_DIR/api @@ -299,7 +304,7 @@ function configure_uwsgi_freezer_api_app { iniset $FREEZER_API_UWSGI_CONF 'uwsgi' http $local_http iniset $FREEZER_API_UWSGI_CONF 'uwsgi' processes 2 iniset $FREEZER_API_UWSGI_CONF 'uwsgi' threads 2 - iniset $FREEZER_API_UWSGI_CONF 'uwsgi' wsgi-file $FREEZER_API_DIR/freezer_api/cmd/wsgi.py + iniset $FREEZER_API_UWSGI_CONF 'uwsgi' wsgi freezer_api.wsgi:application # Make sure the client doesn't try to re-use the connection. iniset $FREEZER_API_UWSGI_CONF 'uwsgi' add-header "Connection: close" diff --git a/etc/freezer/freezer-paste.ini b/etc/freezer/freezer-paste.ini index fb216433..a99baba0 100644 --- a/etc/freezer/freezer-paste.ini +++ b/etc/freezer/freezer-paste.ini @@ -10,8 +10,8 @@ paste.app_factory = freezer_api.service:freezer_appv2_factory [filter:authtoken] paste.filter_factory = keystonemiddleware.auth_token:filter_factory -[filter:healthcheck] -paste.filter_factory = oslo_middleware:Healthcheck.factory +[app:healthcheck] +paste.app_factory = oslo_middleware:Healthcheck.app_factory backends = disable_by_file disable_by_file_path = /etc/freezer/healthcheck_disable @@ -24,11 +24,21 @@ paste.filter_factory = freezer_api.api.versions:VersionNegotiator.factory [filter:http_proxy_to_wsgi] paste.filter_factory = oslo_middleware:HTTPProxyToWSGI.factory -[pipeline:main] -pipeline = healthcheck http_proxy_to_wsgi versionsNegotiator authtoken context backupapp +[composite:main] +use = egg:Paste#urlmap +/healthcheck = healthcheck +/ = api -[pipeline:unauthenticated_freezer_api] -pipeline = http_proxy_to_wsgi healthcheck freezer_app +[pipeline:api] +pipeline = http_proxy_to_wsgi versionsNegotiator authtoken context backupapp + +[composite:unauthenticated_freezer_api] +use = egg:Paste#urlmap +/healthcheck = healthcheck +/ = unauthenticated_api + +[pipeline:unauthenticated_api] +pipeline = http_proxy_to_wsgi freezer_app [composite:backupapp] paste.composite_factory = freezer_api.service:root_app_factory diff --git a/etc/freezer/uwsgi.conf b/etc/freezer/uwsgi.conf index e805d8ca..365eff79 100644 --- a/etc/freezer/uwsgi.conf +++ b/etc/freezer/uwsgi.conf @@ -5,7 +5,7 @@ strict = true http = :9090 processes = 2 threads = 2 -wsgi-file = /opt/stack/freezer-api/freezer_api/cmd/wsgi.py +wsgi = freezer_api.wsgi:application callable = app master = true add-header = Connection: close diff --git a/freezer_api/api/common/middleware.py b/freezer_api/api/common/middleware.py index 63fc55c6..b79310b0 100644 --- a/freezer_api/api/common/middleware.py +++ b/freezer_api/api/common/middleware.py @@ -131,7 +131,8 @@ class RequireJSON(HookableMiddlewareMixin, object): def process_request(self, req, resp): if not req.client_accepts_json: raise falcon.HTTPNotAcceptable( - 'Freezer-api only supports responses encoded as JSON.', + description='Freezer-api only supports responses encoded ' + 'as JSON.', href='http://docs.examples.com/api/json') diff --git a/freezer_api/api/common/resource.py b/freezer_api/api/common/resource.py index ce9a1249..21089944 100644 --- a/freezer_api/api/common/resource.py +++ b/freezer_api/api/common/resource.py @@ -38,5 +38,5 @@ class BaseResource(object): json_data = json.loads(raw_json, encoding='utf-8') except ValueError: raise falcon.HTTPError(falcon.HTTP_753, - 'Malformed JSON') + title='Malformed JSON') return json_data diff --git a/freezer_api/wsgi.py b/freezer_api/wsgi.py new file mode 100644 index 00000000..e8fb0a0a --- /dev/null +++ b/freezer_api/wsgi.py @@ -0,0 +1,24 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""WSGI application entry-point for the Blazar API.""" + +import threading + +from freezer_api.service import initialize_app + +application = None + +lock = threading.Lock() +with lock: + if application is None: + application = initialize_app() diff --git a/releasenotes/notes/wsgi_module-471cb41a14109df6.yaml b/releasenotes/notes/wsgi_module-471cb41a14109df6.yaml new file mode 100644 index 00000000..3a5c7b7c --- /dev/null +++ b/releasenotes/notes/wsgi_module-471cb41a14109df6.yaml @@ -0,0 +1,28 @@ +--- +features: + - | + A new module, ``freezer_api.wsgi``, has been added as a place to provide + WSGI. For example, if using uWSGI then instead of: + + .. code-block:: ini + + [uwsgi] + wsgi-file = /bin/freezer-api-wsgi + + You can now use: + + .. code-block:: ini + + [uwsgi] + wsgi = freezer_api.wsgi:application + + This also simplifies deployment with other WSGI servers that expect module + paths such as gunicorn. + +upgrade: + - | + The WSGI script ``freezer-api-wsgi`` has been removed. Deployment tooling + should instead reference the Python module path for the wsgi module in + Freezer, ``freezer_api.wsgi:application`` if their chosen WSGI server + supports this (gunicorn, uWSGI, etc.) or implement a .wsgi script + themselves if not (mod_wsgi). diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py index b1800ca2..50a0eda6 100644 --- a/releasenotes/source/conf.py +++ b/releasenotes/source/conf.py @@ -30,9 +30,9 @@ extensions = [ ] # openstackdocstheme options -repository_name = 'openstack/freezer-api' -bug_project = 'freezer' -bug_tag = 'release notes' +openstackdocs_repo_name = 'openstack/freezer-api' +openstackdocs_bug_project = 'freezer' +openstackdocs_bug_tag = 'release notes' html_last_updated_fmt = '%Y-%m-%d %H:%M' diff --git a/setup.cfg b/setup.cfg index 5c3748d0..2b24911b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -50,8 +50,6 @@ console_scripts = freezer-api = freezer_api.cmd.api:main freezer-manage = freezer_api.cmd.manage:main freezer-manager-status = freezer_api.cmd.status:main -wsgi_scripts = - freezer-api-wsgi = freezer_api.service:initialize_app freezer.db.backends = sqlalchemy = freezer_api.db.sqlalchemy.driver:SQLDriver