diff --git a/.zuul.yaml b/.zuul.yaml
index 57cbf88e1d..67ffe0805b 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -511,6 +511,16 @@
# changes to devstack w/o gating on it for all devstack changes.
# * nova-next: maintained by nova for unreleased/undefaulted
# things like cellsv2 and placement-api
+ # * neutron-fullstack-with-uwsgi: maintained by neutron for fullstack test
+ # when neutron-api is served by uwsgi, it's in exprimental for testing.
+ # the next cycle we can remove this job if things turn out to be
+ # stable enough.
+ # * neutron-functional-with-uwsgi: maintained by neutron for functional
+ # test. Next cycle we can remove this one if things turn out to be
+ # stable engouh with uwsgi.
+ # * neutron-tempest-with-uwsgi: maintained by neutron for tempest test.
+ # Next cycle we can remove this if everything run out stable enough.
+
experimental:
jobs:
- nova-cells-v1:
@@ -518,3 +528,6 @@
- ^.*\.rst$
- ^doc/.*$
- nova-next
+ - neutron-fullstack-with-uwsgi
+ - neutron-functional-with-uwsgi
+ - neutron-tempest-with-uwsgi
\ No newline at end of file
diff --git a/files/apache-neutron.template b/files/apache-neutron.template
new file mode 100644
index 0000000000..c7796b93bf
--- /dev/null
+++ b/files/apache-neutron.template
@@ -0,0 +1,36 @@
+Listen %PUBLICPORT%
+LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" %D(us)" neutron_combined
+
+
+ Require all granted
+
+
+
+ WSGIDaemonProcess neutron-server processes=%APIWORKERS% threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
+ WSGIProcessGroup neutron-server
+ WSGIScriptAlias / %NEUTRON_BIN%/neutron-api
+ WSGIApplicationGroup %{GLOBAL}
+ WSGIPassAuthorization On
+ ErrorLogFormat "%M"
+ ErrorLog /var/log/%APACHE_NAME%/neutron.log
+ CustomLog /var/log/%APACHE_NAME%/neutron_access.log neutron_combined
+ %SSLENGINE%
+ %SSLCERTFILE%
+ %SSLKEYFILE%
+
+
+
+%SSLLISTEN%
+%SSLLISTEN% %SSLENGINE%
+%SSLLISTEN% %SSLCERTFILE%
+%SSLLISTEN% %SSLKEYFILE%
+%SSLLISTEN%
+
+Alias /networking %NEUTRON_BIN%/neutron-api
+
+ SetHandler wsgi-script
+ Options +ExecCGI
+ WSGIProcessGroup neutron-server
+ WSGIApplicationGroup %{GLOBAL}
+ WSGIPassAuthorization On
+
diff --git a/lib/neutron b/lib/neutron
index 9f9b132377..4847e87f2f 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -28,6 +28,12 @@ set +o xtrace
# Set up default directories
GITDIR["python-neutronclient"]=$DEST/python-neutronclient
+# NEUTRON_DEPLOY_MOD_WSGI defines how neutron is deployed, allowed values:
+# - False (default) : Run neutron under Eventlet
+# - True : Run neutron under uwsgi
+# TODO(annp): Switching to uwsgi in next cycle if things turn out to be stable
+# enough
+NEUTRON_DEPLOY_MOD_WSGI=${NEUTRON_DEPLOY_MOD_WSGI:-False}
NEUTRON_AGENT=${NEUTRON_AGENT:-openvswitch}
NEUTRON_DIR=$DEST/neutron
NEUTRON_AUTH_CACHE_DIR=${NEUTRON_AUTH_CACHE_DIR:-/var/cache/neutron}
@@ -58,6 +64,8 @@ NEUTRON_CREATE_INITIAL_NETWORKS=${NEUTRON_CREATE_INITIAL_NETWORKS:-True}
NEUTRON_STATE_PATH=${NEUTRON_STATE_PATH:=$DATA_DIR/neutron}
NEUTRON_AUTH_CACHE_DIR=${NEUTRON_AUTH_CACHE_DIR:-/var/cache/neutron}
+NEUTRON_UWSGI_CONF=$NEUTRON_CONF_DIR/neutron-api-uwsgi.ini
+
# By default, use the ML2 plugin
NEUTRON_CORE_PLUGIN=${NEUTRON_CORE_PLUGIN:-ml2}
NEUTRON_CORE_PLUGIN_CONF_FILENAME=${NEUTRON_CORE_PLUGIN_CONF_FILENAME:-ml2_conf.ini}
@@ -286,7 +294,7 @@ function configure_neutron_new {
# Format logging
setup_logging $NEUTRON_CONF
- if is_service_enabled tls-proxy; then
+ if is_service_enabled tls-proxy && [ "$NEUTRON_DEPLOY_MOD_WSGI" == "False" ]; then
# Set the service port for a proxy to take the original
iniset $NEUTRON_CONF DEFAULT bind_port "$NEUTRON_SERVICE_PORT_INT"
iniset $NEUTRON_CONF oslo_middleware enable_proxy_headers_parsing True
@@ -357,6 +365,15 @@ function configure_neutron_nova_new {
# create_neutron_accounts() - Create required service accounts
function create_neutron_accounts_new {
+ local neutron_url
+
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then
+ neutron_url=$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST/networking/
+ else
+ neutron_url=$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT/
+ fi
+
+
if [[ "$ENABLED_SERVICES" =~ "neutron-api" ]]; then
create_service_user "neutron"
@@ -364,8 +381,7 @@ function create_neutron_accounts_new {
neutron_service=$(get_or_create_service "neutron" \
"network" "Neutron Service")
get_or_create_endpoint $neutron_service \
- "$REGION_NAME" \
- "$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT/"
+ "$REGION_NAME" "$neutron_url"
fi
}
@@ -427,6 +443,7 @@ function install_neutronclient {
function start_neutron_api {
local service_port=$NEUTRON_SERVICE_PORT
local service_protocol=$NEUTRON_SERVICE_PROTOCOL
+ local neutron_url
if is_service_enabled tls-proxy; then
service_port=$NEUTRON_SERVICE_PORT_INT
service_protocol="http"
@@ -440,17 +457,24 @@ function start_neutron_api {
opts+=" --config-file $cfg_file"
done
- # Start the Neutron service
- # TODO(sc68cal) Stop hard coding this
- run_process neutron-api "$NEUTRON_BIN_DIR/neutron-server $opts"
-
- if ! wait_for_service $SERVICE_TIMEOUT $service_protocol://$NEUTRON_SERVICE_HOST:$service_port; then
- die $LINENO "neutron-api did not start"
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then
+ run_process neutron-api "$NEUTRON_BIN_DIR/uwsgi --procname-prefix neutron-api --ini $NEUTRON_UWSGI_CONF"
+ neutron_url=$service_protocol://$NEUTRON_SERVICE_HOST/networking/
+ enable_service neutron-rpc-server
+ run_process neutron-rpc-server "$NEUTRON_BIN_DIR/neutron-rpc-server $opts"
+ else
+ # Start the Neutron service
+ # TODO(sc68cal) Stop hard coding this
+ run_process neutron-api "$NEUTRON_BIN_DIR/neutron-server $opts"
+ neutron_url=$service_protocol://$NEUTRON_SERVICE_HOST:$service_port
+ # Start proxy if enabled
+ if is_service_enabled tls-proxy; then
+ start_tls_proxy neutron '*' $NEUTRON_SERVICE_PORT $NEUTRON_SERVICE_HOST $NEUTRON_SERVICE_PORT_INT
+ fi
fi
- # Start proxy if enabled
- if is_service_enabled tls-proxy; then
- start_tls_proxy neutron '*' $NEUTRON_SERVICE_PORT $NEUTRON_SERVICE_HOST $NEUTRON_SERVICE_PORT_INT
+ if ! wait_for_service $SERVICE_TIMEOUT $neutron_url; then
+ die $LINENO "neutron-api did not start"
fi
}
@@ -497,6 +521,10 @@ function stop_neutron_new {
stop_process $serv
done
+ if is_service_enabled neutron-rpc-server; then
+ stop_process neutron-rpc-server
+ fi
+
if is_service_enabled neutron-dhcp; then
stop_process neutron-dhcp
pid=$(ps aux | awk '/[d]nsmasq.+interface=(tap|ns-)/ { print $2 }')
@@ -551,6 +579,13 @@ function neutron_deploy_rootwrap_filters_new {
# neutron-legacy is removed.
# TODO(sc68cal) Remove when neutron-legacy is no more.
function cleanup_neutron {
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then
+ stop_process neutron-api
+ stop_process neutron-rpc-server
+ remove_uwsgi_config "$NEUTRON_UWSGI_CONF" "$NEUTRON_BIN_DIR/neutron-api"
+ sudo rm -f $(apache_site_config_for neutron-api)
+ fi
+
if is_neutron_legacy_enabled; then
# Call back to old function
cleanup_mutnauq "$@"
@@ -566,6 +601,10 @@ function configure_neutron {
else
configure_neutron_new "$@"
fi
+
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then
+ write_uwsgi_config "$NEUTRON_UWSGI_CONF" "$NEUTRON_BIN_DIR/neutron-api" "/networking"
+ fi
}
function configure_neutron_nova {
diff --git a/lib/neutron-legacy b/lib/neutron-legacy
index 15bcfe36b9..9330b23802 100644
--- a/lib/neutron-legacy
+++ b/lib/neutron-legacy
@@ -86,6 +86,15 @@ NEUTRON_CONF_DIR=/etc/neutron
NEUTRON_CONF=$NEUTRON_CONF_DIR/neutron.conf
export NEUTRON_TEST_CONFIG_FILE=${NEUTRON_TEST_CONFIG_FILE:-"$NEUTRON_CONF_DIR/debug.ini"}
+# NEUTRON_DEPLOY_MOD_WSGI defines how neutron is deployed, allowed values:
+# - False (default) : Run neutron under Eventlet
+# - True : Run neutron under uwsgi
+# TODO(annp): Switching to uwsgi in next cycle if things turn out to be stable
+# enough
+NEUTRON_DEPLOY_MOD_WSGI=${NEUTRON_DEPLOY_MOD_WSGI:-False}
+
+NEUTRON_UWSGI_CONF=$NEUTRON_CONF_DIR/neutron-api-uwsgi.ini
+
# Agent binaries. Note, binary paths for other agents are set in per-service
# scripts in lib/neutron_plugins/services/
AGENT_DHCP_BINARY="$NEUTRON_BIN_DIR/neutron-dhcp-agent"
@@ -402,6 +411,13 @@ function create_nova_conf_neutron {
# Migrated from keystone_data.sh
function create_mutnauq_accounts {
+ local neutron_url
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then
+ neutron_url=$Q_PROTOCOL://$SERVICE_HOST/networking/
+ else
+ neutron_url=$Q_PROTOCOL://$SERVICE_HOST:$Q_PORT/
+ fi
+
if [[ "$ENABLED_SERVICES" =~ "q-svc" ]]; then
create_service_user "neutron"
@@ -409,8 +425,7 @@ function create_mutnauq_accounts {
get_or_create_service "neutron" "network" "Neutron Service"
get_or_create_endpoint \
"network" \
- "$REGION_NAME" \
- "$Q_PROTOCOL://$SERVICE_HOST:$Q_PORT/"
+ "$REGION_NAME" "$neutron_url"
fi
}
@@ -460,6 +475,7 @@ function start_neutron_service_and_check {
local service_port=$Q_PORT
local service_protocol=$Q_PROTOCOL
local cfg_file_options
+ local neutron_url
cfg_file_options="$(determine_config_files neutron-server)"
@@ -468,16 +484,24 @@ function start_neutron_service_and_check {
service_protocol="http"
fi
# Start the Neutron service
- run_process q-svc "$NEUTRON_BIN_DIR/neutron-server $cfg_file_options"
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then
+ enable_service neutron-api
+ run_process neutron-api "$NEUTRON_BIN_DIR/uwsgi --procname-prefix neutron-api --ini $NEUTRON_UWSGI_CONF"
+ neutron_url=$Q_PROTOCOL://$Q_HOST/networking/
+ enable_service neutron-rpc-server
+ run_process neutron-rpc-server "$NEUTRON_BIN_DIR/neutron-rpc-server $cfg_file_options"
+ else
+ run_process q-svc "$NEUTRON_BIN_DIR/neutron-server $cfg_file_options"
+ neutron_url=$service_protocol://$Q_HOST:$service_port
+ # Start proxy if enabled
+ if is_service_enabled tls-proxy; then
+ start_tls_proxy neutron '*' $Q_PORT $Q_HOST $Q_PORT_INT
+ fi
+ fi
echo "Waiting for Neutron to start..."
- local testcmd="wget ${ssl_ca} --no-proxy -q -O- $service_protocol://$Q_HOST:$service_port"
+ local testcmd="wget ${ssl_ca} --no-proxy -q -O- $neutron_url"
test_with_retry "$testcmd" "Neutron did not start" $SERVICE_TIMEOUT
-
- # Start proxy if enabled
- if is_service_enabled tls-proxy; then
- start_tls_proxy neutron '*' $Q_PORT $Q_HOST $Q_PORT_INT
- fi
}
# Control of the l2 agent is separated out to make it easier to test partial
@@ -532,7 +556,12 @@ function stop_mutnauq_other {
[ ! -z "$pid" ] && sudo kill -9 $pid
fi
- stop_process q-svc
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then
+ stop_process neutron-rpc-server
+ stop_process neutron-api
+ else
+ stop_process q-svc
+ fi
if is_service_enabled q-l3; then
sudo pkill -f "radvd -C $DATA_DIR/neutron/ra"
@@ -715,7 +744,7 @@ function _configure_neutron_common {
# Format logging
setup_logging $NEUTRON_CONF
- if is_service_enabled tls-proxy; then
+ if is_service_enabled tls-proxy && [ "$NEUTRON_DEPLOY_MOD_WSGI" == "False" ]; then
# Set the service port for a proxy to take the original
iniset $NEUTRON_CONF DEFAULT bind_port "$Q_PORT_INT"
iniset $NEUTRON_CONF oslo_middleware enable_proxy_headers_parsing True