From f867c471fbfbcca02144cc619b6edb4d9144e73a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABtan=20Trellu?= <gaetan.trellu@incloudus.com>
Date: Thu, 20 Jun 2019 13:08:53 -0400
Subject: [PATCH] Implement Apache WSGI for Qinling

Since this review[1], Qinling supports WSGI execution.

From a production perspective, Qinling should be deployed
using Apache and mod_wsgi.

"api_worker" option is not needed anymore because processes will
be handle by Apache mod_wsgi.

Qinling Docker image review[2] has ben created.

[1] https://review.opendev.org/661851
[2] https://review.opendev.org/666647

Change-Id: I9aaee4c2932f1e4ea9fe780a64e96a28fa6bccfb
Story: 2005920
Task: 34181
---
 ansible/roles/qinling/handlers/main.yml       |  1 +
 ansible/roles/qinling/tasks/config.yml        | 15 +++++++++
 .../qinling/templates/qinling-api.json.j2     | 10 +++++-
 .../roles/qinling/templates/qinling.conf.j2   |  1 -
 .../qinling/templates/wsgi-qinling.conf.j2    | 33 +++++++++++++++++++
 5 files changed, 58 insertions(+), 2 deletions(-)
 create mode 100644 ansible/roles/qinling/templates/wsgi-qinling.conf.j2

diff --git a/ansible/roles/qinling/handlers/main.yml b/ansible/roles/qinling/handlers/main.yml
index cf29b6ae0..01620ead6 100644
--- a/ansible/roles/qinling/handlers/main.yml
+++ b/ansible/roles/qinling/handlers/main.yml
@@ -21,6 +21,7 @@
     - service.enabled | bool
     - config_json.changed | bool
       or qinling_conf.changed | bool
+      or qinling_conf_wsgi.changed | bool
       or policy_overwriting.changed | bool
       or qinling_api_container.changed | bool
 
diff --git a/ansible/roles/qinling/tasks/config.yml b/ansible/roles/qinling/tasks/config.yml
index 207434c66..0207ad036 100644
--- a/ansible/roles/qinling/tasks/config.yml
+++ b/ansible/roles/qinling/tasks/config.yml
@@ -69,6 +69,21 @@
   notify:
     - Restart {{ item.key }} container
 
+- name: Copying over wsgi-qinling files for services
+  vars:
+    service: "{{ qinling_services['qinling-api'] }}"
+  template:
+    src: "wsgi-qinling.conf.j2"
+    dest: "{{ node_config_directory }}/qinling-api/wsgi-qinling.conf"
+    mode: "0660"
+  become: true
+  register: qinling_conf_wsgi
+  when:
+    - inventory_hostname in groups[service.group]
+    - service.enabled | bool
+  notify:
+    - Restart qinling-api container
+
 - name: Copying over existing policy file
   template:
     src: "{{ qinling_policy_file_path }}"
diff --git a/ansible/roles/qinling/templates/qinling-api.json.j2 b/ansible/roles/qinling/templates/qinling-api.json.j2
index 230219f05..ad9b4f39c 100644
--- a/ansible/roles/qinling/templates/qinling-api.json.j2
+++ b/ansible/roles/qinling/templates/qinling-api.json.j2
@@ -1,11 +1,19 @@
+{% set qinling_cmd = 'apache2' if kolla_base_distro in ['ubuntu', 'debian'] else 'httpd' %}
+{% set qinling_dir = 'apache2/conf-enabled' if kolla_base_distro in ['ubuntu', 'debian'] else 'httpd/conf.d' %}
 {
-    "command": "qinling-api --config-file /etc/qinling/qinling.conf",
+    "command": "{{ qinling_cmd }} -DFOREGROUND",
     "config_files": [
         {
             "source": "{{ container_config_directory }}/qinling.conf",
             "dest": "/etc/qinling/qinling.conf",
             "owner": "qinling",
             "perm": "0600"
+        },
+        {
+            "source": "{{ container_config_directory }}/wsgi-qinling.conf",
+            "dest": "/etc/{{ qinling_dir }}/wsgi-qinling.conf",
+            "owner": "qinling",
+            "perm": "0600"
         }{% if qinling_policy_file is defined %},
         {
             "source": "{{ container_config_directory }}/{{ qinling_policy_file }}",
diff --git a/ansible/roles/qinling/templates/qinling.conf.j2 b/ansible/roles/qinling/templates/qinling.conf.j2
index b7b20c825..230030812 100644
--- a/ansible/roles/qinling/templates/qinling.conf.j2
+++ b/ansible/roles/qinling/templates/qinling.conf.j2
@@ -7,7 +7,6 @@ transport_url = {{ rpc_transport_url }}
 [api]
 port = {{ qinling_api_port }}
 host = {{ api_interface_address }}
-api_workers = {{ openstack_service_workers }}
 {% endif %}
 
 {% if service_name == 'qinling-engine' %}
diff --git a/ansible/roles/qinling/templates/wsgi-qinling.conf.j2 b/ansible/roles/qinling/templates/wsgi-qinling.conf.j2
new file mode 100644
index 000000000..b642d0e03
--- /dev/null
+++ b/ansible/roles/qinling/templates/wsgi-qinling.conf.j2
@@ -0,0 +1,33 @@
+{% if kolla_base_distro == 'ubuntu' %}
+    {% set python_path = '/usr/lib/python3/dist-packages' if qinling_install_type == 'binary' else '/var/lib/kolla/venv/lib/python3.6/site-packages' %}
+{% else %}
+    {% set python_path = '/usr/lib/python2.7/site-packages' if qinling_install_type == 'binary' else '/var/lib/kolla/venv/lib/python2.7/site-packages' %}
+{% endif %}
+
+Listen {{ api_interface_address }}:{{ qinling_api_port }}
+
+ServerSignature Off
+ServerTokens Prod
+TraceEnable off
+
+<VirtualHost *:{{ qinling_api_port }}>
+
+  ## Vhost docroot
+  DocumentRoot "/var/www/cgi-bin/qinling"
+
+  ## Directories, there should at least be a declaration for /var/www/cgi-bin/qinling
+
+  <Directory "/var/www/cgi-bin/qinling">
+    Options Indexes FollowSymLinks MultiViews
+    Require all granted
+  </Directory>
+
+  ## Logging
+  ErrorLog "/var/log/kolla/qinling/qinling_api_wsgi_error.log"
+  LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" logformat
+  CustomLog "/var/log/kolla/qinling/qinling_api_wsgi_access.log" logformat
+  WSGIApplicationGroup %{GLOBAL}
+  WSGIDaemonProcess qinling group=qinling processes={{ openstack_service_workers }} threads=1 user=qinling python-path={{ python_path }}
+  WSGIProcessGroup qinling
+  WSGIScriptAlias / "/var/www/cgi-bin/qinling/wsgi.py"
+</VirtualHost>
-- 
GitLab