This patch provides a new mechanism to deploy Neutron using
WSGI script. This also starts a Neutron RPC server process
when the Neutron API is loaded via a WSGI entry point to
serve the agents.
Co-Authored-By: Victor Morales <victor.morales@intel.com>
Co-Authored-By: Nguyen Phuong An <AnNP@vn.fujitsu.com>
Change-Id: I16a199b04858bfc03ef50d9883154dba8b0d66ea
Depends-On: https://review.openstack.org/#/c/580049/
Partially-implements: blueprint run-in-wsgi-server
... | ... |
@@ -511,6 +511,16 @@ |
511 | 511 |
# changes to devstack w/o gating on it for all devstack changes. |
512 | 512 |
# * nova-next: maintained by nova for unreleased/undefaulted |
513 | 513 |
# things like cellsv2 and placement-api |
514 |
+ # * neutron-fullstack-with-uwsgi: maintained by neutron for fullstack test |
|
515 |
+ # when neutron-api is served by uwsgi, it's in exprimental for testing. |
|
516 |
+ # the next cycle we can remove this job if things turn out to be |
|
517 |
+ # stable enough. |
|
518 |
+ # * neutron-functional-with-uwsgi: maintained by neutron for functional |
|
519 |
+ # test. Next cycle we can remove this one if things turn out to be |
|
520 |
+ # stable engouh with uwsgi. |
|
521 |
+ # * neutron-tempest-with-uwsgi: maintained by neutron for tempest test. |
|
522 |
+ # Next cycle we can remove this if everything run out stable enough. |
|
523 |
+ |
|
514 | 524 |
experimental: |
515 | 525 |
jobs: |
516 | 526 |
- nova-cells-v1: |
... | ... |
@@ -518,3 +528,6 @@ |
518 | 518 |
- ^.*\.rst$ |
519 | 519 |
- ^doc/.*$ |
520 | 520 |
- nova-next |
521 |
+ - neutron-fullstack-with-uwsgi |
|
522 |
+ - neutron-functional-with-uwsgi |
|
523 |
+ - neutron-tempest-with-uwsgi |
|
521 | 524 |
\ No newline at end of file |
522 | 525 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,36 @@ |
0 |
+Listen %PUBLICPORT% |
|
1 |
+LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" %D(us)" neutron_combined |
|
2 |
+ |
|
3 |
+<Directory %NEUTRON_BIN%> |
|
4 |
+ Require all granted |
|
5 |
+</Directory> |
|
6 |
+ |
|
7 |
+<VirtualHost *:%PUBLICPORT%> |
|
8 |
+ WSGIDaemonProcess neutron-server processes=%APIWORKERS% threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV% |
|
9 |
+ WSGIProcessGroup neutron-server |
|
10 |
+ WSGIScriptAlias / %NEUTRON_BIN%/neutron-api |
|
11 |
+ WSGIApplicationGroup %{GLOBAL} |
|
12 |
+ WSGIPassAuthorization On |
|
13 |
+ ErrorLogFormat "%M" |
|
14 |
+ ErrorLog /var/log/%APACHE_NAME%/neutron.log |
|
15 |
+ CustomLog /var/log/%APACHE_NAME%/neutron_access.log neutron_combined |
|
16 |
+ %SSLENGINE% |
|
17 |
+ %SSLCERTFILE% |
|
18 |
+ %SSLKEYFILE% |
|
19 |
+</VirtualHost> |
|
20 |
+ |
|
21 |
+ |
|
22 |
+%SSLLISTEN%<VirtualHost *:443> |
|
23 |
+%SSLLISTEN% %SSLENGINE% |
|
24 |
+%SSLLISTEN% %SSLCERTFILE% |
|
25 |
+%SSLLISTEN% %SSLKEYFILE% |
|
26 |
+%SSLLISTEN%</VirtualHost> |
|
27 |
+ |
|
28 |
+Alias /networking %NEUTRON_BIN%/neutron-api |
|
29 |
+<Location /networking> |
|
30 |
+ SetHandler wsgi-script |
|
31 |
+ Options +ExecCGI |
|
32 |
+ WSGIProcessGroup neutron-server |
|
33 |
+ WSGIApplicationGroup %{GLOBAL} |
|
34 |
+ WSGIPassAuthorization On |
|
35 |
+</Location> |
... | ... |
@@ -28,6 +28,12 @@ set +o xtrace |
28 | 28 |
# Set up default directories |
29 | 29 |
GITDIR["python-neutronclient"]=$DEST/python-neutronclient |
30 | 30 |
|
31 |
+# NEUTRON_DEPLOY_MOD_WSGI defines how neutron is deployed, allowed values: |
|
32 |
+# - False (default) : Run neutron under Eventlet |
|
33 |
+# - True : Run neutron under uwsgi |
|
34 |
+# TODO(annp): Switching to uwsgi in next cycle if things turn out to be stable |
|
35 |
+# enough |
|
36 |
+NEUTRON_DEPLOY_MOD_WSGI=${NEUTRON_DEPLOY_MOD_WSGI:-False} |
|
31 | 37 |
NEUTRON_AGENT=${NEUTRON_AGENT:-openvswitch} |
32 | 38 |
NEUTRON_DIR=$DEST/neutron |
33 | 39 |
NEUTRON_AUTH_CACHE_DIR=${NEUTRON_AUTH_CACHE_DIR:-/var/cache/neutron} |
... | ... |
@@ -58,6 +64,8 @@ NEUTRON_CREATE_INITIAL_NETWORKS=${NEUTRON_CREATE_INITIAL_NETWORKS:-True} |
58 | 58 |
NEUTRON_STATE_PATH=${NEUTRON_STATE_PATH:=$DATA_DIR/neutron} |
59 | 59 |
NEUTRON_AUTH_CACHE_DIR=${NEUTRON_AUTH_CACHE_DIR:-/var/cache/neutron} |
60 | 60 |
|
61 |
+NEUTRON_UWSGI_CONF=$NEUTRON_CONF_DIR/neutron-api-uwsgi.ini |
|
62 |
+ |
|
61 | 63 |
# By default, use the ML2 plugin |
62 | 64 |
NEUTRON_CORE_PLUGIN=${NEUTRON_CORE_PLUGIN:-ml2} |
63 | 65 |
NEUTRON_CORE_PLUGIN_CONF_FILENAME=${NEUTRON_CORE_PLUGIN_CONF_FILENAME:-ml2_conf.ini} |
... | ... |
@@ -286,7 +294,7 @@ function configure_neutron_new { |
286 | 286 |
# Format logging |
287 | 287 |
setup_logging $NEUTRON_CONF |
288 | 288 |
|
289 |
- if is_service_enabled tls-proxy; then |
|
289 |
+ if is_service_enabled tls-proxy && [ "$NEUTRON_DEPLOY_MOD_WSGI" == "False" ]; then |
|
290 | 290 |
# Set the service port for a proxy to take the original |
291 | 291 |
iniset $NEUTRON_CONF DEFAULT bind_port "$NEUTRON_SERVICE_PORT_INT" |
292 | 292 |
iniset $NEUTRON_CONF oslo_middleware enable_proxy_headers_parsing True |
... | ... |
@@ -357,6 +365,15 @@ function configure_neutron_nova_new { |
357 | 357 |
|
358 | 358 |
# create_neutron_accounts() - Create required service accounts |
359 | 359 |
function create_neutron_accounts_new { |
360 |
+ local neutron_url |
|
361 |
+ |
|
362 |
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then |
|
363 |
+ neutron_url=$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST/networking/ |
|
364 |
+ else |
|
365 |
+ neutron_url=$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT/ |
|
366 |
+ fi |
|
367 |
+ |
|
368 |
+ |
|
360 | 369 |
if [[ "$ENABLED_SERVICES" =~ "neutron-api" ]]; then |
361 | 370 |
|
362 | 371 |
create_service_user "neutron" |
... | ... |
@@ -364,8 +381,7 @@ function create_neutron_accounts_new { |
364 | 364 |
neutron_service=$(get_or_create_service "neutron" \ |
365 | 365 |
"network" "Neutron Service") |
366 | 366 |
get_or_create_endpoint $neutron_service \ |
367 |
- "$REGION_NAME" \ |
|
368 |
- "$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT/" |
|
367 |
+ "$REGION_NAME" "$neutron_url" |
|
369 | 368 |
fi |
370 | 369 |
} |
371 | 370 |
|
... | ... |
@@ -427,6 +443,7 @@ function install_neutronclient { |
427 | 427 |
function start_neutron_api { |
428 | 428 |
local service_port=$NEUTRON_SERVICE_PORT |
429 | 429 |
local service_protocol=$NEUTRON_SERVICE_PROTOCOL |
430 |
+ local neutron_url |
|
430 | 431 |
if is_service_enabled tls-proxy; then |
431 | 432 |
service_port=$NEUTRON_SERVICE_PORT_INT |
432 | 433 |
service_protocol="http" |
... | ... |
@@ -440,17 +457,24 @@ function start_neutron_api { |
440 | 440 |
opts+=" --config-file $cfg_file" |
441 | 441 |
done |
442 | 442 |
|
443 |
- # Start the Neutron service |
|
444 |
- # TODO(sc68cal) Stop hard coding this |
|
445 |
- run_process neutron-api "$NEUTRON_BIN_DIR/neutron-server $opts" |
|
446 |
- |
|
447 |
- if ! wait_for_service $SERVICE_TIMEOUT $service_protocol://$NEUTRON_SERVICE_HOST:$service_port; then |
|
448 |
- die $LINENO "neutron-api did not start" |
|
443 |
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then |
|
444 |
+ run_process neutron-api "$NEUTRON_BIN_DIR/uwsgi --procname-prefix neutron-api --ini $NEUTRON_UWSGI_CONF" |
|
445 |
+ neutron_url=$service_protocol://$NEUTRON_SERVICE_HOST/networking/ |
|
446 |
+ enable_service neutron-rpc-server |
|
447 |
+ run_process neutron-rpc-server "$NEUTRON_BIN_DIR/neutron-rpc-server $opts" |
|
448 |
+ else |
|
449 |
+ # Start the Neutron service |
|
450 |
+ # TODO(sc68cal) Stop hard coding this |
|
451 |
+ run_process neutron-api "$NEUTRON_BIN_DIR/neutron-server $opts" |
|
452 |
+ neutron_url=$service_protocol://$NEUTRON_SERVICE_HOST:$service_port |
|
453 |
+ # Start proxy if enabled |
|
454 |
+ if is_service_enabled tls-proxy; then |
|
455 |
+ start_tls_proxy neutron '*' $NEUTRON_SERVICE_PORT $NEUTRON_SERVICE_HOST $NEUTRON_SERVICE_PORT_INT |
|
456 |
+ fi |
|
449 | 457 |
fi |
450 | 458 |
|
451 |
- # Start proxy if enabled |
|
452 |
- if is_service_enabled tls-proxy; then |
|
453 |
- start_tls_proxy neutron '*' $NEUTRON_SERVICE_PORT $NEUTRON_SERVICE_HOST $NEUTRON_SERVICE_PORT_INT |
|
459 |
+ if ! wait_for_service $SERVICE_TIMEOUT $neutron_url; then |
|
460 |
+ die $LINENO "neutron-api did not start" |
|
454 | 461 |
fi |
455 | 462 |
} |
456 | 463 |
|
... | ... |
@@ -497,6 +521,10 @@ function stop_neutron_new { |
497 | 497 |
stop_process $serv |
498 | 498 |
done |
499 | 499 |
|
500 |
+ if is_service_enabled neutron-rpc-server; then |
|
501 |
+ stop_process neutron-rpc-server |
|
502 |
+ fi |
|
503 |
+ |
|
500 | 504 |
if is_service_enabled neutron-dhcp; then |
501 | 505 |
stop_process neutron-dhcp |
502 | 506 |
pid=$(ps aux | awk '/[d]nsmasq.+interface=(tap|ns-)/ { print $2 }') |
... | ... |
@@ -551,6 +579,13 @@ function neutron_deploy_rootwrap_filters_new { |
551 | 551 |
# neutron-legacy is removed. |
552 | 552 |
# TODO(sc68cal) Remove when neutron-legacy is no more. |
553 | 553 |
function cleanup_neutron { |
554 |
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then |
|
555 |
+ stop_process neutron-api |
|
556 |
+ stop_process neutron-rpc-server |
|
557 |
+ remove_uwsgi_config "$NEUTRON_UWSGI_CONF" "$NEUTRON_BIN_DIR/neutron-api" |
|
558 |
+ sudo rm -f $(apache_site_config_for neutron-api) |
|
559 |
+ fi |
|
560 |
+ |
|
554 | 561 |
if is_neutron_legacy_enabled; then |
555 | 562 |
# Call back to old function |
556 | 563 |
cleanup_mutnauq "$@" |
... | ... |
@@ -566,6 +601,10 @@ function configure_neutron { |
566 | 566 |
else |
567 | 567 |
configure_neutron_new "$@" |
568 | 568 |
fi |
569 |
+ |
|
570 |
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then |
|
571 |
+ write_uwsgi_config "$NEUTRON_UWSGI_CONF" "$NEUTRON_BIN_DIR/neutron-api" "/networking" |
|
572 |
+ fi |
|
569 | 573 |
} |
570 | 574 |
|
571 | 575 |
function configure_neutron_nova { |
... | ... |
@@ -86,6 +86,15 @@ NEUTRON_CONF_DIR=/etc/neutron |
86 | 86 |
NEUTRON_CONF=$NEUTRON_CONF_DIR/neutron.conf |
87 | 87 |
export NEUTRON_TEST_CONFIG_FILE=${NEUTRON_TEST_CONFIG_FILE:-"$NEUTRON_CONF_DIR/debug.ini"} |
88 | 88 |
|
89 |
+# NEUTRON_DEPLOY_MOD_WSGI defines how neutron is deployed, allowed values: |
|
90 |
+# - False (default) : Run neutron under Eventlet |
|
91 |
+# - True : Run neutron under uwsgi |
|
92 |
+# TODO(annp): Switching to uwsgi in next cycle if things turn out to be stable |
|
93 |
+# enough |
|
94 |
+NEUTRON_DEPLOY_MOD_WSGI=${NEUTRON_DEPLOY_MOD_WSGI:-False} |
|
95 |
+ |
|
96 |
+NEUTRON_UWSGI_CONF=$NEUTRON_CONF_DIR/neutron-api-uwsgi.ini |
|
97 |
+ |
|
89 | 98 |
# Agent binaries. Note, binary paths for other agents are set in per-service |
90 | 99 |
# scripts in lib/neutron_plugins/services/ |
91 | 100 |
AGENT_DHCP_BINARY="$NEUTRON_BIN_DIR/neutron-dhcp-agent" |
... | ... |
@@ -402,6 +411,13 @@ function create_nova_conf_neutron { |
402 | 402 |
|
403 | 403 |
# Migrated from keystone_data.sh |
404 | 404 |
function create_mutnauq_accounts { |
405 |
+ local neutron_url |
|
406 |
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then |
|
407 |
+ neutron_url=$Q_PROTOCOL://$SERVICE_HOST/networking/ |
|
408 |
+ else |
|
409 |
+ neutron_url=$Q_PROTOCOL://$SERVICE_HOST:$Q_PORT/ |
|
410 |
+ fi |
|
411 |
+ |
|
405 | 412 |
if [[ "$ENABLED_SERVICES" =~ "q-svc" ]]; then |
406 | 413 |
|
407 | 414 |
create_service_user "neutron" |
... | ... |
@@ -409,8 +425,7 @@ function create_mutnauq_accounts { |
409 | 409 |
get_or_create_service "neutron" "network" "Neutron Service" |
410 | 410 |
get_or_create_endpoint \ |
411 | 411 |
"network" \ |
412 |
- "$REGION_NAME" \ |
|
413 |
- "$Q_PROTOCOL://$SERVICE_HOST:$Q_PORT/" |
|
412 |
+ "$REGION_NAME" "$neutron_url" |
|
414 | 413 |
fi |
415 | 414 |
} |
416 | 415 |
|
... | ... |
@@ -460,6 +475,7 @@ function start_neutron_service_and_check { |
460 | 460 |
local service_port=$Q_PORT |
461 | 461 |
local service_protocol=$Q_PROTOCOL |
462 | 462 |
local cfg_file_options |
463 |
+ local neutron_url |
|
463 | 464 |
|
464 | 465 |
cfg_file_options="$(determine_config_files neutron-server)" |
465 | 466 |
|
... | ... |
@@ -468,16 +484,24 @@ function start_neutron_service_and_check { |
468 | 468 |
service_protocol="http" |
469 | 469 |
fi |
470 | 470 |
# Start the Neutron service |
471 |
- run_process q-svc "$NEUTRON_BIN_DIR/neutron-server $cfg_file_options" |
|
471 |
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then |
|
472 |
+ enable_service neutron-api |
|
473 |
+ run_process neutron-api "$NEUTRON_BIN_DIR/uwsgi --procname-prefix neutron-api --ini $NEUTRON_UWSGI_CONF" |
|
474 |
+ neutron_url=$Q_PROTOCOL://$Q_HOST/networking/ |
|
475 |
+ enable_service neutron-rpc-server |
|
476 |
+ run_process neutron-rpc-server "$NEUTRON_BIN_DIR/neutron-rpc-server $cfg_file_options" |
|
477 |
+ else |
|
478 |
+ run_process q-svc "$NEUTRON_BIN_DIR/neutron-server $cfg_file_options" |
|
479 |
+ neutron_url=$service_protocol://$Q_HOST:$service_port |
|
480 |
+ # Start proxy if enabled |
|
481 |
+ if is_service_enabled tls-proxy; then |
|
482 |
+ start_tls_proxy neutron '*' $Q_PORT $Q_HOST $Q_PORT_INT |
|
483 |
+ fi |
|
484 |
+ fi |
|
472 | 485 |
echo "Waiting for Neutron to start..." |
473 | 486 |
|
474 |
- local testcmd="wget ${ssl_ca} --no-proxy -q -O- $service_protocol://$Q_HOST:$service_port" |
|
487 |
+ local testcmd="wget ${ssl_ca} --no-proxy -q -O- $neutron_url" |
|
475 | 488 |
test_with_retry "$testcmd" "Neutron did not start" $SERVICE_TIMEOUT |
476 |
- |
|
477 |
- # Start proxy if enabled |
|
478 |
- if is_service_enabled tls-proxy; then |
|
479 |
- start_tls_proxy neutron '*' $Q_PORT $Q_HOST $Q_PORT_INT |
|
480 |
- fi |
|
481 | 489 |
} |
482 | 490 |
|
483 | 491 |
# Control of the l2 agent is separated out to make it easier to test partial |
... | ... |
@@ -532,7 +556,12 @@ function stop_mutnauq_other { |
532 | 532 |
[ ! -z "$pid" ] && sudo kill -9 $pid |
533 | 533 |
fi |
534 | 534 |
|
535 |
- stop_process q-svc |
|
535 |
+ if [ "$NEUTRON_DEPLOY_MOD_WSGI" == "True" ]; then |
|
536 |
+ stop_process neutron-rpc-server |
|
537 |
+ stop_process neutron-api |
|
538 |
+ else |
|
539 |
+ stop_process q-svc |
|
540 |
+ fi |
|
536 | 541 |
|
537 | 542 |
if is_service_enabled q-l3; then |
538 | 543 |
sudo pkill -f "radvd -C $DATA_DIR/neutron/ra" |
... | ... |
@@ -715,7 +744,7 @@ function _configure_neutron_common { |
715 | 715 |
# Format logging |
716 | 716 |
setup_logging $NEUTRON_CONF |
717 | 717 |
|
718 |
- if is_service_enabled tls-proxy; then |
|
718 |
+ if is_service_enabled tls-proxy && [ "$NEUTRON_DEPLOY_MOD_WSGI" == "False" ]; then |
|
719 | 719 |
# Set the service port for a proxy to take the original |
720 | 720 |
iniset $NEUTRON_CONF DEFAULT bind_port "$Q_PORT_INT" |
721 | 721 |
iniset $NEUTRON_CONF oslo_middleware enable_proxy_headers_parsing True |