diff --git a/changelogs/fragments/copy_fix.yml b/changelogs/fragments/copy_fix.yml new file mode 100644 index 00000000000..0ee7c1843e4 --- /dev/null +++ b/changelogs/fragments/copy_fix.yml @@ -0,0 +1,3 @@ +--- +minor_changes: + - copy - fix appending symlinks information. diff --git a/lib/ansible/plugins/action/copy.py b/lib/ansible/plugins/action/copy.py index 89a6a8f1f95..e2fd9e9089b 100644 --- a/lib/ansible/plugins/action/copy.py +++ b/lib/ansible/plugins/action/copy.py @@ -187,7 +187,7 @@ def _walk_dirs(topdir, base_path=None, local_follow=False, trailing_slash_detect offset += 1 if os.path.islink(topdir) and not local_follow: - r_files['symlinks'] = (os.readlink(topdir), os.path.basename(topdir)) + r_files['symlinks'].append((os.readlink(topdir), os.path.basename(topdir))) return r_files dir_stats = os.stat(topdir) diff --git a/test/integration/targets/copy/tasks/tests.yml b/test/integration/targets/copy/tasks/tests.yml index 06643b97a03..81be4e6f095 100644 --- a/test/integration/targets/copy/tasks/tests.yml +++ b/test/integration/targets/copy/tasks/tests.yml @@ -2535,3 +2535,46 @@ state: absent loop: - '{{ remote_file }}' + +- name: Test copy with local_follow=False and dest is a symlink + block: + - name: execute - Create a test dest dir + file: + path: '{{ item }}' + state: directory + loop: + - '{{ remote_tmp_dir }}/testcase_local_follow_false_symlink_dest' + - '{{ remote_tmp_dir }}/dest' + + - name: Create a dest symlink + file: + src: "{{ remote_tmp_dir }}/dest" + state: link + dest: "{{ remote_tmp_dir }}/sym_dest" + + - name: Copy a file to the dest symlink + copy: + src: "{{ remote_tmp_dir }}/sym_dest" + dest: "{{ remote_tmp_dir }}/testcase_local_follow_false_symlink_dest" + local_follow: False + remote_src: True + register: copy_result + + - name: Gather info about copied symlink + stat: + path: "{{ remote_tmp_dir }}/testcase_local_follow_false_symlink_dest/sym_dest" + register: stat_result + + - name: Assert that the file has been copied + assert: + that: + - copy_result is changed + - stat_result.stat.exists + always: + - name: execute - Clean up + file: + path: '{{ item }}' + state: absent + loop: + - '{{ remote_tmp_dir }}/testcase_local_follow_false_symlink_dest' + - '{{ remote_tmp_dir }}/dest'