mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-15 01:20:51 -07:00
win_copy: Add force parameter and check-mode support (#20405)
* win_copy: Add force parameter and check-mode support The rationale behind this is that if you're working with +3GB files, creating the checksum takes a lot of time, which we can avoid by simply testing if the file exists. I also took the liberty to put the various parameters together. It probably takes a (neglible) performance hit but makes the code a bit easier to inspect/work with, as its closer to all other windows modules. On a normal run, the action plugin does a local checksum of the source and a remote checksum of the destination. And afterwards, the module will do another remote checksum of the copied source, a remote checksum of the original destination, and another remote checksum of the copied destination. On a very huge file (think 4GB) that means 5x reading the complete file (if you have a large cache you may get away with it, otherwise you're doomed !). This patch will ensure with `force: no` that not checksums are being performed. * Moving presence check before remote checksum * Adapted to wishes * Even more performance improvements
This commit is contained in:
parent
ce08b4165d
commit
98934939af
4 changed files with 63 additions and 61 deletions
|
@ -25,7 +25,7 @@ import stat
|
|||
import tempfile
|
||||
|
||||
from ansible.constants import mk_boolean as boolean
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.errors import AnsibleError, AnsibleFileNotFound
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.plugins.action import ActionBase
|
||||
from ansible.utils.hashing import checksum
|
||||
|
@ -155,10 +155,14 @@ class ActionModule(ActionBase):
|
|||
diffs = []
|
||||
for source_full, source_rel in source_files:
|
||||
|
||||
source_full = self._loader.get_real_file(source_full)
|
||||
|
||||
# Generate a hash of the local file.
|
||||
local_checksum = checksum(source_full)
|
||||
# If the local file does not exist, get_real_file() raises AnsibleFileNotFound
|
||||
try:
|
||||
source_full = self._loader.get_real_file(source_full)
|
||||
except AnsibleFileNotFound as e:
|
||||
result['failed'] = True
|
||||
result['msg'] = "could not find src=%s, %s" % (source_full, e)
|
||||
self._remove_tmp_path(tmp)
|
||||
return result
|
||||
|
||||
# Get the local mode and set if user wanted it preserved
|
||||
# https://github.com/ansible/ansible-modules-core/issues/1124
|
||||
|
@ -166,13 +170,6 @@ class ActionModule(ActionBase):
|
|||
lmode = '0%03o' % stat.S_IMODE(os.stat(source_full).st_mode)
|
||||
self._task.args['mode'] = lmode
|
||||
|
||||
# If local_checksum is not defined we can't find the file so we should fail out.
|
||||
if local_checksum is None:
|
||||
result['failed'] = True
|
||||
result['msg'] = "could not find src=%s" % source_full
|
||||
self._remove_tmp_path(tmp)
|
||||
return result
|
||||
|
||||
# This is kind of optimization - if user told us destination is
|
||||
# dir, do path manipulation right away, otherwise we still check
|
||||
# for dest being a dir via remote call below.
|
||||
|
@ -182,7 +179,7 @@ class ActionModule(ActionBase):
|
|||
dest_file = self._connection._shell.join_path(dest)
|
||||
|
||||
# Attempt to get remote file info
|
||||
dest_status = self._execute_remote_stat(dest_file, all_vars=task_vars, follow=follow, tmp=tmp)
|
||||
dest_status = self._execute_remote_stat(dest_file, all_vars=task_vars, follow=follow, tmp=tmp, checksum=force)
|
||||
|
||||
if dest_status['exists'] and dest_status['isdir']:
|
||||
# The dest is a directory.
|
||||
|
@ -196,12 +193,15 @@ class ActionModule(ActionBase):
|
|||
else:
|
||||
# Append the relative source location to the destination and get remote stats again
|
||||
dest_file = self._connection._shell.join_path(dest, source_rel)
|
||||
dest_status = self._execute_remote_stat(dest_file, all_vars=task_vars, follow=follow, tmp=tmp)
|
||||
dest_status = self._execute_remote_stat(dest_file, all_vars=task_vars, follow=follow, tmp=tmp, checksum=force)
|
||||
|
||||
if dest_status['exists'] and not force:
|
||||
# remote_file does not exist so continue to next iteration.
|
||||
# remote_file exists so continue to next iteration.
|
||||
continue
|
||||
|
||||
# Generate a hash of the local file.
|
||||
local_checksum = checksum(source_full)
|
||||
|
||||
if local_checksum != dest_status['checksum']:
|
||||
# The checksums don't match and we will change or error out.
|
||||
changed = True
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue