summaryrefslogtreecommitdiff
path: root/lib/ansible/modules/copy.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ansible/modules/copy.py')
-rw-r--r--lib/ansible/modules/copy.py73
1 files changed, 35 insertions, 38 deletions
diff --git a/lib/ansible/modules/copy.py b/lib/ansible/modules/copy.py
index 0e7dfe28..9bbc02f7 100644
--- a/lib/ansible/modules/copy.py
+++ b/lib/ansible/modules/copy.py
@@ -14,14 +14,10 @@ module: copy
version_added: historical
short_description: Copy files to remote locations
description:
- - The M(ansible.builtin.copy) module copies a file or a directory structure from the local or remote machine to a location on the remote machine.
- File system meta-information (permissions, ownership, etc.) may be set, even when the file or directory already exists on the target system.
- Some meta-information may be copied on request.
- - Get meta-information with the M(ansible.builtin.stat) module.
- - Set meta-information with the M(ansible.builtin.file) module.
+ - The C(copy) module copies a file from the local or remote machine to a location on the remote machine.
- Use the M(ansible.builtin.fetch) module to copy files from remote locations to the local box.
- If you need variable interpolation in copied files, use the M(ansible.builtin.template) module.
- Using a variable with the O(content) parameter produces unpredictable results.
+ Using a variable in the C(content) field will result in unpredictable output.
- For Windows targets, use the M(ansible.windows.win_copy) module instead.
options:
src:
@@ -35,19 +31,19 @@ options:
type: path
content:
description:
- - When used instead of O(src), sets the contents of a file directly to the specified value.
- - Works only when O(dest) is a file. Creates the file if it does not exist.
- - For advanced formatting or if O(content) contains a variable, use the
+ - When used instead of C(src), sets the contents of a file directly to the specified value.
+ - Works only when C(dest) is a file. Creates the file if it does not exist.
+ - For advanced formatting or if C(content) contains a variable, use the
M(ansible.builtin.template) module.
type: str
version_added: '1.1'
dest:
description:
- Remote absolute path where the file should be copied to.
- - If O(src) is a directory, this must be a directory too.
- - If O(dest) is a non-existent path and if either O(dest) ends with "/" or O(src) is a directory, O(dest) is created.
- - If O(dest) is a relative path, the starting directory is determined by the remote host.
- - If O(src) and O(dest) are files, the parent directory of O(dest) is not created and the task fails if it does not already exist.
+ - If C(src) is a directory, this must be a directory too.
+ - If C(dest) is a non-existent path and if either C(dest) ends with "/" or C(src) is a directory, C(dest) is created.
+ - If I(dest) is a relative path, the starting directory is determined by the remote host.
+ - If C(src) and C(dest) are files, the parent directory of C(dest) is not created and the task fails if it does not already exist.
type: path
required: yes
backup:
@@ -59,8 +55,8 @@ options:
force:
description:
- Influence whether the remote file must always be replaced.
- - If V(true), the remote file will be replaced when contents are different than the source.
- - If V(false), the file will only be transferred if the destination does not exist.
+ - If C(true), the remote file will be replaced when contents are different than the source.
+ - If C(false), the file will only be transferred if the destination does not exist.
type: bool
default: yes
version_added: '1.1'
@@ -69,34 +65,33 @@ options:
- The permissions of the destination file or directory.
- For those used to C(/usr/bin/chmod) remember that modes are actually octal numbers.
You must either add a leading zero so that Ansible's YAML parser knows it is an octal number
- (like V(0644) or V(01777)) or quote it (like V('644') or V('1777')) so Ansible receives a string
+ (like C(0644) or C(01777)) or quote it (like C('644') or C('1777')) so Ansible receives a string
and can do its own conversion from string into number. Giving Ansible a number without following
one of these rules will end up with a decimal number which will have unexpected results.
- - As of Ansible 1.8, the mode may be specified as a symbolic mode (for example, V(u+rwx) or V(u=rw,g=r,o=r)).
- - As of Ansible 2.3, the mode may also be the special string V(preserve).
- - V(preserve) means that the file will be given the same permissions as the source file.
- - When doing a recursive copy, see also O(directory_mode).
- - If O(mode) is not specified and the destination file B(does not) exist, the default C(umask) on the system will be used
+ - As of Ansible 1.8, the mode may be specified as a symbolic mode (for example, C(u+rwx) or C(u=rw,g=r,o=r)).
+ - As of Ansible 2.3, the mode may also be the special string C(preserve).
+ - C(preserve) means that the file will be given the same permissions as the source file.
+ - When doing a recursive copy, see also C(directory_mode).
+ - If C(mode) is not specified and the destination file B(does not) exist, the default C(umask) on the system will be used
when setting the mode for the newly created file.
- - If O(mode) is not specified and the destination file B(does) exist, the mode of the existing file will be used.
- - Specifying O(mode) is the best way to ensure files are created with the correct permissions.
+ - If C(mode) is not specified and the destination file B(does) exist, the mode of the existing file will be used.
+ - Specifying C(mode) is the best way to ensure files are created with the correct permissions.
See CVE-2020-1736 for further details.
directory_mode:
description:
- - Set the access permissions of newly created directories to the given mode.
- Permissions on existing directories do not change.
- - See O(mode) for the syntax of accepted values.
- - The target system's defaults determine permissions when this parameter is not set.
+ - When doing a recursive copy set the mode for the directories.
+ - If this is not set we will use the system defaults.
+ - The mode is only set on directories which are newly created, and will not affect those that already existed.
type: raw
version_added: '1.5'
remote_src:
description:
- - Influence whether O(src) needs to be transferred or already is present remotely.
- - If V(false), it will search for O(src) on the controller node.
- - If V(true) it will search for O(src) on the managed (remote) node.
- - O(remote_src) supports recursive copying as of version 2.8.
- - O(remote_src) only works with O(mode=preserve) as of version 2.6.
- - Autodecryption of files does not work when O(remote_src=yes).
+ - Influence whether C(src) needs to be transferred or already is present remotely.
+ - If C(false), it will search for C(src) on the controller node.
+ - If C(true) it will search for C(src) on the managed (remote) node.
+ - C(remote_src) supports recursive copying as of version 2.8.
+ - C(remote_src) only works with C(mode=preserve) as of version 2.6.
+ - Autodecryption of files does not work when C(remote_src=yes).
type: bool
default: no
version_added: '2.0'
@@ -298,7 +293,7 @@ import stat
import tempfile
import traceback
-from ansible.module_utils.common.text.converters import to_bytes, to_native
+from ansible.module_utils._text import to_bytes, to_native
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.process import get_bin_path
from ansible.module_utils.common.locale import get_best_parsable_locale
@@ -523,7 +518,7 @@ def copy_common_dirs(src, dest, module):
changed = True
# recurse into subdirectory
- changed = copy_common_dirs(os.path.join(src, item), os.path.join(dest, item), module) or changed
+ changed = changed or copy_common_dirs(os.path.join(src, item), os.path.join(dest, item), module)
return changed
@@ -624,7 +619,6 @@ def main():
if module.check_mode:
module.exit_json(msg='dest directory %s would be created' % dirname, changed=True, src=src)
os.makedirs(b_dirname)
- changed = True
directory_args = module.load_file_common_arguments(module.params)
directory_mode = module.params["directory_mode"]
if directory_mode is not None:
@@ -694,7 +688,7 @@ def main():
b_mysrc = b_src
if remote_src and os.path.isfile(b_src):
- dummy, b_mysrc = tempfile.mkstemp(dir=os.path.dirname(b_dest))
+ _, b_mysrc = tempfile.mkstemp(dir=os.path.dirname(b_dest))
shutil.copyfile(b_src, b_mysrc)
try:
@@ -757,6 +751,8 @@ def main():
except (IOError, OSError):
module.fail_json(msg="failed to copy: %s to %s" % (src, dest), traceback=traceback.format_exc())
changed = True
+ else:
+ changed = False
# If neither have checksums, both src and dest are directories.
if checksum_src is None and checksum_dest is None:
@@ -804,12 +800,13 @@ def main():
b_dest = to_bytes(os.path.join(b_dest, b_basename), errors='surrogate_or_strict')
if not module.check_mode and not os.path.exists(b_dest):
os.makedirs(b_dest)
- changed = True
b_src = to_bytes(os.path.join(module.params['src'], ""), errors='surrogate_or_strict')
diff_files_changed = copy_diff_files(b_src, b_dest, module)
left_only_changed = copy_left_only(b_src, b_dest, module)
common_dirs_changed = copy_common_dirs(b_src, b_dest, module)
owner_group_changed = chown_recursive(b_dest, module)
+ if diff_files_changed or left_only_changed or common_dirs_changed or owner_group_changed:
+ changed = True
if module.check_mode and not os.path.exists(b_dest):
changed = True