diff --git a/devstack/files/apache-mistral-api.template b/devstack/files/apache-mistral-api.template new file mode 100644 index 000000000..83be271f7 --- /dev/null +++ b/devstack/files/apache-mistral-api.template @@ -0,0 +1,28 @@ +Listen %PUBLICPORT% + + + WSGIDaemonProcess mistral-api processes=%API_WORKERS% threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV% + WSGIProcessGroup mistral-api + WSGIScriptAlias / %MISTRAL_BIN_DIR%/mistral-wsgi-api + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + AllowEncodedSlashes On + = 2.4> + ErrorLogFormat "%{cu}t %M" + + ErrorLog /var/log/%APACHE_NAME%/mistral_api.log + CustomLog /var/log/%APACHE_NAME%/mistral_api_access.log combined + %SSLENGINE% + %SSLCERTFILE% + %SSLKEYFILE% + + + = 2.4> + Require all granted + + + Order allow,deny + Allow from all + + + diff --git a/devstack/plugin.sh b/devstack/plugin.sh index da72012f9..c07735e2a 100755 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -21,6 +21,11 @@ else MISTRAL_BIN_DIR=$(get_python_exec_prefix) fi +# Toggle for deploying Mistral API under HTTPD + mod_wsgi +MISTRAL_USE_MOD_WSGI=${MISTRAL_USE_MOD_WSGI:-True} + +MISTRAL_FILES_DIR=$MISTRAL_DIR/devstack/files + # create_mistral_accounts - Set up common required mistral accounts # # Tenant User Roles @@ -100,6 +105,10 @@ function configure_mistral { if [ "$MISTRAL_RPC_IMPLEMENTATION" ]; then iniset $MISTRAL_CONF_FILE DEFAULT rpc_implementation $MISTRAL_RPC_IMPLEMENTATION fi + + if [ "$MISTRAL_USE_MOD_WSGI" == "True" ]; then + _config_mistral_apache_wsgi + fi } @@ -121,6 +130,10 @@ function install_mistral { if is_service_enabled horizon; then _install_mistraldashboard fi + + if [ "$MISTRAL_USE_MOD_WSGI" == "True" ]; then + install_apache_wsgi + fi } @@ -145,9 +158,19 @@ function install_mistral_pythonclient { # start_mistral - Start running processes, including screen function start_mistral { + # If the site is not enabled then we are in a grenade scenario + local enabled_site_file + enabled_site_file=$(apache_site_config_for mistral-api) + if is_service_enabled mistral-api && is_service_enabled mistral-engine && is_service_enabled mistral-executor && is_service_enabled mistral-event-engine ; then echo_summary "Installing all mistral services in separate processes" - run_process mistral-api "$MISTRAL_BIN_DIR/mistral-server --server api --config-file $MISTRAL_CONF_DIR/mistral.conf" + if [ -f ${enabled_site_file} ] && [ "$MISTRAL_USE_MOD_WSGI" == "True" ]; then + enable_apache_site mistral-api + restart_apache_server + tail_log mistral-api /var/log/$APACHE_NAME/mistral_api.log + else + run_process mistral-api "$MISTRAL_BIN_DIR/mistral-server --server api --config-file $MISTRAL_CONF_DIR/mistral.conf" + fi run_process mistral-engine "$MISTRAL_BIN_DIR/mistral-server --server engine --config-file $MISTRAL_CONF_DIR/mistral.conf" run_process mistral-executor "$MISTRAL_BIN_DIR/mistral-server --server executor --config-file $MISTRAL_CONF_DIR/mistral.conf" run_process mistral-event-engine "$MISTRAL_BIN_DIR/mistral-server --server event-engine --config-file $MISTRAL_CONF_DIR/mistral.conf" @@ -161,9 +184,17 @@ function start_mistral { # stop_mistral - Stop running processes function stop_mistral { # Kill the Mistral screen windows - for serv in mistral mistral-api mistral-engine mistral-executor mistral-event-engine; do + local serv + for serv in mistral mistral-engine mistral-executor mistral-event-engine; do stop_process $serv done + + if [ "$MISTRAL_USE_MOD_WSGI" == "True" ]; then + disable_apache_site mistral-api + restart_apache_server + else + stop_process mistral-api + fi } @@ -171,6 +202,11 @@ function cleanup_mistral { if is_service_enabled horizon; then _mistral_cleanup_mistraldashboard fi + + if [ "$MISTRAL_USE_MOD_WSGI" == "True" ]; then + _mistral_cleanup_apache_wsgi + fi + sudo rm -rf $MISTRAL_CONF_DIR } @@ -178,6 +214,33 @@ function _mistral_cleanup_mistraldashboard { rm -f $HORIZON_DIR/openstack_dashboard/local/enabled/_50_mistral.py } +function _mistral_cleanup_apache_wsgi { + sudo rm -f $(apache_site_config_for mistral-api) +} + +# _config_mistral_apache_wsgi() - Set WSGI config files for Mistral +function _config_mistral_apache_wsgi { + local mistral_apache_conf + mistral_apache_conf=$(apache_site_config_for mistral-api) + local mistral_ssl="" + local mistral_certfile="" + local mistral_keyfile="" + local mistral_api_port=$MISTRAL_SERVICE_PORT + local venv_path="" + + sudo cp $MISTRAL_FILES_DIR/apache-mistral-api.template $mistral_apache_conf + sudo sed -e " + s|%PUBLICPORT%|$mistral_api_port|g; + s|%APACHE_NAME%|$APACHE_NAME|g; + s|%MISTRAL_BIN_DIR%|$MISTRAL_BIN_DIR|g; + s|%API_WORKERS%|$API_WORKERS|g; + s|%SSLENGINE%|$mistral_ssl|g; + s|%SSLCERTFILE%|$mistral_certfile|g; + s|%SSLKEYFILE%|$mistral_keyfile|g; + s|%USER%|$STACK_USER|g; + s|%VIRTUALENV%|$venv_path|g + " -i $mistral_apache_conf +} if is_service_enabled mistral; then if [[ "$1" == "stack" && "$2" == "install" ]]; then diff --git a/mistral/api/wsgi.py b/mistral/api/wsgi.py index 0374aba8a..949d9b522 100644 --- a/mistral/api/wsgi.py +++ b/mistral/api/wsgi.py @@ -15,9 +15,15 @@ from mistral.api import app from mistral import config + # By default, oslo.config parses the CLI args if no args is provided. # As a result, invoking this wsgi script from gunicorn leads to the error # with argparse complaining that the CLI options have already been parsed. -config.parse_args(args=[]) +def init_application(): + config.parse_args(args=[]) -application = app.setup_app() + return app.setup_app() + + +if __name__ == '__main__': + application = init_application() diff --git a/setup.cfg b/setup.cfg index 9ee531c28..33bc0fecd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,6 +40,9 @@ console_scripts = mistral-server = mistral.cmd.launch:main mistral-db-manage = mistral.db.sqlalchemy.migration.cli:main +wsgi_scripts = + mistral-wsgi-api = mistral.api.wsgi:init_application + mistral.engine.rpc_backend = oslo_client = mistral.engine.rpc_backend.oslo.oslo_client:OsloRPCClient oslo_server = mistral.engine.rpc_backend.oslo.oslo_server:OsloRPCServer