Pretalx role files

This commit is contained in:
Marc Debureaux 2024-04-03 21:26:47 +02:00
parent 08db1c1366
commit db38131076
Signed by: debnet
GPG Key ID: 14778F7F564782B9
16 changed files with 749 additions and 1 deletions

@ -1 +0,0 @@
Subproject commit f8e87d121b30ab92896c7cad30bd7093a28414ee

View File

@ -0,0 +1,7 @@
skip_list:
- fqcn[action]
- fqcn[action-core]
- yaml[line-length]
exclude_paths:
- .github

23
roles/pretalx/Vagrantfile vendored Normal file
View File

@ -0,0 +1,23 @@
Vagrant.configure("2") do |config|
config.vm.provider :virtualbox do |v|
v.name = "pretalx"
v.memory = 2048
v.cpus = 2
v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
v.customize ["modifyvm", :id, "--ioapic", "on"]
end
config.vm.define :pretalx do |pretalx|
pretalx.vm.hostname = "pretalx.local"
pretalx.vm.box = "debian/bookworm64"
pretalx.vm.network :private_network, ip: "192.168.56.10"
pretalx.vm.network :forwarded_port, guest: "80", host: "8000"
pretalx.vm.network :forwarded_port, guest: "443", host: "8443"
pretalx.vm.provision "ansible" do |ansible|
ansible.compatibility_mode = "2.0"
ansible.playbook = "pretalx.yml"
ansible.become = true
end
end
end

View File

@ -0,0 +1,66 @@
---
# Use if you have more than one instance on your server, for example for
# seamless updates (sharing a database) or separate instances.
pretalx_instance_identifier: "main"
pretalx_system_user: "pretalx"
pretalx_system_home: "/home/{{ pretalx_system_user }}"
pretalx_database_backend: postgresql
pretalx_database_name: pretalx_{{ pretalx_instance_identifier }}
pretalx_database_user: pretalx_{{ pretalx_instance_identifier }}
pretalx_database_password: false
pretalx_database_host: localhost
pretalx_database_port: 5432
pretalx_staticfiles_directory: "{{ pretalx_system_home }}/pretalx_{{ pretalx_instance_identifier }}/static"
pretalx_data_dir: "{{ pretalx_system_home }}/pretalx_{{ pretalx_instance_identifier }}/data"
pretalx_media_dir: "{{ pretalx_system_home }}/pretalx_{{ pretalx_instance_identifier }}/media"
pretalx_virtualenv: "{{ pretalx_system_home }}/pretalx_{{ pretalx_instance_identifier }}/venv"
pretalx_python: "{{ pretalx_virtualenv }}/bin/python"
pretalx_webserver_group: www-data
pretalx_domain: localhost
pretalx_url: https://{{ pretalx_domain }}
pretalx_core_modules: ""
pretalx_admin_mail: ""
pretalx_mail_from: admin@localhost
pretalx_mail_host: localhost
pretalx_mail_port: 25
pretalx_mail_tls: "False"
pretalx_mail_ssl: "True"
pretalx_mail_user: None # if set to None do not use authentication
pretalx_mail_password: None
pretalx_service_workers: 4 # https://docs.gunicorn.org/en/stable/settings.html?highlight=max-requests#workers
pretalx_service_workers_max_requests: 1200 # https://docs.gunicorn.org/en/stable/settings.html?highlight=max-requests#max-requests
pretalx_service_workers_max_requests_jitter: 50 # https://docs.gunicorn.org/en/stable/settings.html?highlight=max-requests#max-requests-jitter
pretalx_nginx: false
pretalx_nginx_path: false
pretalx_nginx_force_https: false # Set to true if you want this role to take care of HTTPS upgrades, leave false if your nginx configuration handles this already
pretalx_cert_root: /etc/ssl/letsencrypt/certs # for Nginx configuration
pretalx_nginx_http_only: false
pretalx_redis: false
pretalx_celery: true
pretalx_celery_backend: "redis://127.0.0.1:6379/1"
pretalx_celery_broker: "redis://127.0.0.1:6379/2"
pretalx_version: latest
pretalx_git_version: ""
pretalx_git_url: "https://github.com/pretalx/pretalx.git"
pretalx_plugins: null
pretalx_cron: true
pretalx_alternate_domains: null # can be a string like "location1 location2"
pretalx_additional_config: null # string that will be appended to the cfg file without further modifications
pretalx_admin_email: ""
pretalx_admin_password: ""
pretalx_orga_name: ""
pretalx_orga_slug: ""

View File

@ -0,0 +1,86 @@
---
- name: Reload systemd services
systemd:
daemon_reload: true
- name: Install pretalx plugins
shell: cd {{ pretalx_system_home }}/plugins/{{ item.name }} && {{ pretalx_python }} setup.py develop --user
with_items: "{{ pretalx_plugins }}"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Run pretalx migrations
command: "{{ pretalx_python }} -m pretalx migrate"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Run pretalx static collection
command: "{{ pretalx_python }} -m pretalx collectstatic --noinput"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Compile pretalx styles
command: "{{ pretalx_python }} -m pretalx regenerate_css"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Copy static manifest
shell: "cp -f {{ pretalx_staticfiles_directory }}/staticfiles.json {{ pretalx_staticfiles_directory }}/pretalx-manifest.json"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Compile messages for plugins
shell: cd {{ pretalx_system_home }}/plugins/{{ item.name }} && make
with_items: "{{ pretalx_plugins }}"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Rebuild pretalx files
command: "{{ pretalx_python }} -m pretalx rebuild --npm-install"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
- name: Initialize pretalx
command: "{{ pretalx_python }} -m pretalx init --noinput"
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
environment:
- DJANGO_SUPERUSER_EMAIL: "{{ pretalx_admin_email }}"
- DJANGO_SUPERUSER_PASSWORD: "{{ pretalx_admin_password }}"
- PRETALX_INIT_ORGANISER_NAME: "{{ pretalx_orga_name }}"
- PRETALX_INIT_ORGANISER_SLUG: "{{ pretalx_orga_slug }}"
- name: Restart pretalx service
service:
name: pretalx@{{ pretalx_instance_identifier }}
state: restarted
- name: Restart worker service
service:
name: pretalx-worker@{{ pretalx_instance_identifier }}
state: restarted
when: pretalx_celery
- name: Restart redis
service:
name: redis
state: restarted
when: pretalx_redis
- name: Reload nginx
service:
name: nginx
state: reloaded
- name: Restart pretalx socket
service:
name: pretalx@{{ pretalx_instance_identifier }}.socket
state: restarted

View File

@ -0,0 +1,23 @@
---
galaxy_info:
namespace: pretalx
role_name: pretalx
author: Tobias Kunze
description: Ansible role to install pretalx in a production environment
company: pretalx
issue_tracker_url: https://github.com/pretalx/ansible-pretalx
license: Apache
min_ansible_version: "2.4"
galaxy_tags:
- pretalx
- conference
- schedule
- program
- cfp
platforms:
- name: ArchLinux
versions:
- all
- name: Debian
versions:
- bullseye

View File

@ -0,0 +1,22 @@
---
- name: Install system requirements
import_tasks: requirements.yml
- name: Detect installed system Python version
command: |
python3 -c "import sys; (major, minor) = sys.version_info[0:2]; print(f'{major}.{minor}')"
args:
creates: nothing
changed_when: false
# become: true
# become_user: "{{ pretalx_system_user }}"
when: pretalx_system_python_version is not defined
register: pretalx_python_version_info_major_minor
- name: Define installed system Python version variable
set_fact:
pretalx_system_python_version: "{{ pretalx_python_version_info_major_minor.stdout }}"
when: pretalx_system_python_version is not defined
- name: Install pretalx itself
import_tasks: package.yml

View File

