diff --git a/changelogs/fragments/56353-file-extend-absent-diff-result.yml b/changelogs/fragments/56353-file-extend-absent-diff-result.yml new file mode 100644 index 00000000000..4cbc2b74537 --- /dev/null +++ b/changelogs/fragments/56353-file-extend-absent-diff-result.yml @@ -0,0 +1,2 @@ +minor_changes: + - file - Extend ``-diff`` to return list of files and folders that will be removed in case of ``state=absent`` (https://github.com/ansible/ansible/pull/56353) diff --git a/lib/ansible/modules/files/file.py b/lib/ansible/modules/files/file.py index 7794d4c2720..28134da148e 100644 --- a/lib/ansible/modules/files/file.py +++ b/lib/ansible/modules/files/file.py @@ -367,6 +367,21 @@ def initial_diff(path, state, prev_state): if prev_state != state: diff['before']['state'] = prev_state diff['after']['state'] = state + if state == 'absent': + walklist = { + 'directories': [], + 'files': [], + } + for base_path, sub_folders, files in os.walk(path): + for folder in sub_folders: + folderpath = os.path.join(base_path, folder) + walklist['directories'].append(folderpath) + + for filename in files: + filepath = os.path.join(base_path, filename) + walklist['files'].append(filepath) + + diff['before']['path_content'] = walklist return diff @@ -481,6 +496,8 @@ def ensure_absent(path): result = {} if prev_state != 'absent': + diff = initial_diff(path, 'absent', prev_state) + if not module.check_mode: if prev_state == 'directory': try: @@ -495,7 +512,6 @@ def ensure_absent(path): raise AnsibleModuleError(results={'msg': "unlinking failed: %s " % to_native(e), 'path': path}) - diff = initial_diff(path, 'absent', prev_state) result.update({'path': path, 'changed': True, 'diff': diff, 'state': 'absent'}) else: result.update({'path': path, 'changed': False, 'state': 'absent'}) diff --git a/test/integration/targets/file/tasks/main.yml b/test/integration/targets/file/tasks/main.yml index 2c473329d27..6c03f5a8ab6 100644 --- a/test/integration/targets/file/tasks/main.yml +++ b/test/integration/targets/file/tasks/main.yml @@ -243,7 +243,7 @@ when: selinux_installed.stdout != "" ignore_errors: true -- name: remote directory foobar +- name: remove directory foobar file: path={{output_dir}}/foobar state=absent - name: remove file foo.txt @@ -258,6 +258,24 @@ - name: copy directory structure over copy: src=foobar dest={{output_dir}} +- name: check what would be removed if folder state was absent and diff is enabled + file: + path: "{{ output_dir }}" + state: absent + check_mode: yes + diff: yes + register: folder_absent_result + +- name: assert that the absent check lists expected files and folders + assert: + that: + - folder_absent_result.diff.before.path_content is defined + - test_folder in folder_absent_result.diff.before.path_content.directories + - test_file in folder_absent_result.diff.before.path_content.files + vars: + test_folder: "{{ folder_absent_result.path }}/foobar" + test_file: "{{ folder_absent_result.path }}/foobar/fileA" + - name: Change ownership of a directory with recurse=no(default) file: path={{output_dir}}/foobar owner=1234