diff --git a/docs/roles/_init.md b/docs/roles/_init.md index 2f3f43ee..867b8e59 100644 --- a/docs/roles/_init.md +++ b/docs/roles/_init.md @@ -16,8 +16,6 @@ deploy_user: deploy # if you are using ce-provision to deploy infrastructure thi _mysqldump_params: "--max-allowed-packet=128M --single-transaction --skip-opt -e --quick --skip-disable-keys --skip-add-locks -C -a --add-drop-table" # @TODO only used by Drupal 7, can be removed with Drupal 7 deployments bin_directory: "/home/{{ deploy_user }}/.bin" -# Number of dumps/db to look up for cleanup. -cleanup_history_depth: 50 install_php_cachetool: true # set to false if you don't need cachetool, e.g. for a nodejs app ce_deploy_version: 1.x ce_provision_version: 2.x # the version of ce-provision to grab files from when roles are shared diff --git a/roles/_init/README.md b/roles/_init/README.md index 2f3f43ee..867b8e59 100644 --- a/roles/_init/README.md +++ b/roles/_init/README.md @@ -16,8 +16,6 @@ deploy_user: deploy # if you are using ce-provision to deploy infrastructure thi _mysqldump_params: "--max-allowed-packet=128M --single-transaction --skip-opt -e --quick --skip-disable-keys --skip-add-locks -C -a --add-drop-table" # @TODO only used by Drupal 7, can be removed with Drupal 7 deployments bin_directory: "/home/{{ deploy_user }}/.bin" -# Number of dumps/db to look up for cleanup. -cleanup_history_depth: 50 install_php_cachetool: true # set to false if you don't need cachetool, e.g. for a nodejs app ce_deploy_version: 1.x ce_provision_version: 2.x # the version of ce-provision to grab files from when roles are shared diff --git a/roles/_init/defaults/main.yml b/roles/_init/defaults/main.yml index 24cc103f..d9e4fdf4 100644 --- a/roles/_init/defaults/main.yml +++ b/roles/_init/defaults/main.yml @@ -5,8 +5,6 @@ deploy_user: deploy # if you are using ce-provision to deploy infrastructure thi _mysqldump_params: "--max-allowed-packet=128M --single-transaction --skip-opt -e --quick --skip-disable-keys --skip-add-locks -C -a --add-drop-table" # @TODO only used by Drupal 7, can be removed with Drupal 7 deployments bin_directory: "/home/{{ deploy_user }}/.bin" -# Number of dumps/db to look up for cleanup. -cleanup_history_depth: 50 install_php_cachetool: true # set to false if you don't need cachetool, e.g. for a nodejs app ce_deploy_version: 1.x ce_provision_version: 2.x # the version of ce-provision to grab files from when roles are shared diff --git a/roles/_init/tasks/main.yml b/roles/_init/tasks/main.yml index 8c8e8c25..4437ab1c 100644 --- a/roles/_init/tasks/main.yml +++ b/roles/_init/tasks/main.yml @@ -131,6 +131,67 @@ path: "{{ build_base_path }}" state: directory +# Calculate the builds to cleanup once here, so we don't do it many times later. +- name: Calculate builds to cleanup. + when: deploy_operation == 'cleanup' + block: + - name: Initialise list variables for directory reading. + ansible.builtin.set_fact: + _build_directory_names: [] + _build_numbers: [] + _build_numbers_clean: [] + _build_numbers_to_delete: [] + + - name: Find all directories in this project deploy directory. + ansible.builtin.find: + paths: "{{ deploy_base_path }}" + recurse: false + file_type: directory + register: _build_directories_general + + - name: Find all directories in the build directory if SquashFS. + ansible.builtin.find: + paths: "{{ build_base_path }}" + recurse: false + file_type: directory + register: _build_directories_squashfs + when: + - deploy_code.mount_type is defined + - deploy_code.mount_type == "squashfs" + + - name: Copy build directories into consistently named variable. + ansible.builtin.set_fact: + _build_directories: "{{ _build_directories_general }}" + + - name: Replace build directories variable if this is a SquashFS build. + ansible.builtin.set_fact: + _build_directories: "{{ _build_directories_squashfs }}" + when: + - deploy_code.mount_type is defined + - deploy_code.mount_type == "squashfs" + + - name: Build a list of build numbers. + ansible.builtin.set_fact: + _build_numbers: "{{ _build_numbers + [item.path | regex_search('^(.*)_([0-9]*)$', '\\2')] }}" + with_items: "{{ _build_directories.files }}" + + - name: Convert the list of build numbers to integers. + ansible.builtin.set_fact: + _build_numbers_clean: "{{ _build_numbers_clean + [item | int] }}" + with_items: "{{ _build_numbers }}" + + - name: Order the list of build numbers. + ansible.builtin.set_fact: + _build_numbers_clean: "{{ _build_numbers_clean | sort }}" + + - name: Build a list of builds to delete. + ansible.builtin.set_fact: + _build_numbers_to_delete: "{{ _build_numbers_to_delete + [item] }}" + with_items: "{{ _build_numbers_clean }}" + when: _build_directory_index < (_build_directories.matched - deploy_code.keep) + loop_control: + index_var: _build_directory_index + - name: Set the previous deploy's path for later use where we need to manipulate the live site. ansible.builtin.set_fact: previous_deploy_path: "{{ previous_deploy_path | default('{{ deploy_path_prefix }}{{ previous_build_number }}') }}" diff --git a/roles/database_backup/database_backup-mysql/tasks/cleanup-dump.yml b/roles/database_backup/database_backup-mysql/tasks/cleanup-dump.yml index 734aad4d..35910475 100644 --- a/roles/database_backup/database_backup-mysql/tasks/cleanup-dump.yml +++ b/roles/database_backup/database_backup-mysql/tasks/cleanup-dump.yml @@ -1,8 +1,7 @@ --- -# We assume it's safe to only go back 50 build back. -- name: Delete mysql dumps. +- name: Delete MySQL dumps. ansible.builtin.file: path: "{{ mysql_backup.dumps_directory }}/{{ _mysql_host }}/{{ database.database }}-{{ item }}.sql.*" state: absent - with_sequence: start={{ [previous_build_number | int - cleanup_history_depth, 0] | max }} end={{ [previous_build_number | int - mysql_backup.keep, 0] | max }} + with_items: "{{ _build_numbers_to_delete }}" # set in _init role run_once: true diff --git a/roles/database_backup/database_backup-mysql/tasks/cleanup-rolling.yml b/roles/database_backup/database_backup-mysql/tasks/cleanup-rolling.yml index a94ccc2a..058ee80c 100644 --- a/roles/database_backup/database_backup-mysql/tasks/cleanup-rolling.yml +++ b/roles/database_backup/database_backup-mysql/tasks/cleanup-rolling.yml @@ -1,5 +1,5 @@ --- -- name: Delete mysql databases. +- name: Delete MySQL databases. community.mysql.mysql_db: name: "{{ database.database }}_{{ item }}" state: absent @@ -7,5 +7,5 @@ login_user: "{{ _mysql_user }}" login_password: "{{ _mysql_password }}" login_unix_socket: "{{ mysql_backup.mysql_unix_socket | default(omit) }}" - with_sequence: start={{ [previous_build_number | int - cleanup_history_depth, 0] | max }} end={{ [previous_build_number | int - mysql_backup.keep, 0] | max }} + with_items: "{{ _build_numbers_to_delete }}" # set in _init role run_once: true diff --git a/roles/database_backup/database_backup-mysql/tasks/cleanup.yml b/roles/database_backup/database_backup-mysql/tasks/cleanup.yml index 23654247..c999b937 100644 --- a/roles/database_backup/database_backup-mysql/tasks/cleanup.yml +++ b/roles/database_backup/database_backup-mysql/tasks/cleanup.yml @@ -16,7 +16,7 @@ - ansible.builtin.include_tasks: "cleanup-{{ mysql_backup.handling }}.yml" when: database.is_replica is not defined -- name: Delete mysql users. +- name: Delete MySQL users. community.mysql.mysql_user: name: "{{ database.user }}_{{ item }}" host_all: true @@ -24,7 +24,7 @@ login_host: "{{ _mysql_host }}" login_user: "{{ _mysql_user }}" login_password: "{{ _mysql_password }}" - with_sequence: start={{ [previous_build_number | int - cleanup_history_depth, 0] | max }} end={{ [previous_build_number | int - mysql_backup.keep, 0] | max }} + with_items: "{{ _build_numbers_to_delete }}" # set in _init role when: - mysql_backup.credentials_handling == 'rotate' - database.is_replica is not defined diff --git a/roles/deploy_code/tasks/cleanup.yml b/roles/deploy_code/tasks/cleanup.yml index 4a05a955..9f521dd4 100644 --- a/roles/deploy_code/tasks/cleanup.yml +++ b/roles/deploy_code/tasks/cleanup.yml @@ -1,8 +1,8 @@ --- - name: Ensure codebase is writable. ansible.builtin.shell: - cmd: "if [ -d {{ deploy_path_prefix }}{{ item }} ]; then chmod -R 777 {{ deploy_path_prefix }}{{ item }}; fi" - with_sequence: start={{ [previous_build_number | int - cleanup_history_depth, 0] | max }} end={{ [previous_build_number | int - deploy_code.keep, 0] | max }} + cmd: "if [ -d {{ item.path }} ]; then chmod -R 777 {{ item.path }}; fi" + with_items: "{{ _build_directories.files }}" # set in _init role become: true when: - "www_user != deploy_user" @@ -10,20 +10,30 @@ - name: Ensure permissions are set on deploy directory. ansible.builtin.shell: - cmd: "if [ -d {{ deploy_path_prefix }}{{ item }}/{{ deploy_code.perms_fix_path }} ]; then chmod 755 {{ deploy_path_prefix }}{{ item }}/{{ deploy_code.perms_fix_path }}; fi" - with_sequence: start={{ [previous_build_number | int - cleanup_history_depth, 0] | max }} end={{ [previous_build_number | int - deploy_code.keep, 0] | max }} + cmd: "if [ -d {{ item.path }} ]; then chmod 755 {{ item.path }}; fi" + with_items: "{{ _build_directories.files }}" # set in _init role when: - deploy_code.perms_fix_path is defined - deploy_code.perms_fix_path | length > 1 - deploy_code.mount_type != "squashfs" +- name: Initialise list variable for directory deleting. + ansible.builtin.set_fact: + _build_directories_to_delete: [] + - name: Delete codebases from deploy directory. - ansible.builtin.file: - name: "{{ deploy_path_prefix }}{{ item }}" - state: absent - with_sequence: start={{ [previous_build_number | int - cleanup_history_depth, 0] | max }} end={{ [previous_build_number | int - deploy_code.keep, 0] | max }} - when: - - deploy_code.mount_type != "squashfs" + when: deploy_code.mount_type != "squashfs" + block: + - name: Build a list of directories to delete. + ansible.builtin.set_fact: + _build_directories_to_delete: "{{ _build_directories_to_delete + [deploy_path_prefix + item|string] }}" + with_items: "{{ _build_numbers_to_delete }}" # set in _init role + + - name: Delete the directories. + ansible.builtin.file: + name: "{{ item }}" + state: absent + with_items: "{{ _build_directories_to_delete }}" - name: Create a tarball of the deployed codebases. ansible.builtin.command: @@ -55,20 +65,29 @@ # Beginning of the squashFS block. - name: Execute tasks for squashFS mount type. + when: + - deploy_code.mount_sync is defined + - deploy_code.mount_sync | length > 1 + - deploy_code.mount_type == "squashfs" block: - name: Ensure permissions are set on builds directory. ansible.builtin.shell: - cmd: "if [ -d {{ build_path_prefix }}{{ item }}/{{ deploy_code.perms_fix_path }} ]; then chmod 755 {{ build_path_prefix }}{{ item }}/{{ deploy_code.perms_fix_path }}; fi" - with_sequence: start={{ [previous_build_number | int - cleanup_history_depth, 0] | max }} end={{ [previous_build_number | int - deploy_code.keep, 0] | max }} + cmd: "if [ -d {{ item.path }} ]; then chmod 755 {{ item.path }}; fi" + with_items: "{{ _build_directories.files }}" # set in _init role when: - deploy_code.perms_fix_path is defined - deploy_code.perms_fix_path | length > 1 - - name: Delete codebases from builds directory. + - name: Build a list of directories to delete. + ansible.builtin.set_fact: + _build_directories_to_delete: "{{ _build_directories_to_delete + [build_path_prefix + item|string] }}" + with_items: "{{ _build_numbers_to_delete }}" # set in _init role + + - name: Delete the directories. ansible.builtin.file: - name: "{{ build_path_prefix }}{{ item }}" + name: "{{ item }}" state: absent - with_sequence: start={{ [previous_build_number | int - cleanup_history_depth, 0] | max }} end={{ [previous_build_number | int - deploy_code.keep, 0] | max }} + with_items: "{{ _build_directories_to_delete }}" - name: Create a SquashFS image of the deployed codebases. ansible.builtin.command: @@ -200,10 +219,6 @@ - _deploy_code_mount_check.rc == 0 - deploy_code.service_action == "stop" - deploy_code.services | length > 0 - when: - - deploy_code.mount_sync is defined - - deploy_code.mount_sync | length > 1 - - deploy_code.mount_type == "squashfs" # End of the squashFS block. - name: Trigger an infrastructure rebuild.