@ -0,0 +1,269 @@
---
- name: Create a pretalx user
user:
name: "{{ pretalx_system_user }}"
state: present
system: true
tags:
- pretalx
- name: Create required directories
file:
path: "{{ item }}"
state: directory
owner: "{{ pretalx_system_user }}"
group: "{{ pretalx_webserver_group }}"
mode: "0750"
recurse: true
with_items:
- "{{ pretalx_staticfiles_directory }}"
- "{{ pretalx_data_dir }}"
- "{{ pretalx_media_dir }}"
- "{{ pretalx_virtualenv }}"
tags:
- pretalx
- name: Install redis client
pip:
name: django_redis
state: latest # noqa package-latest
virtualenv: "{{ pretalx_virtualenv }}"
become: true
become_user: "{{ pretalx_system_user }}"
when: pretalx_redis or pretalx_celery
tags:
- pretalx
- pretalx-install
- name: Install gunicorn
pip:
name: gunicorn
state: latest # noqa package-latest
virtualenv: "{{ pretalx_virtualenv }}"
become: true
become_user: "{{ pretalx_system_user }}"
tags:
- pretalx
- pretalx-install
- name: Configure pretalx
template:
src: pretalx.cfg.j2
dest: "{{ pretalx_system_home }}/.pretalx.cfg"
mode: "0600"
notify:
- Restart pretalx service
- Restart worker service
- Run pretalx migrations
- Rebuild pretalx files
- Compile pretalx styles
become: true
become_user: "{{ pretalx_system_user }}"
tags:
- pretalx
- pretalxupdate
- name: Set pretalx_extra to "[postgres]" if using postgresql database
set_fact:
pretalx_extra: "[postgres]"
when: pretalx_database_backend == 'postgresql'
tags:
- pretalx
- pretalxupdate
- name: Set pretalx_extra to "[mysql]" if using mysql database
set_fact:
pretalx_extra: "[mysql]"
when: pretalx_database_backend == 'mysql'
tags:
- pretalx
- pretalxupdate
- name: Set pretalx_extra to "" if using other database
set_fact:
pretalx_extra: ""
when: pretalx_extra is not defined
tags:
- pretalx
- pretalxupdate
- name: Install pretalx (latest)
pip:
name: "pretalx{{ pretalx_extra }}"
state: latest # noqa package-latest
virtualenv: "{{ pretalx_virtualenv }}"
notify:
- Restart pretalx service
- Restart worker service
- Run pretalx migrations
- Run pretalx static collection
- Copy static manifest
- Rebuild pretalx files
- Compile pretalx styles
- Initialize pretalx
when: (pretalx_version == 'latest') and not (pretalx_git_version)
become: true
become_user: "{{ pretalx_system_user }}"
tags:
- pretalx
- pretalxupdate
- name: Install pretalx (versioned)
pip:
name: "pretalx{{ pretalx_extra }}"
version: "{{ pretalx_version }}" # noqa package-lastest
virtualenv: "{{ pretalx_virtualenv }}"
notify:
- Restart pretalx service
- Restart worker service
- Run pretalx migrations
- Run pretalx static collection
- Copy static manifest
- Rebuild pretalx files
- Compile pretalx styles
- Initialize pretalx
when: (pretalx_version != 'latest') and not pretalx_git_version
become: true
become_user: "{{ pretalx_system_user }}"
tags:
- pretalx
- pretalxupdate
- name: Install pretalx (git)
pip:
name: "git+{{ pretalx_git_url }}@{{ pretalx_git_version }}#egg=pretalx{{ pretalx_extra }}"
state: forcereinstall
virtualenv: "{{ pretalx_virtualenv }}"
notify:
- Restart pretalx service
- Restart worker service
- Run pretalx migrations
- Run pretalx static collection
- Copy static manifest
- Rebuild pretalx files
- Compile pretalx styles
- Initialize pretalx
when: pretalx_git_version | length > 0
become: true
become_user: "{{ pretalx_system_user }}"
changed_when: true
tags:
- pretalx
- pretalxupdate
- name: Make sure plugin directory exists
file:
path: "{{ pretalx_system_home }}/plugins"
state: directory
owner: "{{ pretalx_system_user }}"
recurse: true
when: pretalx_plugins
tags:
- pretalx
- name: Install pretalx plugins
git:
repo: "{{ item.repository }}"
dest: "{{ pretalx_system_home }}/plugins/{{ item.name }}"
version: "{{ item.version if item.version is defined else 'main' }}"
key_file: "{{ pretalx_system_home }}/.ssh/id_rsa"
accept_hostkey: true
become: true
become_user: "{{ pretalx_system_user }}"
with_items: "{{ pretalx_plugins }}"
when: pretalx_plugins
notify:
- Restart pretalx service
- Restart worker service
- Run pretalx migrations
- Run pretalx static collection
- Copy static manifest
- Rebuild pretalx files
- Compile pretalx styles
- Install pretalx plugins
tags:
- pretalx
- pretalxupdate
- name: Install systemd socket
template:
src: pretalx.socket.j2
dest: /etc/systemd/system/pretalx@{{ pretalx_instance_identifier }}.socket
mode: "0644"
notify:
- Reload systemd services
- Restart pretalx socket
tags:
- pretalx
- name: Install systemd service
template:
src: pretalx.service.j2
dest: /etc/systemd/system/pretalx@{{ pretalx_instance_identifier }}.service
mode: "0644"
notify:
- Reload systemd services
- Restart pretalx service
- Restart worker service
tags:
- pretalx
- name: Install worker service
template:
src: pretalx-worker.service.j2
dest: /etc/systemd/system/pretalx-worker@{{ pretalx_instance_identifier }}.service
mode: "0644"
notify:
- Reload systemd services
- Restart worker service
when: pretalx_celery
tags:
- pretalx
- name: Start pretalx socket
service:
name: pretalx@{{ pretalx_instance_identifier }}.socket
state: started
enabled: true
tags:
- pretalx
- name: Start systemd service
service:
name: pretalx@{{ pretalx_instance_identifier }}
state: started
enabled: true
tags:
- pretalx
- name: Start worker service
service:
name: pretalx-worker@{{ pretalx_instance_identifier }}
state: started
enabled: true
when: pretalx_celery
tags:
- pretalx
- name: Install nginx config
template:
src: nginx.conf
dest: "{{ pretalx_nginx_path }}/pretalx_{{ pretalx_instance_identifier }}.conf"
mode: "0644"
when: pretalx_nginx
notify:
- Reload nginx
tags:
- nginx
- pretalx
- pretalxnginx
- name: Install runperiodic cronjob
cron:
minute: "40"
name: Run pretalx{{ pretalx_instance_identifier }} periodic task
user: "{{ pretalx_system_user }}"
job: "{{ pretalx_python }} -m pretalx runperiodic"
when: pretalx_cron
tags:
- pretalx

View File

@ -0,0 +1,3 @@
---
- name: Install system requirements
include_tasks: requirements_{{ ansible_os_family | lower }}.yml

View File

@ -0,0 +1,43 @@
---
- name: Install dependencies
pacman:
name:
- python
- git
- npm
state: present
notify:
- Reload systemd services
tags:
- pretalx
- name: Install sqlite
pacman:
name:
- sqlite
state: present
notify:
- Reload systemd services
when: pretalx_database_backend != 'postgresql' and pretalx_database_backend != 'mysql'
tags:
- pretalx
- name: Install redis
pacman:
name:
- redis
state: present
notify:
- Restart redis
when: pretalx_redis
tags:
- pretalx
- name: Start and enable redis
service:
name: redis
state: started
enabled: true
when: pretalx_redis
tags:
- pretalx

View File

@ -0,0 +1,40 @@
---
- name: Install Python 3
apt:
name:
- python3
- python3-dev
- python3-wheel
- virtualenv
state: present
tags:
- pretalx
- name: Install other dependencies
apt:
name:
- gcc
- gettext
- git
- npm
state: present
tags:
- pretalx
- name: Install sqlite
apt:
name:
- sqlite3
state: present
when: pretalx_database_backend != 'postgresql' and pretalx_database_backend != 'mysql'
tags:
- pretalx
- name: Install redis
apt:
name:
- redis-server
state: present
when: pretalx_redis
tags:
- pretalx

View File

