diff --git a/changelogs/fragments/552-k8s_cp-fix-issue-when-copying-item-with-space-in-its-name.yml b/changelogs/fragments/552-k8s_cp-fix-issue-when-copying-item-with-space-in-its-name.yml new file mode 100644 index 0000000000..4416a3643f --- /dev/null +++ b/changelogs/fragments/552-k8s_cp-fix-issue-when-copying-item-with-space-in-its-name.yml @@ -0,0 +1,3 @@ +--- +trivial: + - k8s_cp - Fix issue when copying directory with space in its name from Pod without 'find' executable (https://github.com/ansible-collections/kubernetes.core/pull/552). diff --git a/plugins/module_utils/copy.py b/plugins/module_utils/copy.py index fcea3ec8ee..c7e1b4e21a 100644 --- a/plugins/module_utils/copy.py +++ b/plugins/module_utils/copy.py @@ -144,7 +144,13 @@ def listfiles_with_find(self, path): return files def listfile_with_echo(self, path): - echo_cmd = [self.pod_shell, "-c", "echo {path}/* {path}/.*".format(path=path)] + echo_cmd = [ + self.pod_shell, + "-c", + "echo {path}/* {path}/.*".format( + path=path.translate(str.maketrans({" ": r"\ "})) + ), + ] error, out, err = self._run_from_pod(cmd=echo_cmd) if error.get("status") != "Success": self.module.fail_json(msg=error.get("message")) diff --git a/tests/integration/targets/k8s_copy/tasks/main.yml b/tests/integration/targets/k8s_copy/tasks/main.yml index 021faa32a8..519be8f6f9 100644 --- a/tests/integration/targets/k8s_copy/tasks/main.yml +++ b/tests/integration/targets/k8s_copy/tasks/main.yml @@ -24,6 +24,7 @@ - include_tasks: test_multi_container_pod.yml - include_tasks: test_copy_directory.yml - include_tasks: test_copy_large_file.yml + - include_tasks: test_copy_item_with_space_in_its_name.yml always: diff --git a/tests/integration/targets/k8s_copy/tasks/test_copy_item_with_space_in_its_name.yml b/tests/integration/targets/k8s_copy/tasks/test_copy_item_with_space_in_its_name.yml new file mode 100644 index 0000000000..df3efd6bd4 --- /dev/null +++ b/tests/integration/targets/k8s_copy/tasks/test_copy_item_with_space_in_its_name.yml @@ -0,0 +1,120 @@ +--- +- name: create temporary directory for testing + tempfile: + state: directory + suffix: .space + register: _tmpdir + +- block: + - set_fact: + some_file_content: 'this content will be stored into a file in the remote pod which has space in its name' + + - name: create file with space in the name on remote pod + kubernetes.core.k8s_cp: + namespace: '{{ copy_namespace }}' + pod: '{{ pod_without_executable_find.name }}' + remote_path: "/file name space .txt" + content: '{{ some_file_content }}' + state: to_pod + + - set_fact: + local_file_path: '{{ _tmpdir.path }}/file_from_pod.txt' + + - name: copy file (with space in its name) from pod to local filesystem + kubernetes.core.k8s_cp: + namespace: '{{ copy_namespace }}' + pod: '{{ pod_without_executable_find.name }}' + remote_path: "/file name space .txt" + local_path: '{{ local_file_path }}' + state: from_pod + + - name: Ensure file was successfully copied + assert: + that: + - lookup('file', local_file_path) == some_file_content + + - set_fact: + dir_config: + - 'test\ dir\ 01/file1.txt' + - 'test\ dir\ 01/file with space in its name.txt' + - 'test\ dir\ 02/file2.txt' + - 'test\ dir\ 02/another file with space in its name ' + - 'test\ dir\ 03/file3.txt' + - 'test\ dir\ 03/a third file with space in its name' + + - set_fact: + escape_char: \ + + - name: create directories on Pod + kubernetes.core.k8s_exec: + namespace: "{{ copy_namespace }}" + pod: "{{ pod_without_executable_find.name }}" + command: "mkdir -p /ansible_testing/{{ item | dirname }}" + with_items: '{{ dir_config }}' + + - name: create files on remote pod + kubernetes.core.k8s_cp: + namespace: '{{ copy_namespace }}' + pod: '{{ pod_without_executable_find.name }}' + remote_path: "/ansible_testing/{{ item | replace(escape_char, '') }}" + content: "This content is from file named: {{ item | replace(escape_char, '') }}" + state: to_pod + with_items: '{{ dir_config }}' + + - set_fact: + local_copy: '{{ _tmpdir.path }}/local_partial_copy' + full_copy: '{{ _tmpdir.path }}/local_full_copy' + + - name: create local directories + file: + state: directory + path: '{{ item }}' + with_items: + - '{{ local_copy }}' + - '{{ full_copy }}' + + - name: Copy directory from Pod into local filesystem + kubernetes.core.k8s_cp: + namespace: '{{ copy_namespace }}' + pod: '{{ pod_without_executable_find.name }}' + remote_path: "/ansible_testing/{{ item }}" + local_path: '{{ local_copy }}' + state: from_pod + with_items: + - 'test dir 01' + - 'test dir 02' + - 'test dir 03' + + - name: Compare resulting directory + kubectl_file_compare: + namespace: '{{ copy_namespace }}' + pod: '{{ pod_without_executable_find.name }}' + remote_path: "/ansible_testing/{{ item }}" + local_path: '{{ local_copy }}/{{ item }}' + with_items: + - 'test dir 01' + - 'test dir 02' + - 'test dir 03' + + - name: Copy remote directory into local file system + kubernetes.core.k8s_cp: + namespace: '{{ copy_namespace }}' + pod: '{{ pod_without_executable_find.name }}' + remote_path: "/ansible_testing" + local_path: '{{ full_copy }}' + state: from_pod + + - name: Compare resulting directory + kubectl_file_compare: + namespace: '{{ copy_namespace }}' + pod: '{{ pod_without_executable_find.name }}' + remote_path: "/ansible_testing" + local_path: '{{ full_copy }}/ansible_testing' + + always: + - name: Delete temporary directory + file: + state: absent + path: '{{ _tmpdir.path }}' + ignore_errors: true + when: _tmpdir is defined