From 02c21742a3a5f12180afe8fae3d45a023f40f715 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 12 Jun 2025 12:13:15 -0400 Subject: [PATCH] Assemble add check mode (#85094) Co-authored-by: Abhijeet Kasurde --- changelogs/fragments/assemble_check_mode.yml | 3 ++ lib/ansible/module_utils/basic.py | 9 ++--- lib/ansible/modules/assemble.py | 8 +++-- lib/ansible/plugins/action/assemble.py | 3 +- .../targets/assemble/tasks/main.yml | 36 +++++++++++++++++-- 5 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 changelogs/fragments/assemble_check_mode.yml diff --git a/changelogs/fragments/assemble_check_mode.yml b/changelogs/fragments/assemble_check_mode.yml new file mode 100644 index 00000000000..b90dd7ecb8f --- /dev/null +++ b/changelogs/fragments/assemble_check_mode.yml @@ -0,0 +1,3 @@ +minor_changes: + - assemble action added check_mode support + - module_utils.basic.backup_local enforces check_mode now diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index cd8ee202200..9208a4c9134 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -1657,10 +1657,11 @@ class AnsibleModule(object): ext = time.strftime("%Y-%m-%d@%H:%M:%S~", time.localtime(time.time())) backupdest = '%s.%s.%s' % (fn, os.getpid(), ext) - try: - self.preserved_copy(fn, backupdest) - except (shutil.Error, OSError) as ex: - raise Exception(f'Could not make backup of {fn!r} to {backupdest!r}.') from ex + if not self.check_mode: + try: + self.preserved_copy(fn, backupdest) + except (shutil.Error, IOError) as ex: + raise Exception(f'Could not make backup of {fn!r} to {backupdest!r}.') from ex return backupdest diff --git a/lib/ansible/modules/assemble.py b/lib/ansible/modules/assemble.py index 11dd8ab6030..b1329496d96 100644 --- a/lib/ansible/modules/assemble.py +++ b/lib/ansible/modules/assemble.py @@ -80,7 +80,7 @@ attributes: bypass_host_loop: support: none check_mode: - support: none + support: full diff_mode: support: full platform: @@ -212,6 +212,7 @@ def main(): decrypt=dict(type='bool', default=True), ), add_file_common_args=True, + supports_check_mode=True, ) changed = False @@ -266,12 +267,13 @@ def main(): if backup and dest_hash is not None: result['backup_file'] = module.backup_local(dest) - module.atomic_move(path, dest, unsafe_writes=module.params['unsafe_writes']) + if not module.check_mode: + module.atomic_move(path, dest, unsafe_writes=module.params['unsafe_writes']) changed = True cleanup(module, path, result) - # handle file permissions + # handle file permissions (check mode aware) file_args = module.load_file_common_arguments(module.params) result['changed'] = module.set_fs_attributes_if_different(file_args, changed) diff --git a/lib/ansible/plugins/action/assemble.py b/lib/ansible/plugins/action/assemble.py index 344f8f00d8e..4d8bdc00df4 100644 --- a/lib/ansible/plugins/action/assemble.py +++ b/lib/ansible/plugins/action/assemble.py @@ -81,9 +81,10 @@ class ActionModule(ActionBase): def run(self, tmp=None, task_vars=None): - self._supports_check_mode = False + self._supports_check_mode = True super(ActionModule, self).run(tmp, task_vars) + del tmp # tmp no longer has any effect if task_vars is None: diff --git a/test/integration/targets/assemble/tasks/main.yml b/test/integration/targets/assemble/tasks/main.yml index add95f936d0..a0e90b63277 100644 --- a/test/integration/targets/assemble/tasks/main.yml +++ b/test/integration/targets/assemble/tasks/main.yml @@ -29,16 +29,46 @@ that: - "result.changed == true" -- name: test assemble with all fragments +- name: test assemble with all fragments, but only check! assemble: src="{{remote_tmp_dir}}/src" dest="{{remote_tmp_dir}}/assembled1" + check_mode: True register: result - name: assert the fragments were assembled assert: that: - - "result.state == 'file'" - "result.changed == True" - - "result.checksum == '74152e9224f774191bc0bedf460d35de86ad90e6'" + +- name: ensure file was not created + stat: + path: "{{remote_tmp_dir}}/assembled1" + register: check_it + +- name: it should not exist, yet + assert: + that: + - not check_it.stat.exists + +- name: test assemble with all fragments, really create now! + assemble: src="{{remote_tmp_dir}}/src" dest="{{remote_tmp_dir}}/assembled1" + register: result2 + +- name: assert the fragments were assembled + assert: + that: + - "result2.state == 'file'" + - "result2.changed == True" + - "result2.checksum == '74152e9224f774191bc0bedf460d35de86ad90e6'" + +- name: ensure file was created + stat: + path: "{{remote_tmp_dir}}/assembled1" + register: check_it2 + +- name: it should exist now + assert: + that: + - check_it2.stat.exists - name: test assemble with all fragments assemble: src="{{remote_tmp_dir}}/src" dest="{{remote_tmp_dir}}/assembled1"