diff --git a/changelogs/fragments/58323-copy-deep-recursive-with-remote_src.yaml b/changelogs/fragments/58323-copy-deep-recursive-with-remote_src.yaml new file mode 100644 index 00000000000..b8106f92326 --- /dev/null +++ b/changelogs/fragments/58323-copy-deep-recursive-with-remote_src.yaml @@ -0,0 +1,2 @@ +bugfixes: +- copy - recursive copy with ``remote_src=yes`` now recurses beyond first level. (Fixes https://github.com/ansible/ansible/issues/58284) diff --git a/lib/ansible/modules/files/copy.py b/lib/ansible/modules/files/copy.py index 6912439af6f..21aa74c9379 100644 --- a/lib/ansible/modules/files/copy.py +++ b/lib/ansible/modules/files/copy.py @@ -485,6 +485,9 @@ def copy_common_dirs(src, dest, module): left_only_changed = copy_left_only(b_src_item_path, b_dest_item_path, module) if diff_files_changed or left_only_changed: changed = True + + # recurse into subdirectory + changed = changed or copy_common_dirs(os.path.join(src, item), os.path.join(dest, item), module) return changed diff --git a/test/integration/targets/copy/tasks/tests.yml b/test/integration/targets/copy/tasks/tests.yml index 52c6bb39b80..c2e4f1e4661 100644 --- a/test/integration/targets/copy/tasks/tests.yml +++ b/test/integration/targets/copy/tasks/tests.yml @@ -1927,6 +1927,62 @@ - "stat_testcase4_local_follow_false_remote_dir_src_link_file12.stat.exists" - "stat_testcase4_local_follow_false_remote_dir_src_link_file12.stat.islnk" +- block: + - name: execute - Clone the source directory on remote + copy: + remote_src: True + src: '{{ remote_dir }}/remote_dir_src/' + dest: '{{ remote_dir }}/testcase5_remote_src_subdirs_src' + - name: Create a 2nd level subdirectory + file: + path: '{{ remote_dirĀ }}/testcase5_remote_src_subdirs_src/subdir/subdir2/' + state: directory + - name: execute - Copy the directory on remote + copy: + remote_src: True + src: '{{ remote_dir }}/testcase5_remote_src_subdirs_src/' + dest: '{{ remote_dir }}/testcase5_remote_src_subdirs_dest' + local_follow: True + - name: execute - Create a new file in the subdir + copy: + dest: '{{ remote_dir }}/testcase5_remote_src_subdirs_src/subdir/subdir2/file13' + content: 'very new file' + - name: gather - Stat the testcase5_remote_src_subdirs_src/subdir/subdir2/file13 + stat: + path: '{{ remote_dir }}/testcase5_remote_src_subdirs_src/subdir/subdir2/file13' + - name: execute - Copy the directory on remote + copy: + remote_src: True + src: '{{ remote_dir }}/testcase5_remote_src_subdirs_src/' + dest: '{{ remote_dir }}/testcase5_remote_src_subdirs_dest/' + register: testcase5_new + - name: execute - Edit a file in the subdir + copy: + dest: '{{ remote_dir }}/testcase5_remote_src_subdirs_src/subdir/subdir2/file13' + content: 'NOT hello world 12' + - name: gather - Stat the testcase5_remote_src_subdirs_src/subdir/subdir2/file13 + stat: + path: '{{ remote_dir }}/testcase5_remote_src_subdirs_src/subdir/subdir2/file13' + register: stat_testcase5_remote_src_subdirs_file13_before + - name: execute - Copy the directory on remote + copy: + remote_src: True + src: '{{ remote_dir }}/testcase5_remote_src_subdirs_src/' + dest: '{{ remote_dir }}/testcase5_remote_src_subdirs_dest/' + register: testcase5_edited + - name: gather - Stat the testcase5_remote_src_subdirs_dest/subdir/subdir2/file13 + stat: + path: '{{ remote_dir }}/testcase5_remote_src_subdirs_dest/subdir/subdir2/file13' + register: stat_testcase5_remote_src_subdirs_file13 + - name: assert - remote_dir_src has copied with local_follow False. + assert: + that: + - testcase5_new is changed + - testcase5_edited is changed + - "stat_testcase5_remote_src_subdirs_file13.stat.exists" + - "stat_testcase5_remote_src_subdirs_file13_before.stat.checksum == stat_testcase5_remote_src_subdirs_file13.stat.checksum" + + ## test copying the directory on remote with chown