@ -0,0 +1,81 @@
upstream pretalx_{{ pretalx_instance_identifier }}_server {
server unix:/run/gunicorn/pretalx_{{ pretalx_instance_identifier }} fail_timeout=0;
}
proxy_cache_path /tmp/nginx-pretalx-{{ pretalx_instance_identifier }} levels=1:2 keys_zone=pretalx_static_{{ pretalx_instance_identifier }}:10m inactive=60m max_size=250m;
{% if pretalx_nginx_force_https and not pretalx_nginx_http_only %}
server {
listen 80;
listen [::]:80;
server_name {{ pretalx_domain }}{% if pretalx_alternate_domains %} {{ pretalx_alternate_domains }}{% endif %};
return 301 https://$host$request_uri;
}
{% endif %}
{% if pretalx_nginx_http_only %}
server {
listen 80;
listen [::]:80;
server_name {{ pretalx_domain }}{% if pretalx_alternate_domains %} {{ pretalx_alternate_domains }}{% endif %};
{% else %}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{ pretalx_domain }}{% if pretalx_alternate_domains %} {{ pretalx_alternate_domains }}{% endif %};
# ssl on;
# ssl_certificate {{ pretalx_cert_root }}/{{ pretalx_domain }}/fullchain.pem;
# ssl_certificate_key {{ pretalx_cert_root }}/{{ pretalx_domain }}/privkey.pem;
# proxy_set_header X-Forwarded-Proto https;
include snippets/letsencrypt-{{ pretalx_domain }}.conf;
{% endif %}
access_log /var/log/nginx/pretalx_{{ pretalx_instance_identifier }}.access.log;
error_log /var/log/nginx/pretalx_{{ pretalx_instance_identifier }}.error.log;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# If you decide to turn gzip on, turn it off explicitly for ~ (*.)/schedule/export/(*.)
# or your export pages won't show their (working, existing) etags.
# You'd think that gzip_proxied no_etag; would work. It doesn't.
gzip off;
location /static/ {
access_log off;
alias {{ pretalx_staticfiles_directory }}/;
}
location /static/CACHE/ {
gzip on;
expires 30d;
add_header Cache-Control public;
add_header Pragma public;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
proxy_cache pretalx_static_{{ pretalx_instance_identifier }};
proxy_ignore_headers Cache-Control;
proxy_cache_valid any 60m;
add_header X-Proxy-Cache $upstream_cache_status;
alias {{ pretalx_staticfiles_directory }}/CACHE/;
}
location /media/ {
gzip on;
alias {{ pretalx_media_dir }}/;
add_header Content-Disposition 'attachment';
}
location / {
proxy_pass http://pretalx_{{ pretalx_instance_identifier }}_server;
}
client_max_body_size 32M;
}

View File

@ -0,0 +1,15 @@
[Unit]
Description=pretalx %I background worker
After=network.target
[Service]
User={{ pretalx_system_user }}
Group={{ pretalx_system_user }}
ExecStart={{ pretalx_virtualenv }}/bin/celery -A pretalx.celery_app worker -l info
WorkingDirectory={{ pretalx_virtualenv }}/lib/python{{ pretalx_system_python_version }}/site-packages/pretalx
Restart=on-failure
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,51 @@
[filesystem]
static = {{ pretalx_staticfiles_directory }}
media = {{ pretalx_media_dir }}
data = {{ pretalx_data_dir }}
[database]
backend = {{ pretalx_database_backend }}
name = {{ pretalx_database_name }}
user = {{ pretalx_database_user }}
password = {{ pretalx_database_password }}
host = {{ pretalx_database_host }}
port = {{ pretalx_database_port }}
[site]
url = {{ pretalx_url }}
{% if pretalx_secret_key %}secret = {{ pretalx_secret_key }}{% endif %}
{% if pretalx_core_modules %}core_modules = {{ pretalx_core_modules }}{% endif %}
[mail]
from = {{ pretalx_mail_from }}
host = {{ pretalx_mail_host }}
port = {{ pretalx_mail_port }}
{% if pretalx_mail_user %}user = {{ pretalx_mail_user }}{% endif %}
{% if pretalx_mail_password %}password = {{ pretalx_mail_password }}{% endif %}
tls = {{ pretalx_mail_tls }}
ssl = {{ pretalx_mail_ssl }}
{% if pretalx_celery -%}
[celery]
backend = {{ pretalx_celery_backend }}
broker = {{ pretalx_celery_broker }}
{%- endif %}
{% if pretalx_redis %}
[redis]
location = {{ pretalx_redis }}
session = True
{% endif %}
{% if pretalx_admin_mail %}
[logging]
email = {{ pretalx_admin_mail }}
{% endif %}
{% if pretalx_additional_config %}{{ pretalx_additional_config }}{% endif %}

View File

@ -0,0 +1,12 @@
[Unit]
Description=pretalx %I server application
Requires=pretalx@%i.socket
After=network.target
[Service]
User={{ pretalx_system_user }}
Group={{ pretalx_system_user }}
WorkingDirectory={{ pretalx_virtualenv }}/lib/python{{ pretalx_system_python_version }}/site-packages/pretalx
ExecStart={{ pretalx_virtualenv }}/bin/gunicorn --bind unix:/run/gunicorn/pretalx_%i --workers {{ pretalx_service_workers }} --max-requests {{ pretalx_service_workers_max_requests }} --max-requests-jitter {{ pretalx_service_workers_max_requests_jitter }} pretalx.wsgi
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID

View File

@ -0,0 +1,8 @@
[Unit]
Description=pretalx_%I gunicorn socket
[Socket]
ListenStream=/run/gunicorn/pretalx_%i
[Install]
WantedBy=sockets.target