diff --git a/roles/6-generic-apps/tasks/main.yml b/roles/6-generic-apps/tasks/main.yml index 01fcd7340..8712e315c 100644 --- a/roles/6-generic-apps/tasks/main.yml +++ b/roles/6-generic-apps/tasks/main.yml @@ -44,6 +44,12 @@ name: wordpress when: wordpress_install tags: wordpress + +- name: LOKOLE + include_role: + name: lokole + when: lokole_install + tags: lokole - name: Recording STAGE 6 HAS COMPLETED ==================== lineinfile: diff --git a/roles/lokole/README.rst b/roles/lokole/README.rst new file mode 100644 index 000000000..729323c89 --- /dev/null +++ b/roles/lokole/README.rst @@ -0,0 +1,17 @@ +============= +Lokole README +============= + +This Ansible role installs the `Lokole web app `_ within Internet-in-a-Box. Lokole is a project by the Canadian-Congolese non-profit `Ascoderu `_. + +The Lokole is a simple email client that offers functionality like: + +1. Self-service creation of user accounts +2. Read emails sent to the account +3. Write emails including rich formatting +4. Send attachments + +Using It +-------- + +Lokole should be accessible at http://box/lokole/. diff --git a/roles/lokole/defaults/main.yml b/roles/lokole/defaults/main.yml new file mode 100644 index 000000000..e5cfc77c1 --- /dev/null +++ b/roles/lokole/defaults/main.yml @@ -0,0 +1,22 @@ +--- +# Information needed to install Lokole +lokole_version: "0.1.24" +lokole_install_path: "{{ content_base }}/lokole" +lokole_venv: "{{ lokole_install_path }}/venv" + +# Information needed to run Lokole +lokole_user: lokole +lokole_run_directory: "/home/{{ lokole_user }}/state" + +lokole_install: True +lokole_enabled: True + +lokole_url: /lokole +lokole_full_url: "http://{{ iiab_hostname }}.{{ iiab_domain }}{{ lokole_url }}" + +lokole_domain_socket: "{{ lokole_run_directory }}/lokole_gunicorn.sock" + +# Global variables provided by setup-lokole.sh L157-166 +# https://github.com/ascoderu/opwen-webapp/blob/master/setup/setup-lokole.sh#L157 +opwen_server_locale: "{{ default_language }}" +opwen_server_timezone: "{{ local_tz }}" diff --git a/roles/lokole/tasks/install.yml b/roles/lokole/tasks/install.yml new file mode 100644 index 000000000..7accb17e7 --- /dev/null +++ b/roles/lokole/tasks/install.yml @@ -0,0 +1,119 @@ +- name: Install packages required by Lokole + apt: + name: + - python3 + - python3-pip + - python3-venv + - python3-dev + - libffi-dev + - libssl-dev + - bcrypt + state: present + tags: + - install + +- name: Install Lokole from PyPI + pip: + name: opwen_email_client + version: "{{ lokole_version }}" + virtualenv: "{{ lokole_venv }}" + virtualenv_command: python3 -m venv "{{ lokole_venv }}" + tags: + - install + when: internet_available + +- name: Compile translations + shell: | + python_version=$(python3 -c 'from sys import version_info; print("%s.%s" % (version_info.major, version_info.minor));';) + {{ lokole_venv }}/bin/pybabel compile -d {{ item }}/translations + with_items: + - "{{ lokole_venv }}/lib/python${python_version}/site-packages/opwen_email_client/webapp" + tags: + - install + +- name: Create run directory + file: + path: "{{ lokole_run_directory }}" + state: directory + tags: + - configure + +- name: Configure Lokole + template: + src: webapp_secrets.sh.j2 + dest: "{{ lokole_run_directory }}/webapp_secrets.sh" + tags: + - configure + +- name: Configure Gunicorn + template: + src: webapp.sh.j2 + dest: "{{ lokole_run_directory }}/webapp.sh" + mode: a+x + tags: + - configure + +- name: Create 'lokole' service + template: + src: lokole.service.j2 + dest: /etc/systemd/system/lokole.service + tags: + - systemd + +- name: Enable 'lokole' service + systemd: + daemon_reload: yes + name: lokole + enabled: yes + state: restarted + when: lokole_enabled + +- name: Disable 'lokole' service + systemd: + name: lokole + enabled: no + state: stopped + when: not lokole_enabled + +- name: Copy lokole httpd conf file + template: + src: lokole.conf.j2 + dest: "/etc/{{ apache_config_dir }}/lokole.conf" + +- name: Enable httpd conf file if lokole_enabled (debuntu) + file: + src: "/etc/{{ apache_config_dir }}/lokole.conf" + dest: /etc/apache2/sites-enabled/lokole.conf + state: link + when: lokole_enabled and is_debuntu + +- name: Remove httpd conf file if we are disabled (OS's other than debuntu) + file: + path: /etc/apache2/sites-enabled/lokole.conf + state: absent + when: not lokole_enabled and is_debuntu + +- name: Restart Apache, so it picks up the new aliases + service: + name: "{{ apache_service }}" + state: restarted + +- name: Add 'lokole' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: lokole + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: lokole + - option: description + value: '"lokole is an email service."' + - option: lokole_run_directory + value: "{{ lokole_run_directory }}" + - option: lokole_url + value: "{{ lokole_url }}" + - option: lokole_full_url + value: "{{ lokole_full_url }}" + - option: lokole_enabled + value: "{{ lokole_enabled }}" diff --git a/roles/lokole/tasks/main.yml b/roles/lokole/tasks/main.yml new file mode 100644 index 000000000..dee0435b3 --- /dev/null +++ b/roles/lokole/tasks/main.yml @@ -0,0 +1,3 @@ +- name: Include the install playbook + include_tasks: install.yml + when: lokole_install diff --git a/roles/lokole/templates/lokole.conf.j2 b/roles/lokole/templates/lokole.conf.j2 new file mode 100644 index 000000000..10f5ff65b --- /dev/null +++ b/roles/lokole/templates/lokole.conf.j2 @@ -0,0 +1,27 @@ +# Root directory goes to Lokole web server + +ProxyRequests off +ProxyPass {{ lokole_url }}/ unix:{{ lokole_domain_socket }}|http://{{ iiab_hostname }}.{{ iiab_domain }}/ + + + ProxyPassReverse / + ProxyHTMLEnable On + ProxyHTMLURLMap / {{ lokole_url }}/ + RequestHeader unset Accept-Encoding + + +# /static directory is stored on filesystem +Alias {{ lokole_url }}/static {{ lokole_install_path }} + + + Options Indexes FollowSymLinks + + # Don't allow modifications in static directory + Require all granted + + Require all denied + + + +# Disable TRACE to prevent cross-site tracing +TraceEnable off diff --git a/roles/lokole/templates/lokole.service.j2 b/roles/lokole/templates/lokole.service.j2 new file mode 100644 index 000000000..29643cabd --- /dev/null +++ b/roles/lokole/templates/lokole.service.j2 @@ -0,0 +1,16 @@ +[Unit] +Description=Provides the Lokole Server +#Requires=lokole.socket +After=network.target + +[Service] +Type=simple +ExecStart=/bin/bash {{ lokole_run_directory }}/webapp.sh +ExecReload=/bin/kill -s HUP $MAINPID +ExecStop=/bin/kill -s TERM $MAINPID +User=root +Group=root +PrivateTmp=true + +[Install] +WantedBy=multi-user.target diff --git a/roles/lokole/templates/webapp.sh.j2 b/roles/lokole/templates/webapp.sh.j2 new file mode 100644 index 000000000..87290925a --- /dev/null +++ b/roles/lokole/templates/webapp.sh.j2 @@ -0,0 +1,9 @@ +#!/usr/bin/env sh +. '{{lokole_run_directory}}/webapp_secrets.sh' + +'{{lokole_venv}}/bin/gunicorn' \ + --timeout='300' \ + --workers='{{ [4, ansible_memtotal_mb / 200] | min | int }}' \ + --bind='unix:{{ lokole_domain_socket }}' \ + --log-level='error' \ + 'opwen_email_client.webapp:app' diff --git a/roles/lokole/templates/webapp_secrets.sh.j2 b/roles/lokole/templates/webapp_secrets.sh.j2 new file mode 100644 index 000000000..44dcfbae6 --- /dev/null +++ b/roles/lokole/templates/webapp_secrets.sh.j2 @@ -0,0 +1,4 @@ +export OPWEN_STATE_DIRECTORY='{{lokole_run_directory}}' +export OPWEN_SESSION_KEY='{{ lookup('password', '/dev/null chars=ascii_letters,digits,_ length=32') }}' +export OPWEN_PASSWORD_SALT='{{ lookup('password', '/dev/null chars=ascii_letters,digits,_ length=16') }}' +export OPWEN_CLIENT_NAME='iiab-{{ iiab_hostname }}'