From 80234fadceb0412fc3f62dbb96fa6117f2b0087d Mon Sep 17 00:00:00 2001 From: liusheng Date: Mon, 10 Jul 2017 11:05:35 +0800 Subject: [PATCH] Support running api under uWSGI This change add the support to run mogan-api server under uWSGI Implements: bp support-uwsgi Change-Id: I561028f39092b0b7aca5d5216dde36636be70b66 --- devstack/plugin.sh | 22 +++++------ devstack/settings | 10 ++++- doc/source/index.rst | 10 ++++- doc/source/installation/uwsgi.rst | 66 +++++++++++++++++++++++++++++++ etc/mogan-uwsgi.ini.sample | 25 ++++++++++++ mogan/api/app.py | 16 +++++--- mogan/api/app.wsgi | 21 ++++++++++ setup.cfg | 2 + 8 files changed, 153 insertions(+), 19 deletions(-) create mode 100644 doc/source/installation/uwsgi.rst create mode 100644 etc/mogan-uwsgi.ini.sample create mode 100644 mogan/api/app.wsgi diff --git a/devstack/plugin.sh b/devstack/plugin.sh index 554ada74..951fd254 100644 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -14,13 +14,6 @@ set -o xtrace # Defaults # -------- -# Support entry points installation of console scripts -if [[ -d ${MOGAN_DIR}/bin ]]; then - MOGAN_BIN_DIR=${MOGAN_DIR}/bin -else - MOGAN_BIN_DIR=$(get_python_exec_prefix) -fi - # create_mogan_accounts - Set up common required mogan accounts # # Project User Roles @@ -31,9 +24,9 @@ function create_mogan_accounts { get_or_create_service "mogan" "baremetal_compute" "Baremetal Compute" get_or_create_endpoint "baremetal_compute" \ "$REGION_NAME" \ - "${MOGAN_SERVICE_PROTOCOL}://${MOGAN_SERVICE_HOST}:${MOGAN_SERVICE_PORT}/v1" \ - "${MOGAN_SERVICE_PROTOCOL}://${MOGAN_SERVICE_HOST}:${MOGAN_SERVICE_PORT}/v1" \ - "${MOGAN_SERVICE_PROTOCOL}://${MOGAN_SERVICE_HOST}:${MOGAN_SERVICE_PORT}/v1" + "${MOGAN_SERVICE_PROTOCOL}://${MOGAN_SERVICE_HOST}/baremetal_compute/v1" \ + "${MOGAN_SERVICE_PROTOCOL}://${MOGAN_SERVICE_HOST}/baremetal_compute/v1" \ + "${MOGAN_SERVICE_PROTOCOL}://${MOGAN_SERVICE_HOST}/baremetal_compute/v1" } @@ -119,6 +112,9 @@ function configure_mogan { if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then setup_colorized_logging ${MOGAN_CONF_FILE} DEFAULT tenant user fi + + # uWSGI configuration + write_uwsgi_config "$MOGAN_UWSGI_CONF" "$MOGAN_UWSGI_APP" "/baremetal_compute" } @@ -139,6 +135,7 @@ function install_mogan { die $LINENO "$srv should be enabled for Mogan." fi done + pip_install uwsgi setup_develop ${MOGAN_DIR} } @@ -155,8 +152,8 @@ function install_mogan_pythonclient { function start_mogan { if is_service_enabled mogan-api && is_service_enabled mogan-engine && is_service_enabled mogan-scheduler; then echo_summary "Installing all mogan services in separate processes" - run_process mogan-api "${MOGAN_BIN_DIR}/mogan-api --config-file ${MOGAN_CONF_DIR}/mogan.conf" - if ! wait_for_service ${SERVICE_TIMEOUT} ${MOGAN_SERVICE_PROTOCOL}://${MOGAN_SERVICE_HOST}:${MOGAN_SERVICE_PORT}; then + run_process mogan-api "$MOGAN_BIN_DIR/uwsgi --ini $MOGAN_UWSGI_CONF" + if ! wait_for_service ${SERVICE_TIMEOUT} ${MOGAN_SERVICE_PROTOCOL}://${MOGAN_SERVICE_HOST}/baremetal_compute; then die $LINENO "mogan-api did not start" fi run_process mogan-engine "${MOGAN_BIN_DIR}/mogan-engine --config-file ${MOGAN_CONF_DIR}/mogan.conf" @@ -175,6 +172,7 @@ function stop_mogan { for serv in mogan-api mogan-engine mogan-scheduler mogan-consoleauth mogan-shellinaboxproxy; do stop_process $serv done + remove_uwsgi_config "$MOGAN_UWSGI_CONF" "$MOGAN_UWSGI_APP" } diff --git a/devstack/settings b/devstack/settings index dfb9f81f..91efb696 100644 --- a/devstack/settings +++ b/devstack/settings @@ -23,7 +23,15 @@ MOGAN_CONF_FILE=${MOGAN_CONF_DIR}/mogan.conf MOGAN_DEBUG=${MOGAN_DEBUG:-True} MOGAN_SERVICE_HOST=${MOGAN_SERVICE_HOST:-$SERVICE_HOST} -MOGAN_SERVICE_PORT=${MOGAN_SERVICE_PORT:-6688} MOGAN_SERVICE_PROTOCOL=${MOGAN_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL} MOGAN_ADMIN_USER=${MOGAN_ADMIN_USER:-mogan} + +if [[ -d ${MOGAN_DIR}/bin ]]; then + MOGAN_BIN_DIR=${MOGAN_DIR}/bin +else + MOGAN_BIN_DIR=$(get_python_exec_prefix) +fi + +MOGAN_UWSGI_CONF=$MOGAN_CONF_DIR/mogan-uwsgi.ini +MOGAN_UWSGI_APP=$MOGAN_BIN_DIR/mogan-api-wsgi diff --git a/doc/source/index.rst b/doc/source/index.rst index 3604214d..0874d17f 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -54,7 +54,7 @@ project. Setting Up Your Development Environment Advanced testing and guides ----------------------------- +--------------------------- .. toctree:: :maxdepth: 1 @@ -103,3 +103,11 @@ Running tests of Mogan :maxdepth: 1 dev/testing + +Installation and Setup +====================== + +.. toctree:: + :maxdepth: 1 + + installation/uwsgi diff --git a/doc/source/installation/uwsgi.rst b/doc/source/installation/uwsgi.rst new file mode 100644 index 00000000..020ecb4b --- /dev/null +++ b/doc/source/installation/uwsgi.rst @@ -0,0 +1,66 @@ +.. + Copyright (c) 2017 Intel Corporation + All Rights Reserved. + + 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. + + +Running Mogan API using uWSGI +============================= +The recommended way to deploy Mogan is have a web server such as Apache +or nginx to handle http requests and proxy these requests to Mogan WSGI +app running in uWSGI. Mogan comes with some configuration templates on +how to deploy the api service with Apache and uWSGI. + +app.wsgi +******** +The ``mogan/api/app.wsgi`` file contains a WSGI application of +Mogan API service. This file is installed with Mogan application +code. + +mogan-uwsgi.ini.sample +********************** +The ``mogan/etc/mogan-uwsgi.ini.sample`` file is a sample +configuration file for uWSGI server. Update the file to match your +system configuration. + +Steps to use these sample configuration files: + +1. Enable mod_proxy_uwsgi module + +* On Ubuntu install required uwsgi package + ``sudo apt-get install libapache2-mod-proxy-uwsgi``; enable using + ``sudo a2enmod proxy``, ``sudo a2enmod proxy_uwsgi``. +* On Fedora the required package is mod_proxy_uwsgi; enable by creating a file + ``/etc/httpd/conf.modules.d/11-proxy_uwsgi.conf`` containing + ``LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so`` + +2. On deb-based systems copy or symlink the file to + ``/etc/apache2/sites-available/mogan.conf``. For rpm-based systems the file should go into + ``/etc/httpd/conf.d/mogan.conf``. + +3. Enable Mogan site. On deb-based systems:: + + $ a2ensite mogan + $ service apache2 reload + + On rpm-based systems:: + + $ service httpd reload + +4. Copy mogan/etc/mogan-uwsgi.ini.sample to /etc/mogan/mogan-uwsgi.ini. + +5. Start Mogan api using uWSGI:: + + $ sudo pip install uwsgi + $ uwsgi /etc/mogan/mogan-uwsgi.ini diff --git a/etc/mogan-uwsgi.ini.sample b/etc/mogan-uwsgi.ini.sample new file mode 100644 index 00000000..eac63594 --- /dev/null +++ b/etc/mogan-uwsgi.ini.sample @@ -0,0 +1,25 @@ +[uwsgi] +wsgi-file = /usr/local/bin/mogan-api-wsgi + +chmod-socket = 666 + +socket = /var/run/uwsgi/mogan-api-wsgi.socket + +# Override the default size for headers from the 4k default. +buffer-size = 65535 + +# This is running standalone +master = true + +enable-threads = true + +# Tune this to your environment. +processes = 4 + +# uwsgi recommends this to prevent thundering herd on accept. +thunder-lock = true + +plugins = python + +# This ensures that file descriptors aren't shared between Searchlight processes. +lazy-apps = true diff --git a/mogan/api/app.py b/mogan/api/app.py index b9db3534..9f8ae17b 100644 --- a/mogan/api/app.py +++ b/mogan/api/app.py @@ -12,6 +12,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +import sys from oslo_config import cfg import pecan @@ -29,6 +30,10 @@ def get_pecan_config(): def setup_app(pecan_config=None, extra_hooks=None): + if not pecan_config: + pecan_config = get_pecan_config() + pecan.configuration.set_config(dict(pecan_config), overwrite=True) + app_hooks = [hooks.ConfigHook(), hooks.DBHook(), hooks.EngineAPIHook(), @@ -38,11 +43,6 @@ def setup_app(pecan_config=None, extra_hooks=None): if extra_hooks: app_hooks.extend(extra_hooks) - if not pecan_config: - pecan_config = get_pecan_config() - - pecan.configuration.set_config(dict(pecan_config), overwrite=True) - app = pecan.make_app( pecan_config.app.root, static_root=pecan_config.app.static_root, @@ -66,3 +66,9 @@ class VersionSelectorApplication(object): def __call__(self, environ, start_response): return self.v1(environ, start_response) + + +def build_wsgi_app(): + from mogan.common import service as mogan_service + mogan_service.prepare_service(sys.argv) + return setup_app() diff --git a/mogan/api/app.wsgi b/mogan/api/app.wsgi new file mode 100644 index 00000000..223137ce --- /dev/null +++ b/mogan/api/app.wsgi @@ -0,0 +1,21 @@ +# -*- mode: python -*- +# +# 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 under uwsgi. + +See http://pecan.readthedocs.org/en/latest/deployment.html for details. +""" + +from mogan.api import app + +application = app.build_wsgi_app() diff --git a/setup.cfg b/setup.cfg index 353eee24..caf7d50c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,6 +30,8 @@ oslo.config.opts = oslo.policy.policies = mogan.api = mogan.common.policy:list_policies +wsgi_scripts = + mogan-api-wsgi = mogan.api.app:build_wsgi_app console_scripts = mogan-api = mogan.cmd.api:main mogan-dbsync = mogan.cmd.dbsync:main