From bdaa091b33f0ebb273c6ad99b3835530ba2b5a30 Mon Sep 17 00:00:00 2001 From: Aleksey Tsalolikhin <66701226+atsalolikhin-spokeo@users.noreply.github.com> Date: Mon, 28 Aug 2023 11:54:08 -0700 Subject: [PATCH] Add warnings for illegal file names in role (#81555) Co-authored-by: Aleksey Tsalolikhin --- ...d-warning-for-illegal-filenames-in-roles.yaml | 5 +++++ lib/ansible/galaxy/role.py | 16 ++++++++++++++-- .../targets/ansible-galaxy-role/tasks/main.yml | 5 +++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/81555-add-warning-for-illegal-filenames-in-roles.yaml diff --git a/changelogs/fragments/81555-add-warning-for-illegal-filenames-in-roles.yaml b/changelogs/fragments/81555-add-warning-for-illegal-filenames-in-roles.yaml new file mode 100644 index 00000000000..ad56c26d0e5 --- /dev/null +++ b/changelogs/fragments/81555-add-warning-for-illegal-filenames-in-roles.yaml @@ -0,0 +1,5 @@ +minor_changes: + - ansible-galaxy - used to crash out with a "Errno 20 Not a directory" error when extracting files from a role when hitting a file with an illegal name (https://github.com/ansible/ansible/pull/81553). Now it gives a warning identifying the culprit file and the rule violation (e.g., ``my$class.jar`` has a ``$`` in the name) before crashing out, giving the user a chance to remove the invalid file and try again. (https://github.com/ansible/ansible/pull/81555). + +known_issues: + - ansible-galaxy - dies in the middle of installing a role when that role contains Java inner classes (files with $ in the file name). This is by design, to exclude temporary or backup files. (https://github.com/ansible/ansible/pull/81553). diff --git a/lib/ansible/galaxy/role.py b/lib/ansible/galaxy/role.py index f2e1dd3c2fc..b5ba1006785 100644 --- a/lib/ansible/galaxy/role.py +++ b/lib/ansible/galaxy/role.py @@ -376,8 +376,20 @@ class GalaxyRole(object): # It will create the parent directory as an empty file and will # explode if the directory contains valid files. # Leaving this as is since the whole module needs a rewrite. - if n_part != '..' and not n_part.startswith('~') and '$' not in n_part: - n_final_parts.append(n_part) + # + # Check if we have any files with illegal names, + # and display a warning if so. This could help users + # to debug a broken installation. + if n_part == '..': + display.warning(f"Illegal filename '{n_part}': '..' is not allowed") + continue + if n_part.startswith('~'): + display.warning(f"Illegal filename '{n_part}': names cannot start with '~'") + continue + if '$' in n_part: + display.warning(f"Illegal filename '{n_part}': names cannot contain '$'") + continue + n_final_parts.append(n_part) member.name = os.path.join(*n_final_parts) role_tar_file.extract(member, to_native(self.path)) diff --git a/test/integration/targets/ansible-galaxy-role/tasks/main.yml b/test/integration/targets/ansible-galaxy-role/tasks/main.yml index 03d0b3c2433..3e1e6e7e71b 100644 --- a/test/integration/targets/ansible-galaxy-role/tasks/main.yml +++ b/test/integration/targets/ansible-galaxy-role/tasks/main.yml @@ -30,6 +30,11 @@ content: "" dest: "{{ remote_tmp_dir }}/role.d/tasks/~invalid.yml" +- name: Invalid file + copy: + content: "" + dest: "{{ remote_tmp_dir }}/role.d/tasks/invalid$name.yml" + - name: Valid requirements file copy: dest: valid-requirements.yml