From eb86584b9255c518e19307056cb24ce246e45c23 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Mon, 19 Jan 2026 13:05:49 -0500 Subject: [PATCH 1/3] deb822_repository: add backup option * Allow user to backup repo files Fixes: #86428 Signed-off-by: Abhijeet Kasurde --- changelogs/fragments/deb822_backup.yml | 3 ++ lib/ansible/modules/deb822_repository.py | 37 +++++++++++++--- .../targets/deb822_repository/tasks/main.yml | 2 + .../deb822_repository/tasks/test_backup.yml | 43 +++++++++++++++++++ 4 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/deb822_backup.yml create mode 100644 test/integration/targets/deb822_repository/tasks/test_backup.yml 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 7714330e811..891cc1be9e4 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: changed and if backup=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'] @@ -633,19 +651,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 and 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 1165ead9d0d..7282566c146 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: 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..d181b06f247 --- /dev/null +++ b/test/integration/targets/deb822_repository/tasks/test_backup.yml @@ -0,0 +1,43 @@ +- name: remove ansible-test repo + deb822_repository: + name: ansible-test-backup + state: absent + register: ansible_test_repo_remove + +- name: Create deb822 repo + deb822_repository: + name: ansible-test-backup + uris: http://us.archive.ubuntu.com/ubuntu + suites: + - focal + components: + - main + backup: true + register: deb822_create_backup_1 + +- 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_2.changed + - deb822_create_backup_stats.stat.exists + - deb822_create_backup_stats.stat.size > 0 + - deb822_create_backup_stats.stat.mode == '0644' From 09a199bf0b01c657d7e43a0d8950820c4cc018f1 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Tue, 20 Jan 2026 17:09:08 -0500 Subject: [PATCH 2/3] Review requests I Signed-off-by: Abhijeet Kasurde --- lib/ansible/modules/deb822_repository.py | 4 +- .../deb822_repository/tasks/test_backup.yml | 82 ++++++++++--------- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/lib/ansible/modules/deb822_repository.py b/lib/ansible/modules/deb822_repository.py index 891cc1be9e4..444add511a8 100644 --- a/lib/ansible/modules/deb822_repository.py +++ b/lib/ansible/modules/deb822_repository.py @@ -261,7 +261,7 @@ key_filename: backup_file: description: Path to the backup file - returned: changed and if backup=true + returned: when changed and backup is true type: str sample: /path/to/file.txt.2015-02-12@22:09~ """ @@ -667,7 +667,7 @@ def main(): 'dest': sources_filename, 'key_filename': signed_by_filename, } - if backup and backup_file is not None: + if backup_file is not None: return_data['backup_file'] = backup_file module.exit_json(**return_data) diff --git a/test/integration/targets/deb822_repository/tasks/test_backup.yml b/test/integration/targets/deb822_repository/tasks/test_backup.yml index d181b06f247..91b7cccae39 100644 --- a/test/integration/targets/deb822_repository/tasks/test_backup.yml +++ b/test/integration/targets/deb822_repository/tasks/test_backup.yml @@ -1,43 +1,45 @@ -- name: remove ansible-test repo - deb822_repository: - name: ansible-test-backup - state: absent - register: ansible_test_repo_remove +# 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: Create deb822 repo - deb822_repository: - name: ansible-test-backup - uris: http://us.archive.ubuntu.com/ubuntu - suites: - - focal - components: - - main - backup: true - register: deb822_create_backup_1 + - 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: 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: 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_2.changed - - deb822_create_backup_stats.stat.exists - - deb822_create_backup_stats.stat.size > 0 - - deb822_create_backup_stats.stat.mode == '0644' + - 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' + always: + - name: remove ansible-test repo + deb822_repository: + name: ansible-test-backup + state: absent + register: ansible_test_repo_remove From 4fb618e89c9405ea817fe6bfcab00a99dbb3dadd Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Thu, 22 Jan 2026 15:34:07 -0500 Subject: [PATCH 3/3] Review requests II Signed-off-by: Abhijeet Kasurde --- .../targets/deb822_repository/tasks/test_backup.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/integration/targets/deb822_repository/tasks/test_backup.yml b/test/integration/targets/deb822_repository/tasks/test_backup.yml index 91b7cccae39..d7c536832d7 100644 --- a/test/integration/targets/deb822_repository/tasks/test_backup.yml +++ b/test/integration/targets/deb822_repository/tasks/test_backup.yml @@ -10,6 +10,11 @@ - 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 @@ -37,6 +42,8 @@ - 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: