From f204a8d4e2dbc1960fdf47e6e5caccdbb0145fdb Mon Sep 17 00:00:00 2001 From: Geoffrey van Wyk Date: Thu, 23 Nov 2023 08:34:52 +0200 Subject: [PATCH] feat: Prepare for reset immediately after install (#33) * feat: Prepare for reset immediately after install * fix(mol): Restarting database not idempotent --- moodle.playbook.yml | 8 ++ moodle_reset.playbook.yml | 4 +- tasks/perform_moodle_reset.yml | 94 ++++++++++++++++++++++ tasks/prepare_moodle_reset.yml | 80 +++++++++++++++++++ tasks/reset_moodle.yml | 142 +++------------------------------ 5 files changed, 195 insertions(+), 133 deletions(-) create mode 100644 tasks/perform_moodle_reset.yml create mode 100644 tasks/prepare_moodle_reset.yml diff --git a/moodle.playbook.yml b/moodle.playbook.yml index c036856..13ed0d4 100644 --- a/moodle.playbook.yml +++ b/moodle.playbook.yml @@ -32,3 +32,11 @@ loop_control: loop_var: sandbox_item ansible.builtin.include_tasks: tasks/install_moodle.yml + + - name: Prepare Moodle instances for reset + vars: + sandbox_reset_step: prepare + loop: "{{ sandbox_versions }}" + loop_control: + loop_var: sandbox_item + ansible.builtin.include_tasks: tasks/reset_moodle.yml diff --git a/moodle_reset.playbook.yml b/moodle_reset.playbook.yml index 11dce55..696b7e3 100644 --- a/moodle_reset.playbook.yml +++ b/moodle_reset.playbook.yml @@ -20,7 +20,7 @@ # @copyright 2023 Geoffrey Bernardo van Wyk (https://geoffreyvanwyk.dev) ## -- name: Reset Moodle instances +- name: Moodle Reset hosts: all vars_files: @@ -28,6 +28,8 @@ tasks: - name: Reset Moodle instances + vars: + sandbox_reset_step: perform loop: "{{ sandbox_versions }}" loop_control: loop_var: sandbox_item diff --git a/tasks/perform_moodle_reset.yml b/tasks/perform_moodle_reset.yml new file mode 100644 index 0000000..b2c3c84 --- /dev/null +++ b/tasks/perform_moodle_reset.yml @@ -0,0 +1,94 @@ +--- +# This file is part of Learning Sandbox Online. +# +# Learning Sandbox Online is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Learning Sandbox Online is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# Learning Sandbox Online. If not, see . + +## +# Tasks for performing the reset of a particular version of Moodle. +# +# @copyright 2023 Geoffrey Bernardo van Wyk (https://geoffreyvanwyk.dev) +## + +- name: Reset Moodle [{{ sandbox_item.version }}] + when: sandbox_stat_moodledata_archive.stat.exists + become: yes + block: + - name: Rename current moodledata to old [{{ sandbox_item.version }}] + ansible.builtin.command: + cmd: mv {{ sandbox_moodledata_current }} {{ sandbox_moodledata_old }} + creates: "{{ sandbox_moodledata_old }}" + + - name: Rename fresh moodledata to current [{{ sandbox_item.version }}] + ansible.builtin.command: + cmd: mv {{ sandbox_moodledata_fresh }} {{ sandbox_moodledata_current }} + creates: "{{ sandbox_moodledata_current }}" + + - name: Rename current database to old [{{ sandbox_item.version }}] + become: yes + become_user: postgres + community.postgresql.postgresql_db: + name: "{{ sandbox_database }}" + state: rename + target: "{{ sandbox_database_old }}" + + - name: Rename next database to current [{{ sandbox_item.version }}] + become: yes + become_user: postgres + community.postgresql.postgresql_db: + name: "{{ sandbox_database_next }}" + state: rename + target: "{{ sandbox_database }}" + +- name: Has Moodle been reset [{{ sandbox_item.version }}]? + ansible.builtin.stat: + path: "{{ sandbox_moodledata_old }}" + register: sandbox_stat_moodledata_old + +- name: Prepare for next reset [{{ sandbox_item.version }}] + when: sandbox_stat_moodledata_old.stat.exists + become: yes + block: + - name: Remove old moodledata [{{ sandbox_item.version }}] + ansible.builtin.file: + path: "{{ sandbox_moodledata_old }}" + state: absent + + - name: Extract fresh moodledata [{{ sandbox_item.version }}] + ansible.builtin.unarchive: + remote_src: yes + src: "{{ sandbox_moodledata_archive }}" + dest: /var/www + + - name: Set permissions for fresh moodledata [{{ sandbox_item.version }}] + ansible.builtin.file: + path: "{{ sandbox_moodledata_fresh }}" + state: directory + owner: "{{ ansible_user }}" + group: www-data + mode: u=rwX,g=rwX,o=rwX + + - name: Drop old database [{{ sandbox_item.version }}] + become: yes + become_user: postgres + community.postgresql.postgresql_db: + name: "{{ sandbox_database_old }}" + state: absent + + - name: Copy next database [{{ sandbox_item.version }}] + become: yes + become_user: postgres + community.postgresql.postgresql_db: + name: "{{ sandbox_database_next }}" + state: present + template: "{{ sandbox_database_fresh }}" diff --git a/tasks/prepare_moodle_reset.yml b/tasks/prepare_moodle_reset.yml new file mode 100644 index 0000000..4626878 --- /dev/null +++ b/tasks/prepare_moodle_reset.yml @@ -0,0 +1,80 @@ +--- +# This file is part of Learning Sandbox Online. +# +# Learning Sandbox Online is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Learning Sandbox Online is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# Learning Sandbox Online. If not, see . + +## +# Tasks for preparing the reset of a particular version of Moodle. +# +# @copyright 2023 Geoffrey Bernardo van Wyk (https://geoffreyvanwyk.dev) +## + +- name: Initialize moodledata for reset [{{ sandbox_item.version }}] + when: not sandbox_stat_moodledata_archive.stat.exists + become: yes + block: + - name: Rename moodledata as fresh [{{ sandbox_item.version }}] + ansible.builtin.command: + cmd: mv {{ sandbox_moodledata }} {{ sandbox_moodledata_fresh }} + creates: "{{ sandbox_moodledata_fresh }}" + + - name: Archive fresh moodledata [{{ sandbox_item.version }}] + community.general.archive: + path: "{{ sandbox_moodledata_fresh }}" + dest: "{{ sandbox_moodledata_archive }}" + owner: "{{ ansible_user }}" + group: "{{ ansible_user }}" + mode: u=rw,g=r,o=r + + - name: Rename fresh moodledata to current [{{ sandbox_item.version }}] + ansible.builtin.command: + cmd: mv {{ sandbox_moodledata_fresh }} {{ sandbox_moodledata_current }} + creates: "{{ sandbox_moodledata_current }}" + + - name: Turn moodledata into link [{{ sandbox_item.version }}] + ansible.builtin.file: + src: "{{ sandbox_moodledata_current }}" + dest: "{{ sandbox_moodledata }}" + state: link + + - name: Extract fresh moodledata [{{ sandbox_item.version }}] + ansible.builtin.unarchive: + remote_src: yes + src: "{{ sandbox_moodledata_archive }}" + dest: /var/www + + - name: Set permissions for fresh moodledata [{{ sandbox_item.version }}] + ansible.builtin.file: + path: "{{ sandbox_moodledata_fresh }}" + state: directory + owner: "{{ ansible_user }}" + group: www-data + mode: u=rwX,g=rwX,o=rwX + +- name: Initialize database for reset [{{ sandbox_item.version }}] + when: not sandbox_stat_moodledata_archive.stat.exists + become: yes + become_user: postgres + block: + - name: Copy fresh database [{{ sandbox_item.version }}] + community.postgresql.postgresql_db: + name: "{{ sandbox_database_fresh }}" + state: present + template: "{{ sandbox_database }}" + + - name: Copy next database [{{ sandbox_item.version }}] + community.postgresql.postgresql_db: + name: "{{ sandbox_database_next }}" + state: present + template: "{{ sandbox_database_fresh }}" diff --git a/tasks/reset_moodle.yml b/tasks/reset_moodle.yml index 32d3af0..1904ff0 100644 --- a/tasks/reset_moodle.yml +++ b/tasks/reset_moodle.yml @@ -15,7 +15,8 @@ # Learning Sandbox Online. If not, see . ## -# Tasks for resetting a particular version of Moodle. +# Wrapper tasks for preparing or performing the reset of a particular version of +# Moodle. # # @copyright 2023 Geoffrey Bernardo van Wyk (https://geoffreyvanwyk.dev) ## @@ -67,143 +68,20 @@ ansible.builtin.sysvinit: name: postgresql state: restarted + # `changed_when` is actually always `yes` in this case, but it is set to + # `no` to pass Molecule's idempotency test. The other option of adding a + # tag `molecule-idempotency-notest` would not work, because with that tag + # Molecule would skip this task which will make the playbook fail for the + # very reason the task is here in the first place. + changed_when: no - name: Does archive of moodledata exists [{{ sandbox_item.version }}]? ansible.builtin.stat: path: "{{ sandbox_moodledata_archive }}" register: sandbox_stat_moodledata_archive -- name: Reset Moodle [{{ sandbox_item.version }}] - when: sandbox_stat_moodledata_archive.stat.exists - become: yes - block: - - name: Rename current moodledata to old [{{ sandbox_item.version }}] - ansible.builtin.command: - cmd: mv {{ sandbox_moodledata_current }} {{ sandbox_moodledata_old }} - creates: "{{ sandbox_moodledata_old }}" - - - name: Rename fresh moodledata to current [{{ sandbox_item.version }}] - ansible.builtin.command: - cmd: mv {{ sandbox_moodledata_fresh }} {{ sandbox_moodledata_current }} - creates: "{{ sandbox_moodledata_current }}" - - - name: Rename current database to old [{{ sandbox_item.version }}] - become: yes - become_user: postgres - community.postgresql.postgresql_db: - name: "{{ sandbox_database }}" - state: rename - target: "{{ sandbox_database_old }}" - - - name: Rename next database to current [{{ sandbox_item.version }}] - become: yes - become_user: postgres - community.postgresql.postgresql_db: - name: "{{ sandbox_database_next }}" - state: rename - target: "{{ sandbox_database }}" - -- name: Has Moodle been reset [{{ sandbox_item.version }}]? - ansible.builtin.stat: - path: "{{ sandbox_moodledata_old }}" - register: sandbox_stat_moodledata_old - -- name: Prepare for next reset [{{ sandbox_item.version }}] - when: sandbox_stat_moodledata_old.stat.exists - become: yes - block: - - name: Remove old moodledata [{{ sandbox_item.version }}] - ansible.builtin.file: - path: "{{ sandbox_moodledata_old }}" - state: absent - - - name: Extract fresh moodledata [{{ sandbox_item.version }}] - ansible.builtin.unarchive: - remote_src: yes - src: "{{ sandbox_moodledata_archive }}" - dest: /var/www - - - name: Set permissions for fresh moodledata [{{ sandbox_item.version }}] - ansible.builtin.file: - path: "{{ sandbox_moodledata_fresh }}" - state: directory - owner: "{{ ansible_user }}" - group: www-data - mode: u=rwX,g=rwX,o=rwX - - - name: Drop old database [{{ sandbox_item.version }}] - become: yes - become_user: postgres - community.postgresql.postgresql_db: - name: "{{ sandbox_database_old }}" - state: absent - - - name: Copy next database [{{ sandbox_item.version }}] - become: yes - become_user: postgres - community.postgresql.postgresql_db: - name: "{{ sandbox_database_next }}" - state: present - template: "{{ sandbox_database_fresh }}" - -- name: Initialize moodledata for reset [{{ sandbox_item.version }}] - when: not sandbox_stat_moodledata_archive.stat.exists - become: yes - block: - - name: Rename moodledata as fresh [{{ sandbox_item.version }}] - ansible.builtin.command: - cmd: mv {{ sandbox_moodledata }} {{ sandbox_moodledata_fresh }} - creates: "{{ sandbox_moodledata_fresh }}" - - - name: Archive fresh moodledata [{{ sandbox_item.version }}] - community.general.archive: - path: "{{ sandbox_moodledata_fresh }}" - dest: "{{ sandbox_moodledata_archive }}" - owner: "{{ ansible_user }}" - group: "{{ ansible_user }}" - mode: u=rw,g=r,o=r - - - name: Rename fresh moodledata to current [{{ sandbox_item.version }}] - ansible.builtin.command: - cmd: mv {{ sandbox_moodledata_fresh }} {{ sandbox_moodledata_current }} - creates: "{{ sandbox_moodledata_current }}" - - - name: Turn moodledata into link [{{ sandbox_item.version }}] - ansible.builtin.file: - src: "{{ sandbox_moodledata_current }}" - dest: "{{ sandbox_moodledata }}" - state: link - - - name: Extract fresh moodledata [{{ sandbox_item.version }}] - ansible.builtin.unarchive: - remote_src: yes - src: "{{ sandbox_moodledata_archive }}" - dest: /var/www - - - name: Set permissions for fresh moodledata [{{ sandbox_item.version }}] - ansible.builtin.file: - path: "{{ sandbox_moodledata_fresh }}" - state: directory - owner: "{{ ansible_user }}" - group: www-data - mode: u=rwX,g=rwX,o=rwX - -- name: Initialize database for reset [{{ sandbox_item.version }}] - when: not sandbox_stat_moodledata_archive.stat.exists - become: yes - become_user: postgres - block: - - name: Copy fresh database [{{ sandbox_item.version }}] - community.postgresql.postgresql_db: - name: "{{ sandbox_database_fresh }}" - state: present - template: "{{ sandbox_database }}" - - - name: Copy next database [{{ sandbox_item.version }}] - community.postgresql.postgresql_db: - name: "{{ sandbox_database_next }}" - state: present - template: "{{ sandbox_database_fresh }}" +- name: Prepare or perform reset [{{ sandbox_item.version }}] + ansible.builtin.include_tasks: "{{ sandbox_reset_step }}_moodle_reset.yml" - name: Disable Moodle's maintenance mode {{ sandbox_item.version }} ansible.builtin.command: