file: fix setting relative paths for src for hard links (#56055)

pull/55396/merge
Martin Krizek 6 years ago committed by GitHub
parent 705d0201cf
commit 18f2ed63e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
bugfixes:
- file - Fix setting relative paths for hard links (https://github.com/ansible/ansible/issues/55971)

@ -52,8 +52,7 @@ options:
description: description:
- Path of the file to link to. - Path of the file to link to.
- This applies only to C(state=link) and C(state=hard). - This applies only to C(state=link) and C(state=hard).
- Will accept absolute and non-existing paths. - For C(state=link), this will also accept a non-existing path.
- Will accept relative paths unless state=hard.
- Relative paths are relative to the file being created (C(path)) which is how - Relative paths are relative to the file being created (C(path)) which is how
the Unix command C(ln -s SRC DEST) treats relative paths. the Unix command C(ln -s SRC DEST) treats relative paths.
type: path type: path
@ -758,35 +757,13 @@ def ensure_hardlink(path, src, follow, force, timestamps):
mtime = get_timestamp_for_time(timestamps['modification_time'], timestamps['modification_time_format']) mtime = get_timestamp_for_time(timestamps['modification_time'], timestamps['modification_time_format'])
atime = get_timestamp_for_time(timestamps['access_time'], timestamps['access_time_format']) atime = get_timestamp_for_time(timestamps['access_time'], timestamps['access_time_format'])
# src is the source of a hardlink. We require it if we are creating a new hardlink # src is the source of a hardlink. We require it if we are creating a new hardlink.
if src is None and not os.path.exists(b_path): # We require path in the argument_spec so we know it is present at this point.
raise AnsibleModuleError(results={'msg': 'src and dest are required for creating new hardlinks'}) if src is None:
raise AnsibleModuleError(results={'msg': 'src is required for creating new hardlinks'})
# Toshio: Begin suspect block
# I believe that this block of code is wrong for hardlinks.
# src may be relative.
# If it is relative, it should be relative to the cwd (so just use abspath).
# This is different from symlinks where src is relative to the symlink's path.
# Why must src be an absolute path?
if not os.path.isabs(b_src):
raise AnsibleModuleError(results={'msg': "src must be an absolute path"})
# If this is a link, then it can't be a dir so why is it in the conditional?
if not os.path.islink(b_path) and os.path.isdir(b_path):
relpath = path
else:
b_relpath = os.path.dirname(b_path)
relpath = to_native(b_relpath, errors='strict')
# Why? This does nothing because src was checked to be absolute above? if not os.path.exists(b_src):
absrc = os.path.join(relpath, src) raise AnsibleModuleError(results={'msg': 'src does not exist', 'dest': path, 'src': src})
b_absrc = to_bytes(absrc, errors='surrogate_or_strict')
if not force and not os.path.exists(b_absrc):
raise AnsibleModuleError(results={'msg': 'src file does not exist, use "force=yes" if you'
' really want to create the link: %s' % absrc,
'path': path, 'src': src})
# Toshio: end suspect block
diff = initial_diff(path, 'hard', prev_state) diff = initial_diff(path, 'hard', prev_state)
changed = False changed = False

@ -563,9 +563,6 @@
stat: path={{output_dir}}/test_follow_rec_target_dir/foo stat: path={{output_dir}}/test_follow_rec_target_dir/foo
register: file_in_dir_result register: file_in_dir_result
- debug: var=file_result.stat.mode
- debug: var=dir_result.stat.mode
- debug: var=file_in_dir_result.stat.mode
- name: assert that the link targets were unmodified - name: assert that the link targets were unmodified
assert: assert:
that: that:
@ -588,12 +585,77 @@
stat: path={{output_dir}}/test_follow_rec_target_dir/foo stat: path={{output_dir}}/test_follow_rec_target_dir/foo
register: file_in_dir_result register: file_in_dir_result
- debug: var=file_result.stat.mode
- debug: var=dir_result.stat.mode
- debug: var=file_in_dir_result.stat.mode
- name: assert that the link targets were modified - name: assert that the link targets were modified
assert: assert:
that: that:
- file_result.stat.mode == '0600' - file_result.stat.mode == '0600'
- dir_result.stat.mode == '0600' - dir_result.stat.mode == '0600'
- file_in_dir_result.stat.mode == '0600' - file_in_dir_result.stat.mode == '0600'
# https://github.com/ansible/ansible/issues/55971
- name: Test missing src and path
file:
state: hard
register: file_error1
ignore_errors: yes
- assert:
that:
- "file_error1 is failed"
- "file_error1.msg == 'missing required arguments: path'"
- name: Test missing src
file:
dest: "{{ output_dir }}/hard.txt"
state: hard
register: file_error2
ignore_errors: yes
- assert:
that:
- "file_error2 is failed"
- "file_error2.msg == 'src is required for creating new hardlinks'"
- name: Test non-existing src
file:
src: non-existing-file-that-does-not-exist.txt
dest: "{{ output_dir }}/hard.txt"
state: hard
register: file_error3
ignore_errors: yes
- assert:
that:
- "file_error3 is failed"
- "file_error3.msg == 'src does not exist'"
- "file_error3.dest == '{{ output_dir }}/hard.txt' | expanduser"
- "file_error3.src == 'non-existing-file-that-does-not-exist.txt'"
- block:
- name: Create a testing file
file:
dest: original_file.txt
state: touch
- name: Test relative path with state=hard
file:
src: original_file.txt
dest: hard_link_file.txt
state: hard
register: hard_link_relpath
- name: Just check if it was successful, we don't care about the actual hard link in this test
assert:
that:
- "hard_link_relpath is success"
always:
- name: Clean up
file:
path: "{{ item }}"
state: absent
loop:
- original_file.txt
- hard_link_file.txt
# END #55971

Loading…
Cancel
Save