--- - name: Fail if Postgres not enabled ansible.builtin.fail: msg: "Postgres via the matrix-postgres role is not enabled (`matrix_postgres_enabled`). Cannot migrate." when: "not matrix_postgres_enabled | bool" - name: Fail if util called incorrectly (missing matrix_postgres_db_migration_request) ansible.builtin.fail: msg: "The `matrix_postgres_db_migration_request` variable needs to be provided to this util." when: "matrix_postgres_db_migration_request is not defined" - name: Fail if util called incorrectly (invalid matrix_postgres_db_migration_request) ansible.builtin.fail: msg: "The `matrix_postgres_db_migration_request` variable needs to contain `{{ item }}`." with_items: - src - dst - caller - engine_variable_name - systemd_services_to_stop when: "item not in matrix_postgres_db_migration_request" - name: Check if the provided source database file exists ansible.builtin.stat: path: "{{ matrix_postgres_db_migration_request.src }}" register: matrix_postgres_db_migration_request_src_stat_result - name: Fail if provided source database file doesn't exist ansible.builtin.fail: msg: "File cannot be found on the server at {{ matrix_postgres_db_migration_request.src }}" when: "not matrix_postgres_db_migration_request_src_stat_result.stat.exists" - when: "matrix_postgres_pgloader_container_image_self_build | bool" block: - name: Ensure pgloader repository is present on self-build ansible.builtin.git: repo: "{{ matrix_postgres_pgloader_container_image_self_build_repo }}" dest: "{{ matrix_postgres_pgloader_container_image_self_build_src_path }}" version: "{{ matrix_postgres_pgloader_container_image_self_build_repo_branch }}" force: "yes" become: true become_user: "{{ matrix_user_username }}" register: matrix_postgres_pgloader_git_pull_results # If `stable` is used, we hit an error when processing /opt/src/pgloader/build/quicklisp/dists/quicklisp/software/uax-15-20201220-git/data/CompositionExclusions.txt: # > the octet sequence #(194) cannot be decoded # # The issue is described here and is not getting fixed for months: https://github.com/dimitri/pgloader/pull/1179 # # Although we're not using the dimitri/pgloader image, the one we're using suffers from the same problem. - name: Switch pgloader base image from Debian stable (likely 10.x/Buster) to Bullseye ansible.builtin.lineinfile: path: "{{ matrix_postgres_pgloader_container_image_self_build_src_path }}/Dockerfile" regexp: "{{ item.match }}" line: "{{ item.replace }}" with_items: - match: '^FROM debian:stable-slim as builder$' replace: 'FROM debian:bullseye-slim as builder' - match: '^FROM debian:stable-slim$' replace: 'FROM debian:bullseye-slim' - name: Ensure pgloader Docker image is built docker_image: name: "{{ matrix_postgres_pgloader_docker_image }}" source: build force_source: "{{ matrix_postgres_pgloader_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_postgres_pgloader_git_pull_results.changed }}" build: dockerfile: Dockerfile path: "{{ matrix_postgres_pgloader_container_image_self_build_src_path }}" pull: true - name: Ensure pgloader Docker image is pulled docker_image: name: "{{ matrix_postgres_pgloader_docker_image }}" source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" force_source: "{{ matrix_postgres_pgloader_docker_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_postgres_pgloader_docker_image_force_pull }}" when: "not matrix_postgres_pgloader_container_image_self_build" # Defaults - name: Set postgres_start_wait_time, if not provided ansible.builtin.set_fact: postgres_start_wait_time: 15 when: "postgres_start_wait_time | default('') == ''" # Actual import work # matrix-postgres is most likely started already - name: Ensure matrix-postgres is started ansible.builtin.service: name: matrix-postgres state: started daemon_reload: true register: matrix_postgres_service_start_result - name: Wait a bit, so that Postgres can start ansible.builtin.wait_for: timeout: "{{ postgres_start_wait_time }}" delegate_to: 127.0.0.1 become: false when: "matrix_postgres_service_start_result.changed | bool" # We only stop services here, leaving it to the caller to start them later. # # We can't start them, because they probably need to be reconfigured too (changing the configuration from using SQLite to Postgres, etc.), # before starting. # # Since the caller will be starting them, it might make sense to leave stopping to it as well. # However, we don't do it, because it's simpler having it here, and it also gets to happen only if we'll be doing an import. # If we bailed out (somewhere above), nothing would have gotten stopped. It's nice to leave this running in such cases. - name: Ensure systemd services blocking the database import are stopped ansible.builtin.service: name: "{{ item }}" state: stopped failed_when: false with_items: "{{ matrix_postgres_db_migration_request.systemd_services_to_stop }}" - name: Import {{ matrix_postgres_db_migration_request.engine_old }} database from {{ matrix_postgres_db_migration_request.src }} into Postgres # noqa name[template] ansible.builtin.command: cmd: >- {{ matrix_host_command_docker }} run --rm --user={{ matrix_user_uid }}:{{ matrix_user_gid }} --cap-drop=ALL --network={{ matrix_docker_network }} --mount type=bind,src={{ matrix_postgres_db_migration_request.src }},dst=/in.db,ro --entrypoint=/bin/sh {{ matrix_postgres_pgloader_docker_image }} -c 'pgloader {{ matrix_postgres_db_migration_request.pgloader_options | default([]) | join(' ') }} /in.db {{ matrix_postgres_db_migration_request.dst }}' register: matrix_postgres_migrate_db_to_postgres_import_result changed_when: matrix_postgres_migrate_db_to_postgres_import_result.rc == 0 - when: "matrix_postgres_db_migration_request.additional_psql_statements_list | default([]) | length > 0" block: - ansible.builtin.import_role: name: matrix-postgres tasks_from: detect_existing_postgres_version - ansible.builtin.set_fact: matrix_postgres_docker_image_to_use: "{{ matrix_postgres_docker_image_latest if matrix_postgres_detected_version_corresponding_docker_image == '' else matrix_postgres_detected_version_corresponding_docker_image }}" - name: Execute additional Postgres SQL migration statements ansible.builtin.command: cmd: >- {{ matrix_host_command_docker }} run --rm --user={{ matrix_user_uid }}:{{ matrix_user_gid }} --cap-drop=ALL --env-file={{ matrix_postgres_base_path }}/env-postgres-psql --network={{ matrix_docker_network }} {{ matrix_postgres_docker_image_to_use }} psql --host=matrix-postgres --dbname={{ matrix_postgres_db_migration_request.additional_psql_statements_db_name }} --command='{{ item }}' with_items: "{{ matrix_postgres_db_migration_request.additional_psql_statements_list }}" register: matrix_postgres_migrate_db_to_postgres_additional_queries_result changed_when: matrix_postgres_migrate_db_to_postgres_additional_queries_result.rc == 0 - name: Archive {{ matrix_postgres_db_migration_request.engine_old }} database ({{ matrix_postgres_db_migration_request.src }} -> {{ matrix_postgres_db_migration_request.src }}.backup) # noqa name[template] ansible.builtin.command: cmd: "mv {{ matrix_postgres_db_migration_request.src }} {{ matrix_postgres_db_migration_request.src }}.backup" register: matrix_postgres_migrate_db_to_postgres_move_result changed_when: matrix_postgres_migrate_db_to_postgres_move_result.rc == 0 - name: Inject result ansible.builtin.set_fact: matrix_playbook_runtime_results: | {{ matrix_playbook_runtime_results | default([]) + [ "NOTE: Your {{ matrix_postgres_db_migration_request.engine_old }} database file has been imported into Postgres. The original database file has been moved from `{{ matrix_postgres_db_migration_request.src }}` to `{{ matrix_postgres_db_migration_request.src }}.backup`. When you've confirmed that the import went well and everything works, you should be able to safely delete this file." ] }}