From 0c4447fba0efda8ba40ed43d54841eaee76f9799 Mon Sep 17 00:00:00 2001 From: transcaffeine Date: Sat, 13 Sep 2025 16:43:19 +0200 Subject: [PATCH] feat(pretix): add ansible role and playbook --- playbooks/pretix.yml | 7 +++++ roles/pretix/README.md | 16 ++++++++++ roles/pretix/defaults/main/main.yml | 14 +++++++++ .../pretix/defaults/main/system_packages.yml | 21 ++++++++++++++ roles/pretix/defaults/main/systemd.yml | 19 ++++++++++++ roles/pretix/defaults/main/user.yml | 7 +++++ roles/pretix/defaults/main/virtualenv.yml | 11 +++++++ roles/pretix/meta/main.yml | 9 ++++++ roles/pretix/tasks/check.yml | 14 +++++++++ roles/pretix/tasks/configure.yml | 9 ++++++ roles/pretix/tasks/deploy-systemd.yml | 19 ++++++++++++ roles/pretix/tasks/deploy.yml | 5 ++++ roles/pretix/tasks/main.yml | 16 ++++++++++ roles/pretix/tasks/prepare-systemd.yml | 19 ++++++++++++ roles/pretix/tasks/prepare.yml | 29 +++++++++++++++++++ roles/pretix/templates/pretix.service.j2 | 16 ++++++++++ roles/pretix/vars/main.yml | 7 +++++ 17 files changed, 238 insertions(+) create mode 100644 playbooks/pretix.yml create mode 100644 roles/pretix/README.md create mode 100644 roles/pretix/defaults/main/main.yml create mode 100644 roles/pretix/defaults/main/system_packages.yml create mode 100644 roles/pretix/defaults/main/systemd.yml create mode 100644 roles/pretix/defaults/main/user.yml create mode 100644 roles/pretix/defaults/main/virtualenv.yml create mode 100644 roles/pretix/meta/main.yml create mode 100644 roles/pretix/tasks/check.yml create mode 100644 roles/pretix/tasks/configure.yml create mode 100644 roles/pretix/tasks/deploy-systemd.yml create mode 100644 roles/pretix/tasks/deploy.yml create mode 100644 roles/pretix/tasks/main.yml create mode 100644 roles/pretix/tasks/prepare-systemd.yml create mode 100644 roles/pretix/tasks/prepare.yml create mode 100644 roles/pretix/templates/pretix.service.j2 create mode 100644 roles/pretix/vars/main.yml diff --git a/playbooks/pretix.yml b/playbooks/pretix.yml new file mode 100644 index 0000000..6acaac7 --- /dev/null +++ b/playbooks/pretix.yml @@ -0,0 +1,7 @@ +--- +- name: Install and configure pretix + hosts: "{{ pretix_hosts | default('pretix') }}" + become: "{{ pretix_become | default(true) }}" + gather_facts: "{{ pretix_gather_facts | default(false) }}" + roles: + - role: pretix diff --git a/roles/pretix/README.md b/roles/pretix/README.md new file mode 100644 index 0000000..0199be2 --- /dev/null +++ b/roles/pretix/README.md @@ -0,0 +1,16 @@ +# `finallycoffee.services.pretix` ansible role + + +## Troubleshooting + +### virtualenv + +By default, the virtualenv is located in `/var/lib/pretix/virtualenv`. +This can be controlled by setting `pretix_virtualenv_dir`. + +NOTE: To fix a broken virtualenv, try setting `pretix_virtualenv_state` to `forcereinstall` (see +[`ansible.builtin.pip` on docs.ansible.com](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/pip_module.html)). + +NOTE: To install pip packages or execute migrations in the virtualenv, ansible +needs to become the unprivilated `pretix_user` (default: `pretix`). This might +require having the `acl` system package installed. diff --git a/roles/pretix/defaults/main/main.yml b/roles/pretix/defaults/main/main.yml new file mode 100644 index 0000000..3cd1b54 --- /dev/null +++ b/roles/pretix/defaults/main/main.yml @@ -0,0 +1,14 @@ +--- +pretix_version: "2025.7.1" +pretix_state: "present" +pretix_deployment_method: "systemd" + +pretix_config_file: "/etc/pretix/pretix.cfg" +pretix_config_file_owner: "{{ pretix_user_id }}" +pretix_config_file_group: "{{ pretix_group_id }}" +pretix_config_file_mode: "0640" +pretix_config_dir: "{{ pretix_config_file | dirname }}" +pretix_install_dir: "/var/lib/pretix" +pretix_virtualenv_dir: "{{ pretix_install_dir }}/virtualenv" +pretix_data_dir: "{{ pretix_install_dir }}/data" +pretix_media_dir: "{{ pretix_data_dir }}/media" diff --git a/roles/pretix/defaults/main/system_packages.yml b/roles/pretix/defaults/main/system_packages.yml new file mode 100644 index 0000000..54c8c3d --- /dev/null +++ b/roles/pretix/defaults/main/system_packages.yml @@ -0,0 +1,21 @@ +--- +pretix_debian_packages: + - "git" + - "build-essential" + - "python3-dev" + - "python3-venv" + - "python3" + - "python3-pip" + - "libxml2-dev" + - "libxslt1-dev" + - "libffi-dev" + - "zlib1g-dev" + - "libssl-dev" + - "gettext" + - "libpq-dev" + - "libjpeg-dev" + - "libopenjp2-7-dev" + +pretix_packages: + "debian": + "12": "{{ pretix_debian_packages }}" diff --git a/roles/pretix/defaults/main/systemd.yml b/roles/pretix/defaults/main/systemd.yml new file mode 100644 index 0000000..0590f01 --- /dev/null +++ b/roles/pretix/defaults/main/systemd.yml @@ -0,0 +1,19 @@ +--- +pretix_systemd_unit_description: "pretix web service" +pretix_systemd_unit_after: "network.target" + +pretix_systemd_service_user: "{{ pretix_user }}" +pretix_systemd_service_group: "{{ pretix_user }}" +pretix_systemd_service_environment: + VIRTUAL_ENV: "{{ pretix_virtualenv_dir }}" +pretix_systemd_service_working_directory: "{{ pretix_install_dir }}" +pretix_systemd_service_exec_start: >-2 + {{ pretix_virtualenv_dir }}/bin/gunicorn pretix.wsgi + --name pretix + --workers 5 + --max-requests 100 + --log-level=info + --bind=127.0.0.1:8345 +pretix_systemd_service_restart: "on-failure" + +pretix_systemd_install_wanted_by: "multi-user.target" diff --git a/roles/pretix/defaults/main/user.yml b/roles/pretix/defaults/main/user.yml new file mode 100644 index 0000000..5236d37 --- /dev/null +++ b/roles/pretix/defaults/main/user.yml @@ -0,0 +1,7 @@ +--- +pretix_user: "pretix" +pretix_user_system: true +pretix_user_create_home: false + +pretix_user_id: "{{ pretix_user_info.uid | default(pretix_user) }}" +pretix_group_id: "{{ pretix_user_info.group | default(pretix_user) }}" diff --git a/roles/pretix/defaults/main/virtualenv.yml b/roles/pretix/defaults/main/virtualenv.yml new file mode 100644 index 0000000..8d947ae --- /dev/null +++ b/roles/pretix/defaults/main/virtualenv.yml @@ -0,0 +1,11 @@ +--- +pretix_virtualenv_state: "{{ pretix_state }}" +pretix_virtualenv_packages: + - "pip" + - "setuptools" + - "wheel" + - "gunicorn" + - "pretix=={{ pretix_version }}" + +pretix_virtualenv_site_packages: false +pretix_virtualenv_command: "virtualenv" diff --git a/roles/pretix/meta/main.yml b/roles/pretix/meta/main.yml new file mode 100644 index 0000000..bbd0558 --- /dev/null +++ b/roles/pretix/meta/main.yml @@ -0,0 +1,9 @@ +--- +allow_duplicates: true +dependencies: [] +galaxy_info: + role_name: pretix + description: Ansible role to deploy pretix (https://pretix.eu) + galaxy_tags: + - pretix + - ticketing diff --git a/roles/pretix/tasks/check.yml b/roles/pretix/tasks/check.yml new file mode 100644 index 0000000..04088f2 --- /dev/null +++ b/roles/pretix/tasks/check.yml @@ -0,0 +1,14 @@ +--- +- name: Ensure 'pretix_state' is valid + ansible.builtin.fail: + msg: >-2 + Unsupported pretix_state '{{ pretix_state }}'. + Supported states are {{ pretix_states | join(', ') }} + when: pretix_state not in pretix_states + +- name: Ensure 'pretix_deployment_method' is valid + ansible.builtin.fail: + msg: >-2 + Unsupported pretix_state '{{ pretix_deployment_method }}'. + Supported states are {{ pretix_deployment_methods | join(', ') }} + when: pretix_deployment_method not in pretix_deployment_methods diff --git a/roles/pretix/tasks/configure.yml b/roles/pretix/tasks/configure.yml new file mode 100644 index 0000000..5297704 --- /dev/null +++ b/roles/pretix/tasks/configure.yml @@ -0,0 +1,9 @@ +--- +- name: Ensure configuration file is written + ansible.builtin.copy: + path: "{{ pretix_config_file }}" + content: "{{ pretix_config_file_content }}" + owner: "{{ pretix_config_file_owner }}" + group: "{{ pretix_config_file_group }}" + mode: "{{ pretix_config_file_mode }}" + when: ansible_state == 'present' diff --git a/roles/pretix/tasks/deploy-systemd.yml b/roles/pretix/tasks/deploy-systemd.yml new file mode 100644 index 0000000..f75783d --- /dev/null +++ b/roles/pretix/tasks/deploy-systemd.yml @@ -0,0 +1,19 @@ +--- +- name: Ensure virtualenv in {{ pretix_virtualenv_dir }} is present + ansible.builtin.pip: + name: "{{ pretix_virtualenv_packages }}" + state: "{{ pretix_virtualenv_state }}" + chdir: "{{ pretix_install_dir }}" + virtualenv: "{{ pretix_virtualenv_dir }}" + virtualenv_command: "{{ pretix_virtualenv_command }}" + virtualenv_site_packages: "{{ pretix_virtualenv_site_packages }}" + become: true + become_user: "{{ pretix_user }}" + +# TODO: determine to only do this on a) upgrades or b) initial deployis +- name: Ensure pretix static assets are built + ansible.builtin.command: + cmd: "{{ pretix_virtualenv_dir }}/bin/python -m pretix rebuild" + chdir: "{{ pretix_install_dir }}" + environment: + VIRTUAL_ENV: "{{ pretix_virtualenv_dir }}" diff --git a/roles/pretix/tasks/deploy.yml b/roles/pretix/tasks/deploy.yml new file mode 100644 index 0000000..e4b340c --- /dev/null +++ b/roles/pretix/tasks/deploy.yml @@ -0,0 +1,5 @@ +--- +- name: Ensure pretix is deployed using {{ pretix_deployment_method }} + ansible.builtin.include_tasks: + file: "deploy-{{ pretix_deployment_method }}.yml" + when: pretix_state == 'present' diff --git a/roles/pretix/tasks/main.yml b/roles/pretix/tasks/main.yml new file mode 100644 index 0000000..1cb4ea5 --- /dev/null +++ b/roles/pretix/tasks/main.yml @@ -0,0 +1,16 @@ +--- +- name: Ensure preconditions are met + ansible.builtin.include_tasks: + file: "check.yml" + +- name: Ensure deployment preparations are done + ansible.builtin.include_tasks: + file: "prepare.yml" + +- name: Ensure pretix is configured + ansible.builtin.include_tasks: + file: "configure.yml" + +- name: Ensure pretix is deployed + ansible.builtin.include_tasks: + file: "deploy.yml" diff --git a/roles/pretix/tasks/prepare-systemd.yml b/roles/pretix/tasks/prepare-systemd.yml new file mode 100644 index 0000000..03cf5f1 --- /dev/null +++ b/roles/pretix/tasks/prepare-systemd.yml @@ -0,0 +1,19 @@ +--- +- name: Ensure ansible facts are collected + ansible.builtin.setup: + gather_subset: + - "!all" + - "pkg_mgr" + - "distribution" + - "distribution_release" + - "distribution_version" + - "distribution_major_version" + +- name: Ensure system packages are present (apt) + ansible.builtin.apt: + name: "{{ package }}" + state: "{{ pretix_state }}" + loop: "{{ pretix_packages[ansible_distribution | lower] }}" + loop_control: + loop_var: "package" + when: ansible_facts['pkg_mgr'] == 'apt' diff --git a/roles/pretix/tasks/prepare.yml b/roles/pretix/tasks/prepare.yml new file mode 100644 index 0000000..3bea8cc --- /dev/null +++ b/roles/pretix/tasks/prepare.yml @@ -0,0 +1,29 @@ +--- +- name: Ensure pretix user '{{ pretix_user }}' is {{ pretix_state }} + ansible.builtin.user: + name: "{{ pretix_user }}" + state: "{{ pretix_state }}" + system: "{{ pretix_user_system }}" + create_home: "{{ pretix_user_create_home }}" + register: pretix_user_info + +- name: Ensure host directories are {{ pretix_state }} + ansible.builtin.file: + path: "{{ item.path }}" + owner: "{{ item.owner | default(pretix_user_id) }}" + group: "{{ item.group | default(pretix_group_id) }}" + mode: "{{ item.mode | default('0750') }}" + state: "directory" + loop: + - path: "{{ pretix_config_dir }}" + - path: "{{ pretix_virtualenv_dir }}" + - path: "{{ pretix_data_dir }}" + - path: "{{ pretix_media_dir }}" + when: pretix_state == 'present' + +- name: Ensure deployment-type specific preparations for '{{ pretix_deployment_method }}' are run + ansible.builtin.include_tasks: + file: "prepare-{{ pretix_deployment_method }}.yml" + when: + - pretix_state == 'present' + - pretix_deployment_method in ['systemd'] diff --git a/roles/pretix/templates/pretix.service.j2 b/roles/pretix/templates/pretix.service.j2 new file mode 100644 index 0000000..c4cfe08 --- /dev/null +++ b/roles/pretix/templates/pretix.service.j2 @@ -0,0 +1,16 @@ +[Unit] +Description={{ pretix_systemd_unit_description }} +After={{ pretix_systemd_unit_after }} + +[Service] +User={{ pretix_systemd_service_user }} +Group={{ pretix_systemd_service_group }} +{% for kv in pretix_systemd_service_environment | dict2items %} +Environment="{{ kv.key }}={{ kv.value }}" +{% endfor %} +WorkingDirectory={{ pretix_systemd_service_working_directory }} +ExecStart={{ pretix_systemd_service_exec_start }} +Restart={{ pretix_systemd_service_restart }} + +[Install] +WantedBy={{ pretix_systemd_install_wanted_by }} diff --git a/roles/pretix/vars/main.yml b/roles/pretix/vars/main.yml new file mode 100644 index 0000000..464f8aa --- /dev/null +++ b/roles/pretix/vars/main.yml @@ -0,0 +1,7 @@ +--- +pretix_states: + - "present" + - "absent" + +pretix_deployment_methods: + - "systemd"