From af22899ebee2569bf1f84908d03cd854a9595835 Mon Sep 17 00:00:00 2001 From: aditi Date: Tue, 28 Mar 2017 02:30:26 +0530 Subject: [PATCH] Run Watcher-API behind mod-wsgi This patch adds support to run watcher-api with mod-wsgi. It provides 1. wsgi app script files, to run watcher-api under apache. 2. updated devstack plugin to run watcher-api default with mod-wsgi. 3. Document to deploy watcher-api behind wsgi. Change-Id: I8f1026f0b09fd774376220c2d117ee66f72421b8 Closes-Bug: #1675376 --- devstack/files/apache-watcher-api.template | 42 ++++++++++++++ devstack/lib/watcher | 65 +++++++++++++++++++++- devstack/local.conf.controller | 4 ++ doc/source/deploy/apache-mod-wsgi.rst | 49 ++++++++++++++++ doc/source/dev/devstack.rst | 6 ++ doc/source/index.rst | 1 + etc/apache2/watcher | 33 +++++++++++ watcher/api/app.wsgi | 40 +++++++++++++ 8 files changed, 237 insertions(+), 3 deletions(-) create mode 100644 devstack/files/apache-watcher-api.template create mode 100644 doc/source/deploy/apache-mod-wsgi.rst create mode 100644 etc/apache2/watcher create mode 100644 watcher/api/app.wsgi diff --git a/devstack/files/apache-watcher-api.template b/devstack/files/apache-watcher-api.template new file mode 100644 index 000000000..1f9cffb65 --- /dev/null +++ b/devstack/files/apache-watcher-api.template @@ -0,0 +1,42 @@ +# 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. + +# This is an example Apache2 configuration file for using the +# Watcher API through mod_wsgi. This version assumes you are +# running devstack to configure the software. + +Listen %WATCHER_SERVICE_PORT% + + + WSGIDaemonProcess watcher-api user=%USER% processes=%APIWORKERS% threads=1 display-name=%{GROUP} + WSGIScriptAlias / %WATCHER_WSGI_DIR%/app.wsgi + WSGIApplicationGroup %{GLOBAL} + WSGIProcessGroup watcher-api + WSGIPassAuthorization On + + ErrorLogFormat "%M" + ErrorLog /var/log/%APACHE_NAME%/watcher-api.log + CustomLog /var/log/%APACHE_NAME%/watcher-api-access.log combined + + + + WSGIProcessGroup watcher-api + WSGIApplicationGroup %{GLOBAL} + = 2.4> + Require all granted + + + Order allow,deny + Allow from all + + + diff --git a/devstack/lib/watcher b/devstack/lib/watcher index 2f70024ad..7e25c1143 100644 --- a/devstack/lib/watcher +++ b/devstack/lib/watcher @@ -44,6 +44,9 @@ WATCHER_CONF_DIR=/etc/watcher WATCHER_CONF=$WATCHER_CONF_DIR/watcher.conf WATCHER_POLICY_JSON=$WATCHER_CONF_DIR/policy.json +WATCHER_DEVSTACK_DIR=$WATCHER_DIR/devstack +WATCHER_DEVSTACK_FILES_DIR=$WATCHER_DEVSTACK_DIR/files + NOVA_CONF_DIR=/etc/nova NOVA_CONF=$NOVA_CONF_DIR/nova.conf @@ -51,6 +54,13 @@ if is_ssl_enabled_service "watcher" || is_service_enabled tls-proxy; then WATCHER_SERVICE_PROTOCOL="https" fi +WATCHER_USE_MOD_WSGI=$(trueorfalse TRUE WATCHER_USE_MOD_WSGI) + +if is_suse; then + WATCHER_WSGI_DIR=${WATCHER_WSGI_DIR:-/srv/www/htdocs/watcher} +else + WATCHER_WSGI_DIR=${WATCHER_WSGI_DIR:-/var/www/watcher} +fi # Public facing bits WATCHER_SERVICE_HOST=${WATCHER_SERVICE_HOST:-$HOST_IP} WATCHER_SERVICE_PORT=${WATCHER_SERVICE_PORT:-9322} @@ -74,10 +84,21 @@ function is_watcher_enabled { return 1 } +#_cleanup_watcher_apache_wsgi - Remove wsgi files, +#disable and remove apache vhost file +function _cleanup_watcher_apache_wsgi { + sudo rm -rf $WATCHER_WSGI_DIR + sudo rm -f $(apache_site_config_for watcher-api) + restart_apache_server +} + # cleanup_watcher() - Remove residual data files, anything left over from previous # runs that a clean run would need to clean up function cleanup_watcher { sudo rm -rf $WATCHER_STATE_PATH $WATCHER_AUTH_CACHE_DIR + if [[ "$WATCHER_USE_MOD_WSGI" == "True" ]]; then + _cleanup_watcher_apache_wsgi + fi } # configure_watcher() - Set config files, create data dirs, etc @@ -108,6 +129,28 @@ function create_watcher_accounts { "$WATCHER_SERVICE_PROTOCOL://$WATCHER_SERVICE_HOST:$WATCHER_SERVICE_PORT" } +# _config_watcher_apache_wsgi() - Set WSGI config files of watcher +function _config_watcher_apache_wsgi { + local watcher_apache_conf + if [[ "$WATCHER_USE_MOD_WSGI" == "True" ]]; then + sudo mkdir -p $WATCHER_WSGI_DIR + sudo cp $WATCHER_DIR/watcher/api/app.wsgi $WATCHER_WSGI_DIR/app.wsgi + watcher_apache_conf=$(apache_site_config_for watcher-api) + sudo cp $WATCHER_DEVSTACK_FILES_DIR/apache-watcher-api.template $watcher_apache_conf + sudo sed -e " + s|%WATCHER_SERVICE_PORT%|$WATCHER_SERVICE_PORT|g; + s|%WATCHER_WSGI_DIR%|$WATCHER_WSGI_DIR|g; + s|%USER%|$STACK_USER|g; + s|%APIWORKERS%|$API_WORKERS|g; + s|%APACHE_NAME%|$APACHE_NAME|g; + " -i $watcher_apache_conf + enable_apache_site watcher-api + tail_log watcher-access /var/log/$APACHE_NAME/watcher-api-access.log + tail_log watcher-api /var/log/$APACHE_NAME/watcher-api.log + fi + +} + # create_watcher_conf() - Create a new watcher.conf file function create_watcher_conf { # (Re)create ``watcher.conf`` @@ -157,6 +200,10 @@ function create_watcher_conf { iniset $WATCHER_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(levelname)s %(name)s [%(request_id)s %(project_domain)s %(user_name)s %(project_name)s] %(instance)s%(message)s" fi + #config apache files + if [[ "$WATCHER_USE_MOD_WSGI" == "True" ]]; then + _config_watcher_apache_wsgi + fi # Register SSL certificates if provided if is_ssl_enabled_service watcher; then ensure_certificates WATCHER @@ -205,19 +252,26 @@ function install_watcherclient { function install_watcher { git_clone $WATCHER_REPO $WATCHER_DIR $WATCHER_BRANCH setup_develop $WATCHER_DIR + if [[ "$WATCHER_USE_MOD_WSGI" == "True" ]]; then + install_apache_wsgi + fi } # start_watcher_api() - Start the API process ahead of other things function start_watcher_api { # Get right service port for testing + local service_port=$WATCHER_SERVICE_PORT local service_protocol=$WATCHER_SERVICE_PROTOCOL if is_service_enabled tls-proxy; then service_port=$WATCHER_SERVICE_PORT_INT service_protocol="http" fi - - run_process watcher-api "$WATCHER_BIN_DIR/watcher-api --config-file $WATCHER_CONF" + if [[ "$WATCHER_USE_MOD_WSGI" == "True" ]]; then + restart_apache_server + else + run_process watcher-api "$WATCHER_BIN_DIR/watcher-api --config-file $WATCHER_CONF" + fi echo "Waiting for watcher-api to start..." if ! wait_for_service $SERVICE_TIMEOUT $service_protocol://$WATCHER_SERVICE_HOST:$service_port; then die $LINENO "watcher-api did not start" @@ -240,7 +294,12 @@ function start_watcher { # stop_watcher() - Stop running processes (non-screen) function stop_watcher { - for serv in watcher-api watcher-decision-engine watcher-applier; do + if [[ "$WATCHER_USE_MOD_WSGI" == "True" ]]; then + disable_apache_site watcher-api + else + stop_process watcher-api + fi + for serv in watcher-decision-engine watcher-applier; do stop_process $serv done } diff --git a/devstack/local.conf.controller b/devstack/local.conf.controller index 0e236d123..37901b3f6 100644 --- a/devstack/local.conf.controller +++ b/devstack/local.conf.controller @@ -17,6 +17,10 @@ NETWORK_GATEWAY=10.254.1.1 # Change this for your network MULTI_HOST=1 + +#Set this to FALSE if do not want to run watcher-api behind mod-wsgi +#WATCHER_USE_MOD_WSGI=TRUE + # This is the controller node, so disable nova-compute disable_service n-cpu diff --git a/doc/source/deploy/apache-mod-wsgi.rst b/doc/source/deploy/apache-mod-wsgi.rst new file mode 100644 index 000000000..c0b6347ba --- /dev/null +++ b/doc/source/deploy/apache-mod-wsgi.rst @@ -0,0 +1,49 @@ +.. + Except where otherwise noted, this document is licensed under Creative + Commons Attribution 3.0 License. You can view the license at: + + https://creativecommons.org/licenses/by/3.0/ + + +Installing API behind mod_wsgi +============================== + +#. Install the Apache Service:: + + Fedora 21/RHEL7/CentOS7: + sudo yum install httpd + + Fedora 22 (or higher): + sudo dnf install httpd + + Debian/Ubuntu: + apt-get install apache2 + +#. Copy ``etc/apache2/watcher.conf`` under the apache sites:: + + Fedora/RHEL7/CentOS7: + sudo cp etc/apache2/watcher /etc/httpd/conf.d/watcher.conf + + Debian/Ubuntu: + sudo cp etc/apache2/watcher /etc/apache2/sites-available/watcher.conf + +#. Edit ``/watcher.conf`` according to installation + and environment. + + * Modify the ``WSGIDaemonProcess`` directive to set the ``user`` and + ``group`` values to appropriate user on your server. + * Modify the ``WSGIScriptAlias`` directive to point to the + watcher/api/app.wsgi script. + * Modify the ``Directory`` directive to set the path to the Watcher API + code. + * Modify the ``ErrorLog and CustomLog`` to redirect the logs to the right + directory. + +#. Enable the apache watcher site and reload:: + + Fedora/RHEL7/CentOS7: + sudo systemctl reload httpd + + Debian/Ubuntu: + sudo a2ensite watcher + sudo service apache2 reload diff --git a/doc/source/dev/devstack.rst b/doc/source/dev/devstack.rst index 157fa7522..d27f6a77d 100644 --- a/doc/source/dev/devstack.rst +++ b/doc/source/dev/devstack.rst @@ -92,6 +92,12 @@ Detailed DevStack Instructions Note: if you want to use a specific branch, specify WATCHER_BRANCH in the local.conf file. By default it will use the master branch. + Note: watcher-api will default run under apache/httpd, set the variable + WATCHER_USE_MOD_WSGI=FALSE if you do not wish to run under apache/httpd. + For development environment it is suggested to set WATHCER_USE_MOD_WSGI + to FALSE. For Production environment it is suggested to keep it at the + default TRUE value. + #. Start stacking from the controller node:: ./devstack/stack.sh diff --git a/doc/source/index.rst b/doc/source/index.rst index 2c77b4f9a..0cae341fd 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -56,6 +56,7 @@ Getting Started dev/devstack deploy/configuration deploy/conf-files + deploy/apache-mod-wsgi dev/notifications dev/testing dev/rally_link diff --git a/etc/apache2/watcher b/etc/apache2/watcher new file mode 100644 index 000000000..bdf5562a3 --- /dev/null +++ b/etc/apache2/watcher @@ -0,0 +1,33 @@ +# 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. + +# This is an example Apache2 configuration file for using +# Watcher API through mod_wsgi +Listen 9322 + + + WSGIDaemonProcess watcher-api user=stack group=stack processes=2 threads=2 display-name=%{GROUP} + WSGIScriptAlias / /opt/stack/watcher/watcher/api/app.wsgi + WSGIProcessGroup watcher-api + + ErrorLog /var/log/httpd/watcher_error.log + LogLevel info + CustomLog /var/log/httpd/watcher_access.log combined + + + WSGIProcessGroup watcher-api + WSGIApplicationGroup %{GLOBAL} + AllowOverride All + Require all granted + + + diff --git a/watcher/api/app.wsgi b/watcher/api/app.wsgi new file mode 100644 index 000000000..c2b0609ae --- /dev/null +++ b/watcher/api/app.wsgi @@ -0,0 +1,40 @@ +# -*- mode: python -*- +# -*- encoding: utf-8 -*- +# +# 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. +""" +Use this file for deploying the API service under Apache2 mod_wsgi. +""" + +import sys + +from oslo_config import cfg +import oslo_i18n as i18n +from oslo_log import log + +from watcher.api import app +from watcher.common import service + + +CONF = cfg.CONF + +i18n.install('watcher') + +service.prepare_service(sys.argv) + +LOG = log.getLogger(__name__) +LOG.debug("Configuration:") +CONF.log_opt_values(LOG, log.DEBUG) + +application = app.VersionSelectorApplication() +