Fix collection install from source respects symlinks (#78983)

* Fix installation from source transforms symlinks of dirs to empty dirs

* Add test to check symlinks to dirs are respected when installing from source

* Add changelog for collection install from source symlink to dirs issue
pull/79071/head
sbettid 2 years ago committed by GitHub
parent 420564c5bc
commit 8cf7a0d3f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
bugfixes:
- ansible-galaxy collection install - respect symlinks when installing from source or local repository (https://github.com/ansible/ansible/issues/78442)

@ -1372,17 +1372,24 @@ def _build_collection_dir(b_collection_path, b_collection_output, collection_man
src_file = os.path.join(b_collection_path, to_bytes(file_info['name'], errors='surrogate_or_strict'))
dest_file = os.path.join(b_collection_output, to_bytes(file_info['name'], errors='surrogate_or_strict'))
existing_is_exec = os.stat(src_file).st_mode & stat.S_IXUSR
existing_is_exec = os.stat(src_file, follow_symlinks=False).st_mode & stat.S_IXUSR
mode = 0o0755 if existing_is_exec else 0o0644
if os.path.isdir(src_file):
# ensure symlinks to dirs are not translated to empty dirs
if os.path.isdir(src_file) and not os.path.islink(src_file):
mode = 0o0755
base_directories.append(src_file)
os.mkdir(dest_file, mode)
else:
shutil.copyfile(src_file, dest_file)
# do not follow symlinks to ensure the original link is used
shutil.copyfile(src_file, dest_file, follow_symlinks=False)
# avoid setting specific permission on symlinks since it does not
# support avoid following symlinks and will thrown an exception if the
# symlink target does not exist
if not os.path.islink(dest_file):
os.chmod(dest_file, mode)
os.chmod(dest_file, mode)
collection_output = to_text(b_collection_output)
return collection_output

@ -771,6 +771,56 @@
- install_symlink_actual.results[5].stat.islnk
- install_symlink_actual.results[5].stat.lnk_target == '../REÅDMÈ.md'
# Testing an install from source to check that symlinks to directories
# are preserved (see issue https://github.com/ansible/ansible/issues/78442)
- name: symlink_dirs collection install from source test
block:
- name: create symlink_dirs collection
command: ansible-galaxy collection init symlink_dirs.symlink_dirs --init-path "{{ galaxy_dir }}/scratch"
- name: create directory in collection
file:
path: "{{ galaxy_dir }}/scratch/symlink_dirs/symlink_dirs/folderA"
state: directory
- name: create symlink to folderA
file:
dest: "{{ galaxy_dir }}/scratch/symlink_dirs/symlink_dirs/folderB"
src: ./folderA
state: link
force: yes
- name: install symlink_dirs collection from source
command: ansible-galaxy collection install {{ galaxy_dir }}/scratch/symlink_dirs/
environment:
ANSIBLE_COLLECTIONS_PATHS: '{{ galaxy_dir }}/ansible_collections'
register: install_symlink_dirs
- name: get result of install collection with symlink_dirs - {{ test_id }}
stat:
path: '{{ galaxy_dir }}/ansible_collections/symlink_dirs/symlink_dirs/{{ path }}'
register: install_symlink_dirs_actual
loop_control:
loop_var: path
loop:
- folderA
- folderB
- name: assert install collection with symlink_dirs - {{ test_id }}
assert:
that:
- '"Installing ''symlink_dirs.symlink_dirs:1.0.0'' to" in install_symlink_dirs.stdout'
- install_symlink_dirs_actual.results[0].stat.isdir
- install_symlink_dirs_actual.results[1].stat.islnk
- install_symlink_dirs_actual.results[1].stat.lnk_target == './folderA'
always:
- name: clean up symlink_dirs collection directory
file:
path: "{{ galaxy_dir }}/scratch/symlink_dirs"
state: absent
- name: remove install directory for the next test because parent_dep.parent_collection was installed - {{ test_id }}
file:
path: '{{ galaxy_dir }}/ansible_collections'

Loading…
Cancel
Save