fix copy module update atime/mtime (#83235)

Ensure we force mtime/atime update when using copystat

Co-authored-by: Sloane Hertel <19572925+s-hertel@users.noreply.github.com>
Co-authored-by: Brian Coca <bcoca@users.noreply.github.com>
pull/83796/head
dkuji 4 months ago committed by GitHub
parent 89137cb5a0
commit 26375e7f12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,2 @@
bugfixes:
- copy - mtime/atime not updated. Fix now update mtime/atime(https://github.com/ansible/ansible/issues/83013)

@ -1598,6 +1598,7 @@ class AnsibleModule(object):
dest_stat = os.stat(b_dest)
os.chown(b_src, dest_stat.st_uid, dest_stat.st_gid)
shutil.copystat(b_dest, b_src)
os.utime(b_src, times=(time.time(), time.time()))
except OSError as e:
if e.errno != errno.EPERM:
raise

@ -2448,3 +2448,45 @@
loop:
- '{{ src }}'
- '{{ src }}_dest'
- name: Verify atime and mtime update on content change (same partition)
vars:
remote_file: "{{ remote_tmp_dir }}/foo.txt"
ansible_remote_tmp: "{{ remote_tmp_dir }}"
block:
- name: Create a dest file
shell: "echo Test content > {{ remote_file }}"
register: create_dest_result
- name: Check the stat results of the file before copying
stat:
path: "{{ remote_file }}"
register: stat_results_before_copy
- name: Overwrite the file using the content system
copy:
content: "modified"
dest: "{{ remote_file }}"
decrypt: no
register: copy_result
- name: Check the stat results of the file after copying
stat:
path: "{{ remote_file }}"
register: stat_results_after_copy
- name: Assert that the file has changed
assert:
that:
- "create_dest_result is changed"
- "copy_result is changed"
- "'content' not in copy_result"
- "stat_results_before_copy.stat.atime < stat_results_after_copy.stat.atime"
- "stat_results_before_copy.stat.mtime < stat_results_after_copy.stat.mtime"
always:
- name: clean up dest file
file:
path: '{{ item }}'
state: absent
loop:
- '{{ remote_file }}'

@ -48,6 +48,7 @@ def atomic_mocks(mocker, monkeypatch):
'copyfileobj': mocker.patch('shutil.copyfileobj'),
'move': mocker.patch('shutil.move'),
'mkstemp': mocker.patch('tempfile.mkstemp'),
'utime': mocker.patch('os.utime'),
}
mocks['getlogin'].return_value = 'root'

Loading…
Cancel
Save