dd797ba6a7
We were running into conflicts, because having initialized the roles (users) and databases, trying to import leads to errors (role XXX already exists, etc.). We were previously ignoring the Synapse database (`homeserver`) when upgrading/importing, because that one gets created by default whenever the container starts. For our additional databases, it's a similar situation now. It's not created by default as soon as Postgres starts with an empty database, but rather we create it as part of running the playbook. So we either need to skip those role/database creation statements while upgrading/importing, or to avoid creating the additional database and rely on the import for that. I've gone for the former, because it's already similar to what we were doing and it's simpler (it lets `setup_postgres.yml` be the same in all scenarios).
173 lines
6.7 KiB
YAML
173 lines
6.7 KiB
YAML
---
|
|
|
|
- name: Set default postgres_dump_dir, if not provided
|
|
set_fact:
|
|
postgres_dump_dir: "/tmp"
|
|
when: "postgres_dump_dir|default('') == ''"
|
|
|
|
- name: Set postgres_dump_name, if not provided
|
|
set_fact:
|
|
postgres_dump_name: "matrix-postgres-dump.sql.gz"
|
|
when: "postgres_dump_name|default('') == ''"
|
|
|
|
- name: Set postgres_auto_upgrade_backup_data_path, if not provided
|
|
set_fact:
|
|
postgres_auto_upgrade_backup_data_path: "{{ matrix_postgres_data_path }}-auto-upgrade-backup"
|
|
when: "postgres_auto_upgrade_backup_data_path|default('') == ''"
|
|
|
|
- name: Set postgres_start_wait_time, if not provided
|
|
set_fact:
|
|
postgres_start_wait_time: 15
|
|
when: "postgres_start_wait_time|default('') == ''"
|
|
|
|
- name: Set postgres_force_upgrade, if not provided
|
|
set_fact:
|
|
postgres_force_upgrade: false
|
|
when: "postgres_force_upgrade|default('') == ''"
|
|
|
|
- name: Fail, if trying to upgrade external Postgres database
|
|
fail:
|
|
msg: "Your configuration indicates that you're not using Postgres from this role. There is nothing to upgrade."
|
|
when: "not matrix_postgres_enabled|bool"
|
|
|
|
- name: Check Postgres auto-upgrade backup data directory
|
|
stat:
|
|
path: "{{ postgres_auto_upgrade_backup_data_path }}"
|
|
register: result_auto_upgrade_path
|
|
|
|
- name: Abort, if existing Postgres auto-upgrade data path detected
|
|
fail:
|
|
msg: "Detected that a left-over {{ postgres_auto_upgrade_backup_data_path }} exists. You should rename it to {{ matrix_postgres_data_path }} if the previous upgrade went wrong, or delete it if it went well."
|
|
when: "result_auto_upgrade_path.stat.exists"
|
|
|
|
- import_tasks: tasks/util/detect_existing_postgres_version.yml
|
|
|
|
- name: Abort, if no existing Postgres version detected
|
|
fail:
|
|
msg: "Could not find existing Postgres installation"
|
|
when: "not matrix_postgres_detected_existing|bool"
|
|
|
|
- name: Abort, if already at latest Postgres version
|
|
fail:
|
|
msg: "You are already running the latest Postgres version supported ({{ matrix_postgres_docker_image_latest }}). Nothing to do"
|
|
when: "matrix_postgres_detected_version_corresponding_docker_image == matrix_postgres_docker_image_latest and not postgres_force_upgrade"
|
|
|
|
- debug:
|
|
msg: "Upgrading database from {{ matrix_postgres_detected_version_corresponding_docker_image }} to {{ matrix_postgres_docker_image_latest }}"
|
|
|
|
- name: Ensure matrix-synapse is stopped
|
|
service:
|
|
name: matrix-synapse
|
|
state: stopped
|
|
|
|
- name: Ensure matrix-postgres is started
|
|
service:
|
|
name: matrix-postgres
|
|
state: started
|
|
daemon_reload: yes
|
|
|
|
- name: Wait a bit, so that Postgres can start
|
|
wait_for:
|
|
timeout: "{{ postgres_start_wait_time }}"
|
|
delegate_to: 127.0.0.1
|
|
become: false
|
|
|
|
# We dump all databases, roles, etc.
|
|
#
|
|
# Because we'll be importing into a new container which initializes the default
|
|
# role (`matrix_postgres_connection_username`) and database (`matrix_postgres_db_name`) by itself on startup,
|
|
# we need to remove these from the dump, or we'll get errors saying these already exist.
|
|
- name: Perform Postgres database dump
|
|
command: >-
|
|
{{ matrix_host_command_docker }} run --rm --name matrix-postgres-dump
|
|
--log-driver=none
|
|
--user={{ matrix_user_uid }}:{{ matrix_user_gid }}
|
|
--network={{ matrix_docker_network }}
|
|
--env-file={{ matrix_postgres_base_path }}/env-postgres-psql
|
|
--entrypoint=/bin/sh
|
|
--mount type=bind,src={{ postgres_dump_dir }},dst=/out
|
|
{{ matrix_postgres_detected_version_corresponding_docker_image }}
|
|
-c "pg_dumpall -h matrix-postgres
|
|
{{ '| gzip -c ' if postgres_dump_name.endswith('.gz') else '' }}
|
|
> /out/{{ postgres_dump_name }}"
|
|
|
|
- name: Ensure matrix-postgres is stopped
|
|
service:
|
|
name: matrix-postgres
|
|
state: stopped
|
|
|
|
- name: Rename existing Postgres data directory
|
|
command: "mv {{ matrix_postgres_data_path }} {{ postgres_auto_upgrade_backup_data_path }}"
|
|
|
|
- debug:
|
|
msg: "NOTE: Your Postgres data directory has been moved from `{{ matrix_postgres_data_path }}` to `{{ postgres_auto_upgrade_backup_data_path }}`. In the event of failure, you can move it back and run the playbook with --tags=setup-postgres to restore operation."
|
|
|
|
- import_tasks: tasks/setup_postgres.yml
|
|
|
|
- name: Ensure matrix-postgres autoruns and is restarted
|
|
service:
|
|
name: matrix-postgres
|
|
enabled: yes
|
|
state: restarted
|
|
daemon_reload: yes
|
|
|
|
- name: Wait a bit, so that Postgres can start
|
|
wait_for:
|
|
timeout: "{{ postgres_start_wait_time }}"
|
|
delegate_to: 127.0.0.1
|
|
become: false
|
|
|
|
# Starting the database container had automatically created the default
|
|
# role (`matrix_postgres_connection_username`) and database (`matrix_postgres_db_name`).
|
|
# The dump most likely contains those same entries and would try to re-create them, leading to errors.
|
|
# We need to skip over those lines.
|
|
- name: Generate Postgres database import command
|
|
set_fact:
|
|
matrix_postgres_import_command: >-
|
|
{{ matrix_host_command_docker }} run --rm --name matrix-postgres-import
|
|
--log-driver=none
|
|
--user={{ matrix_user_uid }}:{{ matrix_user_gid }}
|
|
--cap-drop=ALL
|
|
--network={{ matrix_docker_network }}
|
|
--env-file={{ matrix_postgres_base_path }}/env-postgres-psql
|
|
--entrypoint=/bin/sh
|
|
--mount type=bind,src={{ postgres_dump_dir }},dst=/in,ro
|
|
{{ matrix_postgres_docker_image_latest }}
|
|
-c "cat /in/{{ postgres_dump_name }} |
|
|
{{ 'gunzip |' if postgres_dump_name.endswith('.gz') else '' }}
|
|
grep -vE '{{ matrix_postgres_import_roles_ignore_regex }}' |
|
|
grep -vE '{{ matrix_postgres_import_databases_ignore_regex }}' |
|
|
psql -v ON_ERROR_STOP=1 -h matrix-postgres"
|
|
|
|
# This is a hack.
|
|
# See: https://ansibledaily.com/print-to-standard-output-without-escaping/
|
|
#
|
|
# We want to run `debug: msg=".."`, but that dumps it as JSON and escapes double quotes within it,
|
|
# which ruins the command (`matrix_postgres_import_command`)
|
|
- name: Note about Postgres importing
|
|
set_fact:
|
|
dummy: true
|
|
with_items:
|
|
- >-
|
|
Importing Postgres database using the following command: `{{ matrix_postgres_import_command }}`.
|
|
If this crashes, you can stop Postgres (`systemctl stop matrix-postgres`),
|
|
delete the new database data (`rm -rf {{ matrix_postgres_data_path }}`)
|
|
and restore the automatically-made backup (`mv {{ postgres_auto_upgrade_backup_data_path }} {{ matrix_postgres_data_path }}`).
|
|
|
|
- name: Perform Postgres database import
|
|
command: "{{ matrix_postgres_import_command }}"
|
|
|
|
- name: Delete Postgres database dump file
|
|
file:
|
|
path: "{{ postgres_dump_dir }}/{{ postgres_dump_name }}"
|
|
state: absent
|
|
|
|
- name: Ensure matrix-synapse is started
|
|
service:
|
|
name: matrix-synapse
|
|
state: started
|
|
daemon_reload: yes
|
|
|
|
- debug:
|
|
msg: "NOTE: Your old Postgres data directory is preserved at `{{ postgres_auto_upgrade_backup_data_path }}`. You might want to get rid of it once you've confirmed that all is well."
|