# This playbook will check for migrations to rollback for Django applications within a larger # Django project. The provided input file will determine what migrations should be rolled back. # # The playbook uses the Django management commands found in this Django app repo: # https://github.com/edx/edx-django-release-util # So the Django app above needs to be installed in the Django project. # # Required variables for this playbook: # # - APPLICATION_PATH - the top-level path of the Django application; the application lives underneath # this directory in a directory with the same name as APPLICATION_NAME. # NOTE: It is assumed that edx-django-release-util is one of its INSTALLED_APPS. # - APPLICATION_NAME - The name of the application that we are migrating. # - APPLICATION_USER - user which is meant to run the application # - ARTIFACT_PATH - the path where the migration artifacts should be copied after completion # - initial_states - An array of the migrations # - database - Name of the database to run the rollback against # # Other variables: # - migration_result - the filename where the migration output is saved # - SUB_APPLICATION_NAME - used for migrations in edxapp {lms|cms}, must be specified # when APPLICATION_NAME is edxapp # - EDX_PLATFORM_SETTINGS - The settings to use for the edx platform {aws|devstack} DEFAULT: aws # - HIPCHAT_TOKEN - API token to send messages to hipchat # - HIPCHAT_ROOM - ID or name of the room to send the notification # - HIPCHAT_URL - URL of the hipchat API (defaults to v1 of the api) # # Example command line to run this playbook: # ansible-playbook \ # -vvvv \ # -i ../{artifact_path}/ansible_inventory \ # --private-key=$PRIVATE_KEY \ # --module-path=playbooks/library \ # --user=ubuntu \ # -e APPLICATION_PATH=$APPLICATION_PATH \ # -e APPLICATION_NAME=$APPLICATION_NAME \ # -e APPLICATION_USER=$APPLICATION_USER \ # -e ARTIFACT_PATH=`/bin/pwd`/../{artifact_path}/migrations \ # -e DB_MIGRATION_USER=$DB_MIGRATION_USER \ # -e DB_MIGRATION_PASS=$DB_MIGRATION_PASS \ # -e @../{artifact_path}/migration_input_file.yml \ # -e SUB_APPLICATION_NAME={sub_application_name} \ # playbooks/continuous_delivery/rollback_migrations.yml - hosts: all gather_facts: false become: true vars: COMMAND_PREFIX: ". {{ APPLICATION_PATH }}/{{ APPLICATION_NAME }}_env; DB_MIGRATION_USER={{ DB_MIGRATION_USER }} DB_MIGRATION_PASS='{{ DB_MIGRATION_PASS }}' /edx/bin/python.{{ APPLICATION_NAME }} /edx/bin/manage.{{ APPLICATION_NAME }} " EDX_PLATFORM_SETTINGS: "aws" rollback_result: rollback_result.yml original_state: original_state.yml migration_plan: migration_plan.yml migration_result: migration_result.yml database: default vars_files: - roles/edxapp/defaults/main.yml tasks: - name: Create a temporary directory for the migration output. command: mktemp -d become_user: "{{ APPLICATION_USER }}" register: temp_output_dir - name: generate current migration state shell: > {{ COMMAND_PREFIX }} show_unapplied_migrations --output_file '{{ temp_output_dir.stdout }}/{{ original_state }}' become_user: "{{ APPLICATION_USER }}" when: APPLICATION_NAME != "edxapp" - name: generate current migration state for edxapp shell: > {{ COMMAND_PREFIX }} {{ SUB_APPLICATION_NAME }} show_unapplied_migrations --database '{{ database }}' --output_file '{{ temp_output_dir.stdout }}/{{ database }}_{{ original_state }}' --settings '{{ EDX_PLATFORM_SETTINGS }}' become_user: "{{ APPLICATION_USER }}" when: APPLICATION_NAME == "edxapp" - name: migrate to original versions shell: > {{ COMMAND_PREFIX }} run_specific_migrations --migration '{{ item.app }}' '{{ item.migration }}' --output_file '{{ temp_output_dir.stdout }}/{{ migration_plan }}' become_user: "{{ APPLICATION_USER }}" with_items: "{{ initial_states }}" when: APPLICATION_NAME != "edxapp" - name: migrate to original versions for edxapp shell: > {{ COMMAND_PREFIX }} {{ SUB_APPLICATION_NAME }} run_specific_migrations --migration '{{ item.app }}' '{{ item.migration }}' --output_file '{{ temp_output_dir.stdout }}/{{ database }}_{{ migration_plan }}' --database '{{ database }}' --settings '{{ EDX_PLATFORM_SETTINGS }}' become_user: "{{ APPLICATION_USER }}" with_items: "{{ initial_states }}" when: APPLICATION_NAME == "edxapp" - name: generate post rollback migration state shell: > {{ COMMAND_PREFIX }} show_unapplied_migrations --output_file '{{ temp_output_dir.stdout }}/{{ migration_result }}' become_user: "{{ APPLICATION_USER }}" when: APPLICATION_NAME != "edxapp" - name: generate post migration state for edxapp shell: > {{ COMMAND_PREFIX }} {{ SUB_APPLICATION_NAME }} show_unapplied_migrations --database '{{ database }}' --output_file '{{ temp_output_dir.stdout }}/{{ database }}_{{ migration_result }}' --settings '{{ EDX_PLATFORM_SETTINGS }}' become_user: "{{ APPLICATION_USER }}" when: APPLICATION_NAME == "edxapp" - name: List all migration files action: "command ls -1 {{ temp_output_dir.stdout }}" register: migration_files - name: Transfer artifacts to the proper place. fetch: src: "{{ temp_output_dir.stdout }}/{{ item }}" dest: "{{ ARTIFACT_PATH }}/" flat: True fail_on_missing: True mode: 0700 with_items: - "{{ migration_files.stdout_lines }}" - name: Send Hipchat notification cleanup has finished hipchat: api: "{{ HIPCHAT_URL }}" token: "{{ HIPCHAT_TOKEN }}" room: "{{ HIPCHAT_ROOM }}" msg: "Migrations have completed." ignore_errors: yes when: HIPCHAT_TOKEN is defined