diff --git a/devstack/lib/heat b/devstack/lib/heat index 0bd5a7f18e..248e2a670a 100644 --- a/devstack/lib/heat +++ b/devstack/lib/heat @@ -39,7 +39,7 @@ GITBRANCH["python-heatclient"]=${HEATCLIENT_BRANCH:-master} HEAT_USE_APACHE=${HEAT_USE_APACHE:-${HEAT_USE_MOD_WSGI:-True}} HEAT_DIR=$DEST/heat -HEAT_FILES_DIR=$HEAT_DIR/heat/httpd/files +HEAT_HTTPD_VHOST_FILES_DIR=$HEAT_DIR/etc/heat/httpd HEAT_STANDALONE=$(trueorfalse False HEAT_STANDALONE) HEAT_ENABLE_ADOPT_ABANDON=$(trueorfalse False HEAT_ENABLE_ADOPT_ABANDON) @@ -58,8 +58,8 @@ HEAT_TRUSTEE_DOMAIN=${HEAT_TRUSTEE_DOMAIN:-default} HEAT_BIN_DIR=$(get_python_exec_prefix) HEAT_API_UWSGI_CONF=$HEAT_CONF_DIR/heat-api-uwsgi.ini HEAT_CFN_API_UWSGI_CONF=$HEAT_CONF_DIR/heat-api-cfn-uwsgi.ini -HEAT_API_UWSGI=$HEAT_BIN_DIR/heat-wsgi-api -HEAT_CFN_API_UWSGI=$HEAT_BIN_DIR/heat-wsgi-api-cfn +HEAT_API_UWSGI=heat.wsgi.api:application +HEAT_CFN_API_UWSGI=heat.wsgi.cfn:application # Flag to set the oslo_policy.enforce_scope and oslo_policy.enforce_new_defaults. # This is used to disable the compute API policies scope and new defaults. @@ -159,12 +159,12 @@ function configure_heat { if [[ "$HEAT_USE_APACHE" == "True" ]]; then if [[ $WSGI_MODE == "uwsgi" ]]; then - write_uwsgi_config "$HEAT_API_UWSGI_CONF" "$HEAT_API_UWSGI" "/heat-api" + write_uwsgi_config "$HEAT_API_UWSGI_CONF" "$HEAT_API_UWSGI" "/heat-api" "" "heat-api" # configure threads for h-api to avoid IO wait and messaging timeout. We use # 'nproc/4' to calculate API workers, hence, 4 would be probably correct # approximation. iniset "$HEAT_API_UWSGI_CONF" uwsgi threads 4 - write_uwsgi_config "$HEAT_CFN_API_UWSGI_CONF" "$HEAT_CFN_API_UWSGI" "/heat-api-cfn" + write_uwsgi_config "$HEAT_CFN_API_UWSGI_CONF" "$HEAT_CFN_API_UWSGI" "/heat-api-cfn" "" "heat-api-cfn" else _config_heat_apache_wsgi fi @@ -368,11 +368,11 @@ function _config_heat_apache_wsgi { local heat_cfn_api_port=$HEAT_API_CFN_PORT local venv_path="" - sudo cp $HEAT_FILES_DIR/heat-api.conf $heat_apache_conf + sudo cp $HEAT_HTTPD_VHOST_FILES_DIR/heat-api.conf $heat_apache_conf sudo sed -e " s|%PUBLICPORT%|$heat_api_port|g; s|%APACHE_NAME%|$APACHE_NAME|g; - s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g; + s|%HEAT_DIR%|$HEAT_DIR|g; s|%API_WORKERS%|$API_WORKERS|g; s|%SSLENGINE%|$heat_ssl|g; s|%SSLCERTFILE%|$heat_certfile|g; @@ -381,11 +381,11 @@ function _config_heat_apache_wsgi { s|%VIRTUALENV%|$venv_path|g " -i $heat_apache_conf - sudo cp $HEAT_FILES_DIR/heat-api-cfn.conf $heat_cfn_apache_conf + sudo cp $HEAT_HTTPD_VHOST_FILES_DIR/heat-api-cfn.conf $heat_cfn_apache_conf sudo sed -e " s|%PUBLICPORT%|$heat_cfn_api_port|g; s|%APACHE_NAME%|$APACHE_NAME|g; - s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g; + s|%HEAT_DIR%|$HEAT_DIR|g; s|%API_WORKERS%|$API_WORKERS|g; s|%SSLENGINE%|$heat_ssl|g; s|%SSLCERTFILE%|$heat_certfile|g; diff --git a/doc/source/conf.py b/doc/source/conf.py index 933b0f3cbc..24dc6228a2 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -180,10 +180,10 @@ apidoc_excluded_paths = [ 'engine/resources/aws', 'engine/resources/openstack', 'hacking', - 'httpd', 'locale', 'tests', 'version.py', + 'wsgi', ] diff --git a/heat/httpd/files/heat-api-cfn.conf b/etc/heat/httpd/heat-api-cfn.conf similarity index 93% rename from heat/httpd/files/heat-api-cfn.conf rename to etc/heat/httpd/heat-api-cfn.conf index 7cbca4a05f..0359c80c10 100644 --- a/heat/httpd/files/heat-api-cfn.conf +++ b/etc/heat/httpd/heat-api-cfn.conf @@ -3,7 +3,7 @@ Listen %PUBLICPORT% WSGIDaemonProcess heat-api-cfn processes=%API_WORKERS% threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV% WSGIProcessGroup heat-api-cfn - WSGIScriptAlias / %HEAT_BIN_DIR%/heat-wsgi-api-cfn + WSGIScriptAlias / %HEAT_DIR%/cfn/wsgi.py WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On AllowEncodedSlashes On diff --git a/heat/httpd/files/heat-api.conf b/etc/heat/httpd/heat-api.conf similarity index 93% rename from heat/httpd/files/heat-api.conf rename to etc/heat/httpd/heat-api.conf index 01411be667..877ad5918b 100644 --- a/heat/httpd/files/heat-api.conf +++ b/etc/heat/httpd/heat-api.conf @@ -3,7 +3,7 @@ Listen %PUBLICPORT% WSGIDaemonProcess heat-api processes=%API_WORKERS% threads=10 user=%USER% display-name=%{GROUP} %VIRTUALENV% WSGIProcessGroup heat-api - WSGIScriptAlias / %HEAT_BIN_DIR%/heat-wsgi-api + WSGIScriptAlias / %HEAT_DIR%/api/wsgi.py WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On AllowEncodedSlashes On diff --git a/heat/httpd/files/heat-api-cfn-uwsgi.ini b/etc/heat/uwsgi/heat-api-cfn-uwsgi.ini similarity index 84% rename from heat/httpd/files/heat-api-cfn-uwsgi.ini rename to etc/heat/uwsgi/heat-api-cfn-uwsgi.ini index cd08bd7198..cb88c5e953 100644 --- a/heat/httpd/files/heat-api-cfn-uwsgi.ini +++ b/etc/heat/uwsgi/heat-api-cfn-uwsgi.ini @@ -11,4 +11,4 @@ die-on-term = true master = true processes = 4 http = 127.0.0.1:80998 -wsgi-file = /usr/local/bin/heat-wsgi-api-cfn +module = heat.wsgi.cfn:application diff --git a/heat/httpd/files/heat-api-uwsgi.ini b/etc/heat/uwsgi/heat-api-uwsgi.ini similarity index 85% rename from heat/httpd/files/heat-api-uwsgi.ini rename to etc/heat/uwsgi/heat-api-uwsgi.ini index f5b11f94e2..9b7151c83d 100644 --- a/heat/httpd/files/heat-api-uwsgi.ini +++ b/etc/heat/uwsgi/heat-api-uwsgi.ini @@ -11,4 +11,4 @@ die-on-term = true master = true processes = 4 http = 127.0.0.1:80999 -wsgi-file = /usr/local/bin/heat-wsgi-api +module = heat.wsgi.api:application diff --git a/heat/httpd/heat_api_cfn.py b/heat/api/cfn/wsgi.py similarity index 100% rename from heat/httpd/heat_api_cfn.py rename to heat/api/cfn/wsgi.py diff --git a/heat/httpd/heat_api.py b/heat/api/openstack/wsgi.py similarity index 100% rename from heat/httpd/heat_api.py rename to heat/api/openstack/wsgi.py diff --git a/heat/httpd/files/uwsgi-heat-api-cfn.conf b/heat/httpd/files/uwsgi-heat-api-cfn.conf deleted file mode 100644 index 5b9879d9ad..0000000000 --- a/heat/httpd/files/uwsgi-heat-api-cfn.conf +++ /dev/null @@ -1,2 +0,0 @@ -KeepAlive Off -ProxyPass "/heat-api-cfn" "http://127.0.0.1:80998" retry=0 diff --git a/heat/httpd/files/uwsgi-heat-api.conf b/heat/httpd/files/uwsgi-heat-api.conf deleted file mode 100644 index 3ac14e03cd..0000000000 --- a/heat/httpd/files/uwsgi-heat-api.conf +++ /dev/null @@ -1,2 +0,0 @@ -KeepAlive Off -ProxyPass "/heat-api" "http://127.0.0.1:80999" retry=0 diff --git a/heat/httpd/__init__.py b/heat/wsgi/__init__.py similarity index 100% rename from heat/httpd/__init__.py rename to heat/wsgi/__init__.py diff --git a/heat/wsgi/api.py b/heat/wsgi/api.py new file mode 100644 index 0000000000..59624c1cd5 --- /dev/null +++ b/heat/wsgi/api.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 Heat API.""" + +import threading + +from heat.api.openstack import wsgi + +application = None + +lock = threading.Lock() +with lock: + if application is None: + application = wsgi.init_application() diff --git a/heat/wsgi/cfn.py b/heat/wsgi/cfn.py new file mode 100644 index 0000000000..a81bf9455d --- /dev/null +++ b/heat/wsgi/cfn.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 Heat API.""" + +import threading + +from heat.api.cfn import wsgi + +application = None + +lock = threading.Lock() +with lock: + if application is None: + application = wsgi.init_application() diff --git a/releasenotes/notes/add-heat-wsgi-module-bd75e71b4fc47568.yaml b/releasenotes/notes/add-heat-wsgi-module-bd75e71b4fc47568.yaml new file mode 100644 index 0000000000..fb3c89d6c3 --- /dev/null +++ b/releasenotes/notes/add-heat-wsgi-module-bd75e71b4fc47568.yaml @@ -0,0 +1,22 @@ +--- +features: + - | + A new module, ``heat.wsgi``, has been added as a place to gather WSGI + ``application`` objects. This is intended to ease deployment by providing + a consistent location for these objects. For example, if using uWSGI then + instead of: + + .. code-block:: ini + + [uwsgi] + wsgi-file = /bin/heat-api + + You can now use: + + .. code-block:: ini + + [uwsgi] + module = heat.wsgi.api:application + + This also simplifies deployment with other WSGI servers that expect module + paths such as gunicorn. diff --git a/setup.cfg b/setup.cfg index 54587e9bbf..d44a44180f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -43,8 +43,8 @@ console_scripts = heat-status = heat.cmd.status:main wsgi_scripts = - heat-wsgi-api = heat.httpd.heat_api:init_application - heat-wsgi-api-cfn = heat.httpd.heat_api_cfn:init_application + heat-wsgi-api = heat.api.openstack.wsgi:init_application + heat-wsgi-api-cfn = heat.api.cfn.wsgi:init_application oslo.config.opts = heat.common.cache = heat.common.cache:list_opts