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