From 934cfff69dff3ea569cb547a017ac8b40dfdcc89 Mon Sep 17 00:00:00 2001
From: Emmanuel Cazenave <ecazenave@entrouvert.com>
Date: Wed, 31 Mar 2021 16:22:35 +0200
Subject: [PATCH] add uwsgi as available application server (#50525)

---
 roles/app-setup/tasks/main.yml                | 48 +++++++++++++++++++
 .../templates/server-uwsgi-supervisor.j2      | 27 +++++++++++
 roles/app-setup/vars/main.yml                 |  3 ++
 roles/authentic/vars/main.yml                 |  1 +
 roles/base/tasks/main.yml                     | 15 ++++++
 roles/base/templates/get-uwsgidecorators.j2   | 15 ++++++
 roles/bijoe/vars/main.yml                     |  1 +
 roles/chrono/vars/main.yml                    |  1 +
 roles/combo/vars/main.yml                     |  1 +
 roles/fargo/vars/main.yml                     |  1 +
 roles/hobo/vars/main.yml                      |  1 +
 roles/passerelle/vars/main.yml                |  1 +
 roles/wcs/vars/main.yml                       |  1 +
 roles/welco/vars/main.yml                     |  1 +
 14 files changed, 117 insertions(+)
 create mode 100644 roles/app-setup/templates/server-uwsgi-supervisor.j2
 create mode 100644 roles/base/templates/get-uwsgidecorators.j2

diff --git a/roles/app-setup/tasks/main.yml b/roles/app-setup/tasks/main.yml
index c56ce8d..3158f37 100644
--- a/roles/app-setup/tasks/main.yml
+++ b/roles/app-setup/tasks/main.yml
@@ -107,3 +107,51 @@
     src: server-supervisor.j2
     dest: "/etc/supervisor/conf.d/{{server_app_name}}.conf"
   become: yes
+
+- name: "{{app_name}} - copy uwsgi configuration file"
+  copy:
+    src: "{{uwsgi_settings_orig}}"
+    dest: "{{uwsgi_settings}}"
+
+- name: "{{app_name}} - comment cron options in uwsgi configuration file"
+  replace:
+    path: "{{uwsgi_settings}}"
+    regexp: '^(cron.*)'
+    replace: '# \1'
+
+- name: "{{app_name}} - change http-to option in uwsgi configuration file"
+  ini_file:
+    path: "{{uwsgi_settings}}"
+    section: uwsgi
+    option: http-socket
+    value: ":{{server_port}}"
+
+- name: "{{app_name}} - set py-auto-reload in uwsgi configuration file"
+  ini_file:
+    path: "{{uwsgi_settings}}"
+    section: uwsgi
+    option: py-auto-reload
+    value: 1
+
+- name: '{{app_name}} - change local configuration path in uwsgi configuration file'
+  replace:
+    path: '{{uwsgi_settings}}'
+    regexp: '/etc/{{project_name}}/'
+    replace: '{{app_settings_dir}}/settings.d/'
+
+- name: "{{app_name}} - uwsgi server supervisor configuration"
+  template:
+    src: server-uwsgi-supervisor.j2
+    dest: "/etc/supervisor/conf.d/{{server_app_name}}-uwsgi.conf"
+  become: yes
+
+- name: "{{app_name}} - create some directories"
+  file:
+    path: "{{item}}"
+    state: directory
+    owner: "{{user}}"
+    group: "{{user}}"
+  become: yes
+  loop:
+     - "{{run_dir}}"
+     - "{{spooler_dir}}"
diff --git a/roles/app-setup/templates/server-uwsgi-supervisor.j2 b/roles/app-setup/templates/server-uwsgi-supervisor.j2
new file mode 100644
index 0000000..3167b78
--- /dev/null
+++ b/roles/app-setup/templates/server-uwsgi-supervisor.j2
@@ -0,0 +1,27 @@
+[program:{{server_app_name}}-uwsgi]
+command=/usr/bin/uwsgi --ini {{uwsgi_settings}} -H {{venv_py3}} --spooler {{state_dir}}/spooler/
+environment={{settings_env_var}}="{{app_settings}}"
+process_name={{server_app_name}}-uwsgi
+user={{user}}
+numprocs=1
+stdout_logfile={{log_dir}}/stdout.log
+stderr_logfile={{log_dir}}/stderr.log
+
+autostart=false
+autorestart=true
+startsecs=10
+; Need to wait for currently executing tasks to finish at shutdown.
+; Increase this if you have very long running tasks.
+stopwaitsecs = 600
+
+stopsignal=KILL
+; When resorting to send SIGKILL to the program to terminate it
+; send SIGKILL to its whole process group instead,
+; taking care of its children as well.
+killasgroup=true
+stopasgroup=true
+
+; if rabbitmq is supervised, set its priority higher
+; so it starts first
+priority=998
+
diff --git a/roles/app-setup/vars/main.yml b/roles/app-setup/vars/main.yml
index e897c27..316a8ee 100644
--- a/roles/app-setup/vars/main.yml
+++ b/roles/app-setup/vars/main.yml
@@ -1,3 +1,6 @@
 log_dir: "/var/log/{{server_app_name}}"
+run_dir: "/run/{{project_name}}"
 state_dir: "/var/lib/{{project_name}}"
+spooler_dir: "{{state_dir}}/spooler"
 tenants_dir: "/var/lib/{{project_name}}/tenants"
+uwsgi_settings: "{{publik_settings}}/{{project_name}}/uwsgi.ini"
diff --git a/roles/authentic/vars/main.yml b/roles/authentic/vars/main.yml
index 97550b5..1a985b0 100644
--- a/roles/authentic/vars/main.yml
+++ b/roles/authentic/vars/main.yml
@@ -8,4 +8,5 @@ nginx_template_name: "std-nginx-server.j2"
 project_name: "{{apps['authentic']['project_name']}}"
 server_port: "{{apps['authentic']['server_port']}}"
 settings_env_var: AUTHENTIC2_SETTINGS_FILE
+uwsgi_settings_orig: "{{src_dir}}/{{app_name}}/debian/authentic2-multitenant-uwsgi.ini"
 virtualenv: "{{venv_py3}}"
diff --git a/roles/base/tasks/main.yml b/roles/base/tasks/main.yml
index 55bc262..38f8167 100644
--- a/roles/base/tasks/main.yml
+++ b/roles/base/tasks/main.yml
@@ -29,6 +29,9 @@
        - virtualenv
        - pkg-config
        - libsystemd-dev
+       - uwsgi
+       - uwsgi-plugin-python3
+       - python3-uwsgidecorators
     state: present
   become: yes
 
@@ -107,6 +110,18 @@
 - name: execute getlasso
   command: "{{venv_py3_bin}}/getlasso.sh"
 
+- name: create get-uwsgidecorators scripts
+  template:
+    src: get-uwsgidecorators.j2
+    dest: "{{venv_py3_bin}}/get-uwsgidecorators.sh"
+    mode: "u=rwx,g=rx,o=rx"
+  vars:
+    virtualenv_python: "{{venv_py3_python}}"
+    system_python: "/usr/bin/python3"
+
+- name: execute get-uwsgidecorators
+  command: "{{venv_py3_bin}}/get-uwsgidecorators.sh"
+
 - name: source install eopayment
   include_tasks: install_source.yml
   vars:
diff --git a/roles/base/templates/get-uwsgidecorators.j2 b/roles/base/templates/get-uwsgidecorators.j2
new file mode 100644
index 0000000..e7c3b99
--- /dev/null
+++ b/roles/base/templates/get-uwsgidecorators.j2
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Get venv site-packages path
+DSTDIR=`{{virtualenv_python}} -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib())'`
+
+SRCDIR=`{{system_python}} -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib())'`
+
+# Clean up
+rm -f $DSTDIR/uwsgidecorators.py*
+
+# Link
+ln -sv $SRCDIR/uwsgidecorators.py $DSTDIR
+
+exit 0
+
diff --git a/roles/bijoe/vars/main.yml b/roles/bijoe/vars/main.yml
index fa51c9b..2776b27 100644
--- a/roles/bijoe/vars/main.yml
+++ b/roles/bijoe/vars/main.yml
@@ -8,4 +8,5 @@ nginx_template_name: "std-nginx-server.j2"
 project_name: "{{apps['bijoe']['project_name']}}"
 server_port: "{{apps['bijoe']['server_port']}}"
 settings_env_var: BIJOE_SETTINGS_FILE
+uwsgi_settings_orig: "{{src_dir}}/{{app_name}}/debian/uwsgi.ini"
 virtualenv: "{{venv_py3}}"
diff --git a/roles/chrono/vars/main.yml b/roles/chrono/vars/main.yml
index cb2eba1..f28a9d0 100644
--- a/roles/chrono/vars/main.yml
+++ b/roles/chrono/vars/main.yml
@@ -8,4 +8,5 @@ nginx_template_name: "chrono-nginx-server.j2"
 project_name: "{{apps['chrono']['project_name']}}"
 server_port: "{{apps['chrono']['server_port']}}"
 settings_env_var: CHRONO_SETTINGS_FILE
+uwsgi_settings_orig: "{{src_dir}}/{{app_name}}/debian/uwsgi.ini"
 virtualenv: "{{venv_py3}}"
diff --git a/roles/combo/vars/main.yml b/roles/combo/vars/main.yml
index 3a3636c..b4804e6 100644
--- a/roles/combo/vars/main.yml
+++ b/roles/combo/vars/main.yml
@@ -8,4 +8,5 @@ nginx_template_name: "std-nginx-server.j2"
 project_name: "{{apps['combo']['project_name']}}"
 server_port: "{{apps['combo']['server_port']}}"
 settings_env_var: COMBO_SETTINGS_FILE
+uwsgi_settings_orig: "{{src_dir}}/{{app_name}}/debian/uwsgi.ini"
 virtualenv: "{{venv_py3}}"
diff --git a/roles/fargo/vars/main.yml b/roles/fargo/vars/main.yml
index 79fc75c..26b5edd 100644
--- a/roles/fargo/vars/main.yml
+++ b/roles/fargo/vars/main.yml
@@ -8,4 +8,5 @@ nginx_template_name: "fargo-nginx-server.j2"
 project_name: "{{apps['fargo']['project_name']}}"
 server_port: "{{apps['fargo']['server_port']}}"
 settings_env_var: FARGO_SETTINGS_FILE
+uwsgi_settings_orig: "{{src_dir}}/{{app_name}}/debian/uwsgi.ini"
 virtualenv: "{{venv_py3}}"
diff --git a/roles/hobo/vars/main.yml b/roles/hobo/vars/main.yml
index 2f36105..99a9aa4 100644
--- a/roles/hobo/vars/main.yml
+++ b/roles/hobo/vars/main.yml
@@ -8,4 +8,5 @@ nginx_template_name: "std-nginx-server.j2"
 project_name: "{{apps['hobo']['project_name']}}"
 server_port: "{{apps['hobo']['server_port']}}"
 settings_env_var: HOBO_SETTINGS_FILE
+uwsgi_settings_orig: "{{src_dir}}/{{app_name}}/debian/server/uwsgi.ini"
 virtualenv: "{{venv_py3}}"
diff --git a/roles/passerelle/vars/main.yml b/roles/passerelle/vars/main.yml
index 0c7bf52..3a42de3 100644
--- a/roles/passerelle/vars/main.yml
+++ b/roles/passerelle/vars/main.yml
@@ -8,4 +8,5 @@ nginx_template_name: "std-nginx-server.j2"
 project_name: "{{apps['passerelle']['project_name']}}"
 server_port: "{{apps['passerelle']['server_port']}}"
 settings_env_var: PASSERELLE_SETTINGS_FILE
+uwsgi_settings_orig: "{{src_dir}}/{{app_name}}/debian/uwsgi.ini"
 virtualenv: "{{venv_py3}}"
diff --git a/roles/wcs/vars/main.yml b/roles/wcs/vars/main.yml
index 143cd36..fa2019a 100644
--- a/roles/wcs/vars/main.yml
+++ b/roles/wcs/vars/main.yml
@@ -9,4 +9,5 @@ nginx_template_name: "wcs-nginx-server.j2"
 project_name: "{{apps['wcs']['project_name']}}"
 server_port: "{{apps['wcs']['server_port']}}"
 settings_env_var: WCS_SETTINGS_FILE
+uwsgi_settings_orig: "{{src_dir}}/{{app_name}}/debian/uwsgi.ini"
 virtualenv: "{{venv_py3}}"
diff --git a/roles/welco/vars/main.yml b/roles/welco/vars/main.yml
index 13a3d98..512c21e 100644
--- a/roles/welco/vars/main.yml
+++ b/roles/welco/vars/main.yml
@@ -8,4 +8,5 @@ nginx_template_name: "welco-nginx-server.j2"
 project_name: "{{apps['welco']['project_name']}}"
 server_port: "{{apps['welco']['server_port']}}"
 settings_env_var: WELCO_SETTINGS_FILE
+uwsgi_settings_orig: "{{src_dir}}/{{app_name}}/debian/uwsgi.ini"
 virtualenv: "{{venv_py3}}"
-- 
2.20.1

