From 0d00430908a2ccc5a9111a6b9822b6f4a844463e Mon Sep 17 00:00:00 2001 From: Geoffrey van Wyk Date: Tue, 21 Nov 2023 11:49:46 +0200 Subject: [PATCH 1/5] chore: Prepare moodledata for reset --- tasks/install_moodle.yml | 56 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tasks/install_moodle.yml b/tasks/install_moodle.yml index 3f5d811..79e73d2 100644 --- a/tasks/install_moodle.yml +++ b/tasks/install_moodle.yml @@ -33,3 +33,59 @@ moodle_cfg_disableupdateautodeploy: true moodle_cfg_noemailever: true moodle_cfg_preventexecpath: true + +- name: Set instance identifier for Moodle {{ sandbox_item.version }} + ansible.builtin.set_fact: + sandbox_moodle_instance: >- + {{ sandbox_domain }}-moodle-{{ sandbox_item.version }} + +- name: Does archive of moodledata exists for Moodle {{ sandbox_item.version }}? + ansible.builtin.stat: + path: /var/www/moodledata-fresh-{{ sandbox_moodle_instance }}.tar.gz + register: moodledata_archive + +- name: Prepare for reset of Moodle {{ sandbox_item.version }} + when: not moodledata_archive.stat.exists + become: yes + block: + - name: Rename moodledata as fresh {{ sandbox_item.version }} + ansible.builtin.command: + cmd: > + mv /var/www/moodledata-{{ sandbox_moodle_instance }} + /var/www/moodledata-fresh-{{ sandbox_moodle_instance }} + creates: /var/www/moodledata-fresh-{{ sandbox_moodle_instance }} + + - name: Archive fresh moodledata {{ sandbox_item.version }} + community.general.archive: + path: /var/www/moodledata-fresh-{{ sandbox_moodle_instance }} + dest: /var/www/moodledata-fresh-{{ sandbox_moodle_instance }}.tar.gz + owner: "{{ ansible_user }}" + group: "{{ ansible_user }}" + mode: u=rw,g=r,o=r + + - name: Rename moodledata as current {{ sandbox_item.version }} + ansible.builtin.command: + cmd: > + mv /var/www/moodledata-fresh-{{ sandbox_moodle_instance }} + /var/www/moodledata-current-{{ sandbox_moodle_instance }} + creates: /var/www/moodledata-current-{{ sandbox_moodle_instance }} + + - name: Turn moodledata into link {{ sandbox_item.version }} + ansible.builtin.file: + src: /var/www/moodledata-current-{{ sandbox_moodle_instance }} + dest: /var/www/moodledata-{{ sandbox_moodle_instance }} + state: link + + - name: Extract fresh moodledata {{ sandbox_item.version }} + ansible.builtin.unarchive: + remote_src: yes + src: /var/www/moodledata-fresh-{{ sandbox_moodle_instance }}.tar.gz + dest: /var/www + + - name: Set permissions for fresh moodledata {{ sandbox_item.version }} + ansible.builtin.file: + path: /var/www/moodledata-fresh-{{ sandbox_moodle_instance }} + state: directory + owner: "{{ ansible_user }}" + group: www-data + mode: u=rwX,g=rwX,o=rwX From b4d8a4f909b5fab1f4b3520e3b4bdb16f85fdf94 Mon Sep 17 00:00:00 2001 From: Geoffrey van Wyk Date: Tue, 21 Nov 2023 14:00:17 +0200 Subject: [PATCH 2/5] chore: Prepare database copy for reset --- tasks/install_moodle.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tasks/install_moodle.yml b/tasks/install_moodle.yml index 79e73d2..ed84fd5 100644 --- a/tasks/install_moodle.yml +++ b/tasks/install_moodle.yml @@ -44,7 +44,7 @@ path: /var/www/moodledata-fresh-{{ sandbox_moodle_instance }}.tar.gz register: moodledata_archive -- name: Prepare for reset of Moodle {{ sandbox_item.version }} +- name: Prepare for reset of moodledata {{ sandbox_item.version }} when: not moodledata_archive.stat.exists become: yes block: @@ -89,3 +89,19 @@ owner: "{{ ansible_user }}" group: www-data mode: u=rwX,g=rwX,o=rwX + +- name: Prepare for reset of database {{ sandbox_item.version }} + become: yes + become_user: postgres + block: + - name: Copy fresh database {{ sandbox_item.version }} + community.postgresql.postgresql_db: + name: moodle-{{ sandbox_item.version | replace(".", "") }}-fresh + state: present + template: moodle-{{ sandbox_item.version | replace(".", "") }} + + - name: Copy next database {{ sandbox_item.version }} + community.postgresql.postgresql_db: + name: moodle-{{ sandbox_item.version | replace(".", "") }}-next + state: present + template: moodle-{{ sandbox_item.version | replace(".", "") }} From 1e04ffa197f07e92062cc1a33c3db6fce231ef64 Mon Sep 17 00:00:00 2001 From: Geoffrey van Wyk Date: Wed, 22 Nov 2023 03:16:22 +0200 Subject: [PATCH 3/5] chore: Create play for resetting Moodles --- moodle_reset.playbook.yml | 34 ++++++++++++++ tasks/reset_moodle.yml | 94 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 moodle_reset.playbook.yml create mode 100644 tasks/reset_moodle.yml diff --git a/moodle_reset.playbook.yml b/moodle_reset.playbook.yml new file mode 100644 index 0000000..11dce55 --- /dev/null +++ b/moodle_reset.playbook.yml @@ -0,0 +1,34 @@ +--- +# 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 . + +## +# Playbook for resetting the Moodle instances. +# +# @copyright 2023 Geoffrey Bernardo van Wyk (https://geoffreyvanwyk.dev) +## + +- name: Reset Moodle instances + hosts: all + + vars_files: + - defaults/main.yml + + tasks: + - name: Reset Moodle instances + loop: "{{ sandbox_versions }}" + loop_control: + loop_var: sandbox_item + ansible.builtin.include_tasks: tasks/reset_moodle.yml diff --git a/tasks/reset_moodle.yml b/tasks/reset_moodle.yml new file mode 100644 index 0000000..8fb3018 --- /dev/null +++ b/tasks/reset_moodle.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 resetting a particular version of Moodle. +# +# @copyright 2023 Geoffrey Bernardo van Wyk (https://geoffreyvanwyk.dev) +## + +- name: Set instance identifier for Moodle {{ sandbox_item.version }} + ansible.builtin.set_fact: + sandbox_moodle_instance: >- + {{ sandbox_domain }}-moodle-{{ sandbox_item.version }} + +- name: Rename current moodledata to old {{ sandbox_item.version }} + become: yes + ansible.builtin.command: + cmd: > + mv /var/www/moodledata-current-{{ sandbox_moodle_instance }} + /var/www/moodledata-old-{{ sandbox_moodle_instance }} + creates: /var/www/moodledata-old-{{ sandbox_moodle_instance }} + +- name: Rename fresh moodledata to current {{ sandbox_item.version }} + become: yes + ansible.builtin.command: + cmd: > + mv /var/www/moodledata-fresh-{{ sandbox_moodle_instance }} + /var/www/moodledata-current-{{ sandbox_moodle_instance }} + creates: /var/www/moodledata-current-{{ sandbox_moodle_instance }} + +- name: Rename "current" database to old {{ sandbox_item.version }} + become: yes + become_user: postgres + community.postgresql.postgresql_db: + name: moodle-{{ sandbox_item.version | replace(".", "") }} + state: rename + target: moodle-{{ sandbox_item.version | replace(".", "") }}-old + +- name: Rename next database to "current" {{ sandbox_item.version }} + become: yes + become_user: postgres + community.postgresql.postgresql_db: + name: moodle-{{ sandbox_item.version | replace(".", "") }}-next + state: rename + target: moodle-{{ sandbox_item.version | replace(".", "") }} + +- name: Remove old moodledata {{ sandbox_item.version }} + become: yes + ansible.builtin.file: + path: /var/www/moodledata-old-{{ sandbox_moodle_instance }} + state: absent + +- name: Drop old database {{ sandbox_item.version }} + become: yes + become_user: postgres + community.postgresql.postgresql_db: + name: moodle-{{ sandbox_item.version | replace(".", "") }}-old + state: absent + +- name: Extract fresh moodledata {{ sandbox_item.version }} + become: yes + ansible.builtin.unarchive: + remote_src: yes + src: /var/www/moodledata-fresh-{{ sandbox_moodle_instance }}.tar.gz + dest: /var/www + +- name: Set permissions for fresh moodledata {{ sandbox_item.version }} + ansible.builtin.file: + path: /var/www/moodledata-fresh-{{ sandbox_moodle_instance }} + state: directory + owner: "{{ ansible_user }}" + group: www-data + mode: u=rwX,g=rwX,o=rwX + +- name: Copy next database {{ sandbox_item.version }} + become: yes + become_user: postgres + community.postgresql.postgresql_db: + name: moodle-{{ sandbox_item.version | replace(".", "") }}-next + state: present + template: moodle-{{ sandbox_item.version | replace(".", "") }}-fresh From 4f81e04dd72df96484d22f82b75d519f9c91d6b8 Mon Sep 17 00:00:00 2001 From: Geoffrey van Wyk Date: Wed, 22 Nov 2023 05:37:07 +0200 Subject: [PATCH 4/5] test: Reset with Molecule --- molecule/default/converge.yml | 2 +- molecule/default/molecule.yml | 2 ++ molecule/default/side_effect.yml | 15 +++++++++++++++ tasks/reset_moodle.yml | 1 + 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 molecule/default/side_effect.yml diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index f81b684..d517e8c 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -1,5 +1,5 @@ --- -- name: Default Scenario +- name: Converge hosts: all tasks: - name: Override default variables with facts diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index dca037b..1be2ea7 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -16,5 +16,7 @@ provisioner: host_vars: learningsandboxonline_molecule_${MOLECULE_DISTRO:-ubuntu2204}: ansible_user: ubuntu + playbooks: + side_effect: side_effect.yml verifier: name: ansible diff --git a/molecule/default/side_effect.yml b/molecule/default/side_effect.yml new file mode 100644 index 0000000..153b575 --- /dev/null +++ b/molecule/default/side_effect.yml @@ -0,0 +1,15 @@ +--- +- name: Side-Effect + hosts: all + tasks: + - name: Override default variables with facts + ansible.builtin.set_fact: + sandbox_domain: learningsandbox.test + sandbox_domain_aliases: [] + sandbox_environment: development + sandbox_versions: + - branch: MOODLE_39_STABLE + version: 3.9 + +- name: Import reset playbook + ansible.builtin.import_playbook: ../../moodle_reset.playbook.yml diff --git a/tasks/reset_moodle.yml b/tasks/reset_moodle.yml index 8fb3018..5fa7ab9 100644 --- a/tasks/reset_moodle.yml +++ b/tasks/reset_moodle.yml @@ -78,6 +78,7 @@ dest: /var/www - name: Set permissions for fresh moodledata {{ sandbox_item.version }} + become: yes ansible.builtin.file: path: /var/www/moodledata-fresh-{{ sandbox_moodle_instance }} state: directory From 735736f67e61284f6bc1134974ac1673b5444115 Mon Sep 17 00:00:00 2001 From: Geoffrey van Wyk Date: Wed, 22 Nov 2023 07:07:15 +0200 Subject: [PATCH 5/5] chore(cd): GHA workflow for resetting Moodles Where GHA stands for GitHub Actions. --- .github/workflows/reset.yml | 63 +++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 .github/workflows/reset.yml diff --git a/.github/workflows/reset.yml b/.github/workflows/reset.yml new file mode 100644 index 0000000..3ba8b02 --- /dev/null +++ b/.github/workflows/reset.yml @@ -0,0 +1,63 @@ +--- +# 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 . + +## +# GitHub Actions workflow for resetting the Moodle instances on the public +# website every 30 minutes past the hour. +# +# @copyright 2023 Geoffrey Bernardo van Wyk (https://geoffreyvanwyk.dev) +# @see GitHub Actions {@link https://docs.github.com/en/actions} +## + +name: Reset +on: + schedule: + - cron: '30 * * * *' + +jobs: + ansible-playbook: + name: Run playbook + runs-on: ubuntu-22.04 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: "3.x" + + - name: Install Ansible. + run: pip3 install ansible + + - name: Install playbooks dependencies + run: ansible-galaxy role install --role-file requirements.yml + + - name: Install SSH key. + uses: shimataro/ssh-key-action@v2 + with: + key: ${{ secrets.SSH_PRIVATE_KEY }} + known_hosts: ${{ secrets.KNOWN_HOSTS }} + + - name: Run plays. + run: > + ansible-playbook moodle_reset.playbook.yml + --inventory ${{ secrets.ANSIBLE_INVENTORY }}, + --user ${{ secrets.ANSIBLE_USER }} + env: + PY_COLORS: "1" + ANSIBLE_FORCE_COLOR: "1"