Merge "Run neutron-api behind uwsgi"
diff --git a/README.rst b/README.rst
index 7ee2ea3..8986c63 100644
--- a/README.rst
+++ b/README.rst
@@ -1602,7 +1602,9 @@
           eventletwsgi:
             level: 'DEBUG'
     ......
-Neutron server with memcached caching and security strategy:
+
+Neutron server with memcached caching and security strategy
+-----------------------------------------------------------
 
 .. code-block:: yaml
 
@@ -1622,6 +1624,21 @@
             strategy: ENCRYPT
             secret_key: secret
 
+
+Neutron API behind uWSGI (experimental)
+---------------------------------------
+
+.. code-block:: yaml
+
+    neutron:
+      server:
+        wsgi:
+          enabled: true
+          threads: 32
+          workers: 64
+          logto: /var/log/neutron/neutron-server.log
+
+
 Upgrades
 ========
 
diff --git a/neutron/files/wsgi/rpc-server.systemd b/neutron/files/wsgi/rpc-server.systemd
new file mode 100644
index 0000000..b0e5425
--- /dev/null
+++ b/neutron/files/wsgi/rpc-server.systemd
@@ -0,0 +1,16 @@
+[Unit]
+Description=OpenStack Neutron RPC Server
+After=rabbitmq-server.service
+
+[Service]
+User=neutron
+Group=neutron
+Type=notify
+ExecStart=/usr/bin/neutron-rpc-server --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugin.ini --log-file=/var/log/neutron/neutron-rpc-server.log
+PrivateTmp=true
+NotifyAccess=all
+KillMode=process
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
diff --git a/neutron/files/wsgi/server.systemd b/neutron/files/wsgi/server.systemd
new file mode 100644
index 0000000..12cb149
--- /dev/null
+++ b/neutron/files/wsgi/server.systemd
@@ -0,0 +1,17 @@
+[Unit]
+Description=OpenStack Neutron API Server
+After=mysql.service postgresql.service keystone.service syslog.target
+
+[Service]
+User=neutron
+Group=neutron
+ExecStart=/usr/bin/uwsgi --ini /etc/neutron/neutron-api-uwsgi.ini
+RuntimeDirectory=uwsgi
+Restart=always
+KillSignal=SIGQUIT
+Type=notify
+StandardError=syslog
+NotifyAccess=all
+
+[Install]
+WantedBy=multi-user.target
diff --git a/neutron/files/wsgi/uwsgi.ini b/neutron/files/wsgi/uwsgi.ini
new file mode 100644
index 0000000..8107dbc
--- /dev/null
+++ b/neutron/files/wsgi/uwsgi.ini
@@ -0,0 +1,19 @@
+{%- from "neutron/map.jinja" import server with context %}
+[uwsgi]
+http = {{ server.bind.address }}:{{ server.bind.port }}
+wsgi-file = /usr/bin/neutron-api
+plugins = python
+master = true
+lazy-apps = true
+add-header = Connection: close
+buffer-size = 65535
+thunder-lock = true
+die-on-term = true
+enable-threads = true
+threads = {{ server.wsgi.get('threads', 1) }}
+workers = {{ server.wsgi.get('workers', grains.num_cpus) }}
+{%- if server.wsgi.logto is defined %}
+logto = {{ server.wsgi.logto }}
+{%- else %}
+disable-logging = true
+{%- endif %}
diff --git a/neutron/map.jinja b/neutron/map.jinja
index 1670a3f..8312d13 100644
--- a/neutron/map.jinja
+++ b/neutron/map.jinja
@@ -119,10 +119,12 @@
 }, merge=pillar.neutron.get('gateway', {}), base='BaseDefaults') %}
 
 {%- set sfc_enabled = pillar.neutron.get('server', {}).get('sfc', {}).get('enabled', False) %}
-{%- set server_pkgs_list = ['neutron-server','python-neutron-lbaas', 'gettext-base', 'python-pycadf'] %}
-{%- if sfc_enabled %}
-{%- do server_pkgs_list.append('python-networking-sfc') %}
-{%- endif %}
+{%- set wsgi_enabled = pillar.neutron.get('server', {}).get('wsgi', {}).get('enabled', False) %}
+{%- set server_pkgs_list = ['python-neutron-lbaas'] %}
+{%- do server_pkgs_list.append('uwsgi-plugin-python' if wsgi_enabled else 'neutron-server') %}
+{%- do server_pkgs_list.append('python-networking-sfc') if sfc_enabled %}
+{%- set server_services_list = ['neutron-server'] %}
+{%- do server_services_list.append('neutron-rpc-server') if wsgi_enabled %}
 
 {% set server = salt['grains.filter_by']({
     'BaseDefaults': default_params,
@@ -133,7 +135,7 @@
         'pkgs_l2gw': ['python-networking-l2gw'],
         'pkgs_bgpvpn': ['python-networking-bgpvpn'],
         'pkgs_bagpipe': ['python-networking-bagpipe'],
-        'services': ['neutron-server'],
+        'services': server_services_list,
         'services_ovn': ['openvswitch-switch', 'ovn-central'],
         'notification': {},
         'dpdk': false,
diff --git a/neutron/server.sls b/neutron/server.sls
index e13dc75..99bbdef 100644
--- a/neutron/server.sls
+++ b/neutron/server.sls
@@ -379,6 +379,10 @@
 
 {% endif %}
 
+{%- if server.wsgi is defined %}
+  {%- include "neutron/wsgi/uwsgi.sls" %}
+{%- endif %}
+
 neutron_server_services:
   service.running:
   - names: {{ server.services }}
diff --git a/neutron/wsgi/uwsgi.sls b/neutron/wsgi/uwsgi.sls
new file mode 100644
index 0000000..0fe68e7
--- /dev/null
+++ b/neutron/wsgi/uwsgi.sls
@@ -0,0 +1,19 @@
+{%- from "neutron/map.jinja" import server with context %}
+{%- if server.wsgi.enabled|default(False) %}
+
+{%- for _server in ['rpc-server', 'server'] %}
+/lib/systemd/system/neutron-{{ _server }}.service:
+  file.managed:
+  - source: salt://neutron/files/wsgi/{{ _server }}.systemd
+{%- endfor %}
+
+/etc/neutron/neutron-api-uwsgi.ini:
+  file.managed:
+  - source: salt://neutron/files/wsgi/uwsgi.ini
+  - mode: 0640
+  - group: neutron
+  - template: jinja
+  - require:
+    - pkg: neutron_server_packages
+
+{%- endif %}