Add support for upgrading Postgres

Since cbee084ac1, this playbook supports Postgres 10.x,
but keeps existing Postgres-9.x installs on 9.x.

This playbook can now also be ran with `--tags=upgrade-postgres`
to make it upgrade from Postgres 9.x to 10.x (or other versions
in the future).
This commit is contained in:
Slavi Pantaleev 2018-05-28 20:40:42 +03:00
parent cbee084ac1
commit d107ab2540
4 changed files with 153 additions and 0 deletions

View File

@ -259,6 +259,28 @@ You can do it via this Ansible playbook (make sure to edit the `<your-username>`
**Note**: `<your-username>` is just a plain username (like `john`), not your full `@<username>:<your-domain>` identifier.
### Upgrading Postgres
If you're not using an external Postgres server, this playbook initially installs Postgres for you.
Once installed like that, this playbook attempts to preserve the Postgres version it starts with.
This is because newer Postgres versions cannot start with data generated by an older Postgres version.
An upgrade must be performed.
This playbook can upgrade your existing Postgres setup with the following command:
ansible-playbook -i inventory/hosts setup.yml --tags=upgrade-postgres
**The old Postgres data directory is backed up** (by renaming to `/matrix/postgres-auto-upgrade-backup`).
It stays around forever, until you **manually decide to delete it**.
As part of the upgrade, the database is dumped to `/tmp`, upgraded and then restored from that dump.
To use a different directory, pass some extra flags to the command above, like this: `--extra-vars="postgres_dump_dir=/directory/to/dump/here"`
**ONLY one database is migrated** (the one specified in `matrix_postgres_db_name`, named `homeserver` by default).
If you've created other databases in that database instance (something this playbook never does and never advises), data will be lost.
## Uninstalling
**Note**: If you have some trouble with your installation configuration, you can just re-run the playbook and it will try to set things up again. You don't need to uninstall and install fresh.

View File

@ -13,6 +13,10 @@
- setup-main
- setup-ssl
- include: tasks/upgrade_postgres.yml
tags:
- upgrade-postgres
- include: tasks/setup_postgres.yml
tags:
- setup-main

View File

@ -33,6 +33,10 @@
docker_postgres_image_to_use: "{{ docker_postgres_image_v9 }}"
when: "pg_version.startswith('9.')"
- debug:
msg: "NOTE: Your setup is on an old Postgres version ({{ docker_postgres_image_to_use }}), while {{ docker_postgres_image_latest }} is supported. You can upgrade using --tags=upgrade-postgres"
when: "docker_postgres_image_to_use != docker_postgres_image_latest"
# Even if we don't run the internal server, we still need this for running the CLI
- name: Ensure postgres Docker image is pulled
docker_image:

View File

@ -0,0 +1,123 @@
---
- 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.out"
when: "postgres_dump_name|default('') == ''"
- set_fact:
postgres_auto_upgrade_backup_data_path: "{{ matrix_postgres_data_path }}-auto-upgrade-backup"
- name: Fail, if trying to upgrade external Postgres database
fail:
msg: "Your configuration indicates that you're using an external Postgres database. Refusing to try and upgrade that."
when: "matrix_postgres_use_external"
- 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"
- name: Determine existing Postgres version (check PG_VERSION file)
stat:
path: "{{ matrix_postgres_data_path }}/PG_VERSION"
register: result_pg_version_stat
- name: Abort, if no existing Postgres version detected
fail: msg="Could not find existing Postgres installation"
when: "not result_pg_version_stat.stat.exists"
- name: Determine existing Postgres version (read PG_VERSION file)
slurp:
src: "{{ matrix_postgres_data_path }}/PG_VERSION"
register: result_pg_version
- name: Determine existing Postgres version (default to empty)
set_fact:
pg_version: ""
- name: Determine existing Postgres version (make sense of PG_VERSION file)
set_fact:
pg_version: "{{ result_pg_version['content']|b64decode|replace('\n', '') }}"
- name: Determine Postgres version to use (default to latest)
set_fact:
docker_postgres_image_to_use: "{{ docker_postgres_image_latest }}"
- name: Determine Postgres version to use (use 9.x, if detected)
set_fact:
docker_postgres_image_to_use: "{{ docker_postgres_image_v9 }}"
when: "pg_version.startswith('9.')"
- name: Abort, if already at latest Postgres version
fail: msg="You are already running the latest Postgres version supported. Nothing to do"
when: "docker_postgres_image_to_use == docker_postgres_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: 5
delegate_to: 127.0.0.1
become: false
- name: Perform Postgres database dump
command: |
/usr/bin/docker run --rm --name matrix-postgres-dump \
--link matrix-postgres:postgres \
--env-file=/matrix/environment-variables/env-postgres-pgsql-docker \
-v {{ postgres_dump_dir }}:/out \
{{ docker_postgres_image_to_use }} pg_dump -h postgres {{ matrix_postgres_db_name }} -f /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."
- include: 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: 5
delegate_to: 127.0.0.1
become: false
- name: Perform Postgres database import
command: |
/usr/bin/docker run --rm --name matrix-postgres-import \
--link matrix-postgres:postgres \
--env-file=/matrix/environment-variables/env-postgres-pgsql-docker \
-v {{ postgres_dump_dir }}:/in:ro \
{{ docker_postgres_image_to_use }} psql -h postgres -f /in/{{ postgres_dump_name }}
- 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."