diff --git a/lib/ansible/parsing/dataloader.py b/lib/ansible/parsing/dataloader.py index 1e15584d4c2..3e8bce70968 100644 --- a/lib/ansible/parsing/dataloader.py +++ b/lib/ansible/parsing/dataloader.py @@ -273,8 +273,8 @@ class DataLoader: :returns: An absolute path to the filename ``source`` if found :raises: An AnsibleFileNotFound Exception if the file is found to exist in the search paths ''' - b_dirname = to_bytes(dirname) - b_source = to_bytes(source) + b_dirname = to_bytes(dirname, errors='surrogate_or_strict') + b_source = to_bytes(source, errors='surrogate_or_strict') result = None search = [] @@ -305,8 +305,8 @@ class DataLoader: # always append basedir as last resort # don't add dirname if user already is using it in source if b_source.split(b'/')[0] != dirname: - search.append(os.path.join(to_bytes(self.get_basedir()), b_dirname, b_source)) - search.append(os.path.join(to_bytes(self.get_basedir()), b_source)) + search.append(os.path.join(to_bytes(self.get_basedir(), errors='surrogate_or_strict'), b_dirname, b_source)) + search.append(os.path.join(to_bytes(self.get_basedir(), errors='surrogate_or_strict'), b_source)) display.debug(u'search_path:\n\t%s' % to_text(b'\n\t'.join(search))) for b_candidate in search: @@ -316,7 +316,7 @@ class DataLoader: break if result is None: - raise AnsibleFileNotFound(file_name=source, paths=[to_text(p) for p in search]) + raise AnsibleFileNotFound(file_name=source, paths=[to_native(p) for p in search]) return result diff --git a/lib/ansible/utils/path.py b/lib/ansible/utils/path.py index 4fd416c2808..05649db79a9 100644 --- a/lib/ansible/utils/path.py +++ b/lib/ansible/utils/path.py @@ -44,20 +44,22 @@ def unfrackpath(path, follow=True, basedir=None): '$HOME/../../var/mail' becomes '/var/spool/mail' ''' - if basedir is None: - basedir = os.getcwd() - elif os.path.isfile(to_bytes(basedir, errors='surrogate_or_strict')): - basedir = os.path.dirname(basedir) + b_basedir = to_bytes(basedir, errors='surrogate_or_strict', nonstring='passthru') - final_path = os.path.expanduser(os.path.expandvars(to_bytes(path, errors='surrogate_or_strict'))) + if b_basedir is None: + b_basedir = to_bytes(os.getcwd(), errors='surrogate_or_strict') + elif os.path.isfile(b_basedir): + b_basedir = os.path.dirname(b_basedir) - if not os.path.isabs(final_path): - final_path = os.path.join(to_bytes(basedir, errors='surrogate_or_strict'), final_path) + b_final_path = os.path.expanduser(os.path.expandvars(to_bytes(path, errors='surrogate_or_strict'))) + + if not os.path.isabs(b_final_path): + b_final_path = os.path.join(b_basedir, b_final_path) if follow: - final_path = os.path.realpath(final_path) + b_final_path = os.path.realpath(b_final_path) - return to_text(os.path.normpath(final_path), errors='surrogate_or_strict') + return to_text(os.path.normpath(b_final_path), errors='surrogate_or_strict') def makedirs_safe(path, mode=None): diff --git a/test/integration/targets/copy/aliases b/test/integration/targets/copy/aliases index 9af2d790425..961b20518e2 100644 --- a/test/integration/targets/copy/aliases +++ b/test/integration/targets/copy/aliases @@ -1,2 +1,3 @@ needs/root shippable/posix/group2 +destructive diff --git a/test/integration/targets/copy/tasks/main.yml b/test/integration/targets/copy/tasks/main.yml index 023d872183d..a9d58e0962a 100644 --- a/test/integration/targets/copy/tasks/main.yml +++ b/test/integration/targets/copy/tasks/main.yml @@ -34,6 +34,20 @@ name: '{{ remote_unprivileged_user }}' register: user + - name: Check sudoers dir + stat: + path: /etc/sudoers.d + register: etc_sudoers + + - name: Set sudoers.d path fact + set_fact: + sudoers_d_file: "{{ '/etc/sudoers.d' if etc_sudoers.stat.exists else '/usr/local/etc/sudoers.d' }}/{{ remote_unprivileged_user }}" + + - name: Create sudoers file + copy: + dest: "{{ sudoers_d_file }}" + content: "{{ remote_unprivileged_user }} ALL=(ALL) NOPASSWD: ALL" + - file: path: "{{ user.home }}/.ssh" owner: '{{ remote_unprivileged_user }}' @@ -93,3 +107,8 @@ name: '{{ remote_unprivileged_user }}' state: absent remove: yes + + - name: Remove sudoers.d file + file: + path: "{{ sudoers_d_file }}" + state: absent diff --git a/test/integration/targets/copy/tasks/tests.yml b/test/integration/targets/copy/tasks/tests.yml index 9d6edaf48e3..52c6bb39b80 100644 --- a/test/integration/targets/copy/tasks/tests.yml +++ b/test/integration/targets/copy/tasks/tests.yml @@ -50,7 +50,6 @@ - copy_result.dest == remote_file_expanded - "'group' in copy_result" - "'gid' in copy_result" - - "'md5sum' in copy_result" - "'checksum' in copy_result" - "'owner' in copy_result" - "'size' in copy_result" @@ -1068,16 +1067,19 @@ file: path: 'source_recursive' state: directory + delegate_to: localhost - name: Create a file inside of the directory copy: content: "testing" dest: 'source_recursive/file' + delegate_to: localhost - name: Create a directory to place the test output in file: path: 'destination' state: directory + delegate_to: localhost - name: Copy the directory and files within (no trailing slash) copy: @@ -1323,9 +1325,10 @@ - assert: that: - - "file_attrs.stat.uid == 0" - - "file_attrs.stat.pw_name == 'root'" - "file_attrs.stat.mode == '0604'" + # The below assertions make an invalid assumption, these were not explicitly set + # - "file_attrs.stat.uid == 0" + # - "file_attrs.stat.pw_name == 'root'" - name: check that the containing directory did not change attributes stat: path={{ remote_dir }}/directory/ @@ -1343,7 +1346,8 @@ # # Recursive copying with symlinks tests # -- block: +- delegate_to: localhost + block: - name: Create a test dir to copy file: path: '{{ local_temp_dirĀ }}/top_dir' @@ -1376,7 +1380,6 @@ path: '{{ local_temp_dir }}/top_dir/subdir/circle' src: '{{ local_temp_dir }}/top_dir/' state: link - delegate_to: localhost - name: Copy the directory's link copy: @@ -1936,22 +1939,26 @@ user: name: '{{ ansible_copy_test_user_name }}' state: present + become: true register: ansible_copy_test_user - name: execute - create a group for test group: name: '{{ ansible_copy_test_user_name }}' state: present + become: true register: ansible_copy_test_group - name: execute - Copy the directory on remote with chown copy: remote_src: True - src: '{{ remote_dir }}/remote_dir_src/' - dest: '{{ remote_dir }}/new_dir_with_chown' + src: '{{ remote_dir_expanded }}/remote_dir_src/' + dest: '{{ remote_dir_expanded }}/new_dir_with_chown' owner: '{{ ansible_copy_test_user_name }}' group: '{{ ansible_copy_test_user_name }}' + follow: true register: testcase5 + become: true - name: gather - Stat the new_dir_with_chown stat: @@ -2009,11 +2016,13 @@ name: '{{ ansible_copy_test_user_name }}' state: absent remove: yes + become: true - name: execute - remove the group for test group: name: '{{ ansible_copy_test_user_name }}' state: absent + become: true ## testcase last - make sure remote_dir_src not change - block: