148 lines
5.8 KiB
YAML
148 lines
5.8 KiB
YAML
---
|
|
- name: Create Multica install directory
|
|
ansible.builtin.file:
|
|
path: "{{ multica_install_dir }}"
|
|
state: directory
|
|
mode: "0755"
|
|
|
|
- name: Clone / update Multica repository
|
|
ansible.builtin.git:
|
|
repo: "{{ multica_repo_url }}"
|
|
dest: "{{ multica_install_dir }}"
|
|
version: "{{ multica_version }}"
|
|
update: "{{ multica_git_update }}"
|
|
force: false
|
|
register: _multica_git
|
|
|
|
# Optional: dump Postgres before touching a stack that is already running
|
|
- name: Back up Postgres before changes
|
|
when:
|
|
- multica_backup_enabled | bool
|
|
- _multica_compose_stat.stat.exists
|
|
- (_multica_ps.stdout | default('') | length) > 0
|
|
block:
|
|
- name: Create backup directory
|
|
ansible.builtin.file:
|
|
path: "{{ multica_backup_dir }}"
|
|
state: directory
|
|
mode: "0700"
|
|
|
|
- name: Gather date facts
|
|
ansible.builtin.setup:
|
|
gather_subset: [date_time]
|
|
|
|
- name: Dump database (redirect to file first so pg_dump's exit status counts)
|
|
ansible.builtin.shell: >-
|
|
docker compose -p {{ multica_compose_project }} -f {{ _multica_compose_file }}
|
|
exec -T postgres pg_dump -U {{ multica_postgres_user }} {{ multica_postgres_db }}
|
|
> {{ multica_backup_dir }}/multica-{{ ansible_date_time.iso8601_basic_short }}.sql
|
|
&& gzip {{ multica_backup_dir }}/multica-{{ ansible_date_time.iso8601_basic_short }}.sql
|
|
args:
|
|
chdir: "{{ multica_install_dir }}"
|
|
changed_when: true
|
|
|
|
# `make selfhost` only creates .env when missing; we do the same, then manage specific keys.
|
|
- name: Create .env from .env.example (first run only)
|
|
ansible.builtin.copy:
|
|
src: "{{ multica_install_dir }}/.env.example"
|
|
dest: "{{ multica_install_dir }}/.env"
|
|
remote_src: true
|
|
force: false
|
|
mode: "0600"
|
|
|
|
- name: Set managed keys in .env
|
|
ansible.builtin.lineinfile:
|
|
path: "{{ multica_install_dir }}/.env"
|
|
regexp: "^{{ item.key }}="
|
|
line: "{{ item.key }}={{ item.value }}"
|
|
mode: "0600"
|
|
loop: "{{ _multica_env | dict2items }}"
|
|
loop_control:
|
|
label: "{{ item.key }}"
|
|
no_log: "{{ multica_no_log }}"
|
|
|
|
# .env.example ships a DATABASE_URL with the default password embedded. POSTGRES_PASSWORD alone does not
|
|
# change it, so keep the URL's password in step (no-op if the line is absent or already matches).
|
|
- name: Sync password inside DATABASE_URL
|
|
ansible.builtin.replace:
|
|
path: "{{ multica_install_dir }}/.env"
|
|
regexp: '^(DATABASE_URL=[a-z]+://[^:/@]+:)[^@]*(@.*)$'
|
|
replace: '\g<1>{{ multica_postgres_password }}\g<2>'
|
|
mode: "0600"
|
|
no_log: "{{ multica_no_log }}"
|
|
|
|
# Compose re-reads .env and recreates containers whose config changed (equivalent of `up -d`).
|
|
- name: Start / update Multica stack
|
|
community.docker.docker_compose_v2:
|
|
project_name: "{{ multica_compose_project }}"
|
|
project_src: "{{ multica_install_dir }}"
|
|
files:
|
|
- "{{ _multica_compose_file }}"
|
|
state: present
|
|
pull: "{{ 'always' if multica_pull_latest | bool else 'missing' }}"
|
|
recreate: auto
|
|
register: _multica_up
|
|
|
|
# Postgres only reads POSTGRES_PASSWORD when the data volume is first initialised. If the volume pre-dates this
|
|
# run (or the vault value changed), the DB user keeps the old password and the backend can't log in.
|
|
# Test over TCP (the local socket is trust-auth and proves nothing) and repair via the socket if needed.
|
|
- name: Wait for Postgres to accept connections
|
|
ansible.builtin.command:
|
|
argv: ["docker", "compose", "-p", "{{ multica_compose_project }}", "-f", "{{ _multica_compose_file }}",
|
|
"exec", "-T", "postgres", "pg_isready", "-U", "{{ multica_postgres_user }}", "-d", "{{ multica_postgres_db }}"]
|
|
chdir: "{{ multica_install_dir }}"
|
|
register: _multica_pg_ready
|
|
until: _multica_pg_ready.rc == 0
|
|
retries: 24
|
|
delay: 5
|
|
changed_when: false
|
|
|
|
- name: Test database login with the configured password (over TCP)
|
|
ansible.builtin.command:
|
|
argv: ["docker", "compose", "-p", "{{ multica_compose_project }}", "-f", "{{ _multica_compose_file }}",
|
|
"exec", "-T", "-e", "PGPASSWORD", "postgres", "sh", "-c",
|
|
"psql -h \"$(hostname -i | cut -d' ' -f1)\" -U {{ multica_postgres_user }} -d {{ multica_postgres_db }} -tAc 'select 1'"]
|
|
chdir: "{{ multica_install_dir }}"
|
|
environment:
|
|
PGPASSWORD: "{{ multica_postgres_password }}"
|
|
register: _multica_pg_auth
|
|
changed_when: false
|
|
failed_when:
|
|
- _multica_pg_auth.rc != 0
|
|
- "'password authentication failed' not in _multica_pg_auth.stderr"
|
|
no_log: "{{ multica_no_log }}"
|
|
|
|
- name: Reset database user password to match .env
|
|
when: _multica_pg_auth.rc != 0
|
|
block:
|
|
- name: ALTER USER via local socket (password passed on stdin)
|
|
ansible.builtin.command:
|
|
argv: ["docker", "compose", "-p", "{{ multica_compose_project }}", "-f", "{{ _multica_compose_file }}",
|
|
"exec", "-T", "postgres", "psql", "-v", "ON_ERROR_STOP=1",
|
|
"-U", "{{ multica_postgres_user }}", "-d", "{{ multica_postgres_db }}"]
|
|
chdir: "{{ multica_install_dir }}"
|
|
stdin: "ALTER USER {{ multica_postgres_user }} PASSWORD '{{ multica_postgres_password }}';"
|
|
changed_when: true
|
|
no_log: "{{ multica_no_log }}"
|
|
|
|
- name: Restart backend so it reconnects
|
|
ansible.builtin.command:
|
|
argv: ["docker", "compose", "-p", "{{ multica_compose_project }}", "-f", "{{ _multica_compose_file }}",
|
|
"restart", "backend"]
|
|
chdir: "{{ multica_install_dir }}"
|
|
changed_when: true
|
|
|
|
- name: Wait for backend /readyz (db + migrations ok)
|
|
ansible.builtin.uri:
|
|
url: "http://127.0.0.1:{{ _multica_backend_port }}/readyz"
|
|
return_content: true
|
|
status_code: 200
|
|
register: _multica_ready
|
|
until: >-
|
|
_multica_ready.status == 200 and
|
|
(_multica_ready.json.checks.db | default('')) == 'ok' and
|
|
(_multica_ready.json.checks.migrations | default('')) == 'ok'
|
|
retries: 30
|
|
delay: 5
|
|
changed_when: false
|