* Fix file touch check mode result (#79360) (#79422)
Fixes #79360
(cherry picked from commit 3936b5c471)
* Rename changelog fragment according to PR number
This commit is contained in:
@ -0,0 +1,3 @@
|
||||
bugfixes:
|
||||
- file - touch action in check mode was always returning ok. Fix now evaluates the different conditions and
|
||||
returns the appropriate changed status. (https://github.com/ansible/ansible/issues/79360)
|
||||
@ -552,34 +552,38 @@ def execute_touch(path, follow, timestamps):
|
||||
mtime = get_timestamp_for_time(timestamps['modification_time'], timestamps['modification_time_format'])
|
||||
atime = get_timestamp_for_time(timestamps['access_time'], timestamps['access_time_format'])
|
||||
|
||||
if not module.check_mode:
|
||||
if prev_state == 'absent':
|
||||
# Create an empty file if the filename did not already exist
|
||||
try:
|
||||
open(b_path, 'wb').close()
|
||||
changed = True
|
||||
except (OSError, IOError) as e:
|
||||
raise AnsibleModuleError(results={'msg': 'Error, could not touch target: %s'
|
||||
% to_native(e, nonstring='simplerepr'),
|
||||
'path': path})
|
||||
|
||||
# Update the attributes on the file
|
||||
diff = initial_diff(path, 'touch', prev_state)
|
||||
file_args = module.load_file_common_arguments(module.params)
|
||||
# If the file did not already exist
|
||||
if prev_state == 'absent':
|
||||
# if we are in check mode and the file is absent
|
||||
# we can set the changed status to True and return
|
||||
if module.check_mode:
|
||||
result['changed'] = True
|
||||
return result
|
||||
# Create an empty file
|
||||
try:
|
||||
changed = module.set_fs_attributes_if_different(file_args, changed, diff, expand=False)
|
||||
changed |= update_timestamp_for_file(file_args['path'], mtime, atime, diff)
|
||||
except SystemExit as e:
|
||||
if e.code: # this is the exit code passed to sys.exit, not a constant -- pylint: disable=using-constant-test
|
||||
# We take this to mean that fail_json() was called from
|
||||
# somewhere in basic.py
|
||||
if prev_state == 'absent':
|
||||
# If we just created the file we can safely remove it
|
||||
os.remove(b_path)
|
||||
raise
|
||||
open(b_path, 'wb').close()
|
||||
changed = True
|
||||
except (OSError, IOError) as e:
|
||||
raise AnsibleModuleError(results={'msg': 'Error, could not touch target: %s'
|
||||
% to_native(e, nonstring='simplerepr'),
|
||||
'path': path})
|
||||
# Update the attributes on the file
|
||||
diff = initial_diff(path, 'touch', prev_state)
|
||||
file_args = module.load_file_common_arguments(module.params)
|
||||
try:
|
||||
changed = module.set_fs_attributes_if_different(file_args, changed, diff, expand=False)
|
||||
changed |= update_timestamp_for_file(file_args['path'], mtime, atime, diff)
|
||||
except SystemExit as e:
|
||||
if e.code: # this is the exit code passed to sys.exit, not a constant -- pylint: disable=using-constant-test
|
||||
# We take this to mean that fail_json() was called from
|
||||
# somewhere in basic.py
|
||||
if prev_state == 'absent':
|
||||
# If we just created the file we can safely remove it
|
||||
os.remove(b_path)
|
||||
raise
|
||||
|
||||
result['changed'] = changed
|
||||
result['diff'] = diff
|
||||
result['changed'] = changed
|
||||
result['diff'] = diff
|
||||
return result
|
||||
|
||||
|
||||
|
||||
@ -711,6 +711,82 @@
|
||||
- group_exists.warnings is not defined
|
||||
- group_gid_exists.warnings is not defined
|
||||
|
||||
# ensures touching a file returns changed when needed
|
||||
# issue: https://github.com/ansible/ansible/issues/79360
|
||||
- name: touch a file returns changed in check mode if file does not exist
|
||||
file:
|
||||
path: '/tmp/touch_check_mode_test'
|
||||
state: touch
|
||||
check_mode: yes
|
||||
register: touch_result_in_check_mode_not_existing
|
||||
|
||||
- name: touch the file
|
||||
file:
|
||||
path: '/tmp/touch_check_mode_test'
|
||||
mode: "0660"
|
||||
state: touch
|
||||
|
||||
- name: touch an existing file returns changed in check mode
|
||||
file:
|
||||
path: '/tmp/touch_check_mode_test'
|
||||
state: touch
|
||||
check_mode: yes
|
||||
register: touch_result_in_check_mode_change_all_attr
|
||||
|
||||
- name: touch an existing file returns changed in check mode when preserving access time
|
||||
file:
|
||||
path: '/tmp/touch_check_mode_test'
|
||||
state: touch
|
||||
access_time: "preserve"
|
||||
check_mode: yes
|
||||
register: touch_result_in_check_mode_preserve_access_time
|
||||
|
||||
- name: touch an existing file returns changed in check mode when only mode changes
|
||||
file:
|
||||
path: '/tmp/touch_check_mode_test'
|
||||
state: touch
|
||||
access_time: "preserve"
|
||||
modification_time: "preserve"
|
||||
mode: "0640"
|
||||
check_mode: yes
|
||||
register: touch_result_in_check_mode_change_only_mode
|
||||
|
||||
- name: touch an existing file returns ok if all attributes are preserved
|
||||
file:
|
||||
path: '/tmp/touch_check_mode_test'
|
||||
state: touch
|
||||
access_time: "preserve"
|
||||
modification_time: "preserve"
|
||||
check_mode: yes
|
||||
register: touch_result_in_check_mode_all_attrs_preserved
|
||||
|
||||
- name: touch an existing file fails in check mode when user does not exist
|
||||
file:
|
||||
path: '/tmp/touch_check_mode_test'
|
||||
state: touch
|
||||
owner: not-existing-user
|
||||
check_mode: yes
|
||||
ignore_errors: true
|
||||
register: touch_result_in_check_mode_fails_not_existing_user
|
||||
|
||||
- name: touch an existing file fails in check mode when group does not exist
|
||||
file:
|
||||
path: '/tmp/touch_check_mode_test'
|
||||
state: touch
|
||||
group: not-existing-group
|
||||
check_mode: yes
|
||||
ignore_errors: true
|
||||
register: touch_result_in_check_mode_fails_not_existing_group
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- touch_result_in_check_mode_not_existing.changed
|
||||
- touch_result_in_check_mode_preserve_access_time.changed
|
||||
- touch_result_in_check_mode_change_only_mode.changed
|
||||
- not touch_result_in_check_mode_all_attrs_preserved.changed
|
||||
- touch_result_in_check_mode_fails_not_existing_user.warnings[0] is search('failed to look up user')
|
||||
- touch_result_in_check_mode_fails_not_existing_group.warnings[0] is search('failed to look up group')
|
||||
|
||||
# https://github.com/ansible/ansible/issues/50943
|
||||
# Need to use /tmp as nobody can't access remote_tmp_dir_test at all
|
||||
- name: create file as root with all write permissions
|
||||
|
||||
Reference in New Issue
Block a user