diff --git a/changelogs/fragments/deb822_backup.yml b/changelogs/fragments/deb822_backup.yml new file mode 100644 index 00000000000..e99376bceeb --- /dev/null +++ b/changelogs/fragments/deb822_backup.yml @@ -0,0 +1,3 @@ +--- +minor_changes: + - deb822_repository - add option to specify backup repo files (https://github.com/ansible/ansible/issues/86428). diff --git a/lib/ansible/modules/deb822_repository.py b/lib/ansible/modules/deb822_repository.py index c41cd6e6360..86425ff0231 100644 --- a/lib/ansible/modules/deb822_repository.py +++ b/lib/ansible/modules/deb822_repository.py @@ -169,6 +169,13 @@ options: - absent - present default: present + backup: + description: + - Create a backup file including the timestamp information so you can + get the original file back if you somehow clobbered it incorrectly. + type: bool + default: false + version_added: '2.21' requirements: - python3-debian / python-debian version_added: '2.15' @@ -251,6 +258,12 @@ key_filename: returned: always type: str sample: /etc/apt/keyrings/debian.gpg + +backup_file: + description: Path to the backup file + returned: when changed and backup is true + type: str + sample: /path/to/file.txt.2015-02-12@22:09~ """ import os @@ -503,6 +516,10 @@ def main(): ], 'default': 'present', }, + 'backup': { + 'type': 'bool', + 'default': False, + }, }, mutually_exclusive=[ ['exclude', 'include'] @@ -569,6 +586,7 @@ def main(): # popped non-deb822 args mode = params.pop('mode') state = params.pop('state') + backup = params.pop('backup') params.pop('install_python_debian') name = params['name'] @@ -638,19 +656,26 @@ def main(): src_chksum = module.sha256(tmpfile) dest_chksum = module.sha256(sources_filename) + backup_file = None if src_chksum != dest_chksum: if not check_mode: + if backup and os.path.exists(sources_filename): + backup_file = module.backup_local(sources_filename) module.atomic_move(tmpfile, sources_filename) changed |= True changed |= module.set_mode_if_different(sources_filename, mode, False) - module.exit_json( - repo=repo, - changed=changed, - dest=sources_filename, - key_filename=signed_by_filename, - ) + return_data = { + 'repo': repo, + 'changed': changed, + 'dest': sources_filename, + 'key_filename': signed_by_filename, + } + if backup_file is not None: + return_data['backup_file'] = backup_file + + module.exit_json(**return_data) if __name__ == '__main__': diff --git a/test/integration/targets/deb822_repository/tasks/main.yml b/test/integration/targets/deb822_repository/tasks/main.yml index b84f4bb2e23..594e9c764aa 100644 --- a/test/integration/targets/deb822_repository/tasks/main.yml +++ b/test/integration/targets/deb822_repository/tasks/main.yml @@ -185,6 +185,8 @@ - import_tasks: test.yml - import_tasks: name_handling.yml - import_tasks: install.yml + + - include_tasks: test_backup.yml always: - name: uninstall python3-debian apt: diff --git a/test/integration/targets/deb822_repository/tasks/test_backup.yml b/test/integration/targets/deb822_repository/tasks/test_backup.yml new file mode 100644 index 00000000000..d7c536832d7 --- /dev/null +++ b/test/integration/targets/deb822_repository/tasks/test_backup.yml @@ -0,0 +1,52 @@ +# test backup file is created when repo is updated +- block: + - name: Create deb822 repo + deb822_repository: + name: ansible-test-backup + uris: http://us.archive.ubuntu.com/ubuntu + suites: + - focal + components: + - main + register: deb822_create_backup_1 + + - name: Get Checksum of newly created repo file + stat: + path: "{{ deb822_create_backup_1.dest }}" + register: deb822_create_backup_1_stat + + - name: Update deb822 repo with backup + deb822_repository: + name: ansible-test-backup + uris: http://us.archive.ubuntu.com/ubuntu + suites: + - focal + - focal-updates + components: + - main + - restricted + backup: true + register: deb822_create_backup_2 + + - name: Check backup file + stat: + path: "{{ deb822_create_backup_2.backup_file }}" + register: deb822_create_backup_stats + + - name: Assert backup file exists + assert: + that: + - deb822_create_backup_1.changed + - deb822_create_backup_1.backup_file is not defined + - deb822_create_backup_2.changed + - deb822_create_backup_stats.stat.exists + - deb822_create_backup_stats.stat.size > 0 + - deb822_create_backup_stats.stat.mode == '0644' + - deb822_create_backup_1_stat.stat.checksum == deb822_create_backup_stats.stat.checksum + + always: + - name: remove ansible-test repo + deb822_repository: + name: ansible-test-backup + state: absent + register: ansible_test_repo_remove