Add example of templating inline using copy module (#19752)

* Add example of templating inline using copy module

The **copy** module documentation implies that `content:` only works
for 'simple values' and for complex stuff you need the **template**
module, but that is an understatement. You can use **copy** to template
anything you desire.

So I changed the wording, added an example, and also added a note
to the template module that the **copy** module could be used for
'inline templating'.

This fixes #19741.
This commit is contained in:
Dag Wieers 2017-07-23 07:12:31 +02:00 committed by Toshio Kuratomi
parent 4e8b28e404
commit be1c517f4d
3 changed files with 75 additions and 70 deletions

View file

@ -22,12 +22,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.0',
'status': ['stableinterface'],
'supported_by': 'core'}
DOCUMENTATION = '''
DOCUMENTATION = r'''
---
module: copy
version_added: "historical"
short_description: Copies files to remote locations.
short_description: Copies files to remote locations
description:
- The C(copy) module copies a file from the local or remote machine to a location on the remote machine.
Use the M(fetch) module to copy files from remote locations to the local box.
@ -41,69 +40,58 @@ options:
with "/", only inside contents of that directory are copied to destination.
Otherwise, if it does not end with "/", the directory itself with all contents
is copied. This behavior is similar to Rsync.
required: false
default: null
aliases: []
content:
version_added: "1.1"
description:
- When used instead of 'src', sets the contents of a file directly to the specified value.
This is for simple values, for anything complex or with formatting please switch to the template module.
required: false
default: null
For anything advanced or with formatting also look at the template module.
version_added: "1.1"
dest:
description:
- Remote absolute path where the file should be copied to. If src is a directory,
- Remote absolute path where the file should be copied to. If C(src) is a directory,
this must be a directory too.
required: true
default: null
required: yes
backup:
description:
- Create a backup file including the timestamp information so you can get
the original file back if you somehow clobbered it incorrectly.
type: bool
default: 'no'
version_added: "0.7"
required: false
choices: [ "yes", "no" ]
default: "no"
force:
description:
- the default is C(yes), which will replace the remote file when contents
are different than the source. If C(no), the file will only be transferred
if the destination does not exist.
version_added: "1.1"
required: false
choices: [ "yes", "no" ]
default: "yes"
type: bool
default: 'yes'
aliases: [ "thirsty" ]
version_added: "1.1"
directory_mode:
description:
- 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.
required: false
version_added: "1.5"
remote_src:
description:
- If False, it will search for src at originating/master machine, if True it will go to the remote/target machine for the src. Default is False.
- Currently remote_src does not support recursive copying.
choices: [ "True", "False" ]
required: false
default: "False"
- If C(no), it will search for src at originating/master machine.
- If C(yes), it will go to the remote/target machine for the src. Default is False.
- Currently C(remote_src) does not support recursive copying.
type: bool
default: 'no'
version_added: "2.0"
follow:
required: false
default: "no"
choices: [ "yes", "no" ]
description:
- This flag indicates that filesystem links in the destination, if they exist, should be followed.
type: bool
default: 'no'
version_added: "1.8"
description:
- 'This flag indicates that filesystem links in the destination, if they exist, should be followed.'
local_follow:
required: false
default: "yes"
choices: [ "yes", "no" ]
version_added: "2.4"
description:
- 'This flag indicates that filesystem links in the source tree, if they exist, should be followed.'
- This flag indicates that filesystem links in the source tree, if they exist, should be followed.
type: bool
default: 'yes'
version_added: "2.4"
extends_documentation_fragment:
- files
- validate
@ -117,7 +105,7 @@ notes:
- For Windows targets, use the M(win_copy) module instead.
'''
EXAMPLES = '''
EXAMPLES = r'''
# Example from Ansible Playbooks
- copy:
src: /srv/myfiles/foo.conf
@ -132,7 +120,7 @@ EXAMPLES = '''
dest: /etc/foo.conf
owner: foo
group: foo
mode: "u=rw,g=r,o=r"
mode: u=rw,g=r,o=r
# Another symbolic mode example, adding some permissions and removing others
- copy:
@ -140,7 +128,7 @@ EXAMPLES = '''
dest: /etc/foo.conf
owner: foo
group: foo
mode: "u+rw,g-wx,o-rwx"
mode: u+rw,g-wx,o-rwx
# Copy a new "ntp.conf file into place, backing up the original if it differs from the copied version
- copy:
@ -155,41 +143,57 @@ EXAMPLES = '''
- copy:
src: /mine/sudoers
dest: /etc/sudoers
validate: 'visudo -cf %s'
validate: visudo -cf %s
# Copy a "sudoers" file on the remote machine for editing
- copy:
remote_src: true
src: /etc/sudoers
dest: /etc/sudoers.edit
remote_src: yes
validate: visudo -cf %s
# Create a CSV file from your complete inventory using an inline template
- hosts: all
tasks:
- copy:
content: |
HOSTNAME;IPADDRESS;FQDN;OSNAME;OSVERSION;PROCESSOR;ARCHITECTURE;MEMORY;
{% for host in hostvars %}
{% set vars = hostvars[host|string] %}
{{ vars.ansible_hostname }};{{ vars.remote_host }};{{ vars.ansible_fqdn }};{{ vars.ansible_distribution }};{{ vars.ansible_distribution_version }};{{ vars.ansible_processor[1] }};{{ vars.ansible_architecture }};{{ (vars.ansible_memtotal_mb/1024)|round|int }}; # NOQA
{% endfor %}
dest: /some/path/systems.csv
backup: yes
run_once: yes
delegate_to: localhost
'''
RETURN = '''
RETURN = r'''
dest:
description: destination file/path
returned: success
type: string
sample: "/path/to/file.txt"
sample: /path/to/file.txt
src:
description: source file used for the copy on the target machine
returned: changed
type: string
sample: "/home/httpd/.ansible/tmp/ansible-tmp-1423796390.97-147729857856000/source"
sample: /home/httpd/.ansible/tmp/ansible-tmp-1423796390.97-147729857856000/source
md5sum:
description: md5 checksum of the file after running copy
returned: when supported
type: string
sample: "2a5aeecc61dc98c4d780b14b330e3282"
sample: 2a5aeecc61dc98c4d780b14b330e3282
checksum:
description: sha1 checksum of the file after running copy
returned: success
type: string
sample: "6e642bb8dd5c2e027bf21dd923337cbb4214f827"
sample: 6e642bb8dd5c2e027bf21dd923337cbb4214f827
backup_file:
description: name of backup file created
returned: changed and if backup=yes
type: string
sample: "/path/to/file.txt.2015-02-12@22:09~"
sample: /path/to/file.txt.2015-02-12@22:09~
gid:
description: group id of the file, after execution
returned: success
@ -199,12 +203,12 @@ group:
description: group of the file, after execution
returned: success
type: string
sample: "httpd"
sample: httpd
owner:
description: owner of the file, after execution
returned: success
type: string
sample: "httpd"
sample: httpd
uid:
description: owner id of the file, after execution
returned: success
@ -214,7 +218,7 @@ mode:
description: permissions of the target, after execution
returned: success
type: string
sample: "0644"
sample: 0644
size:
description: size of the target, after execution
returned: success
@ -224,7 +228,7 @@ state:
description: state of the target, after execution
returned: success
type: string
sample: "file"
sample: file
'''
import os
@ -271,16 +275,16 @@ def main():
module = AnsibleModule(
# not checking because of daisy chain to file module
argument_spec=dict(
src = dict(required=False, type='path'),
original_basename = dict(required=False), # used to handle 'dest is a directory' via template, a slight hack
content = dict(required=False, no_log=True),
dest = dict(required=True, type='path'),
backup = dict(default=False, type='bool'),
force = dict(default=True, aliases=['thirsty'], type='bool'),
validate = dict(required=False, type='str'),
directory_mode = dict(required=False, type='raw'),
remote_src = dict(required=False, type='bool'),
local_follow = dict(required=False, type='bool'),
src=dict(type='path'),
original_basename=dict(type='str'), # used to handle 'dest is a directory' via template, a slight hack
content=dict(type='str', no_log=True),
dest=dict(type='path', required=True),
backup=dict(type='bool', default=False),
force=dict(type='bool', default=True, aliases=['thirsty']),
validate=dict(type='str'),
directory_mode=dict(type='raw'),
remote_src=dict(type='bool'),
local_follow=dict(type='bool'),
),
add_file_common_args=True,
supports_check_mode=True,

View file

@ -19,12 +19,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.0',
'status': ['stableinterface'],
'supported_by': 'core'}
DOCUMENTATION = r'''
---
module: template
version_added: historical
short_description: Templates a file out to a remote server.
short_description: Templates a file out to a remote server
description:
- Templates are processed by the Jinja2 templating language
(U(http://jinja.pocoo.org/docs/)) - documentation on the template
@ -51,8 +50,8 @@ options:
description:
- Create a backup file including the timestamp information so you can get
the original file back if you somehow clobbered it incorrectly.
choices: [ "yes", "no" ]
default: "no"
type: bool
default: 'no'
newline_sequence:
description:
- Specify the newline sequence to use for templating files.
@ -82,15 +81,16 @@ options:
trim_blocks:
description:
- If this is set to True the first newline after a block is removed (block, not variable tag!).
default: "no"
type: bool
default: 'no'
version_added: '2.4'
force:
description:
- the default is C(yes), which will replace the remote file when contents
are different than the source. If C(no), the file will only be transferred
if the destination does not exist.
choices: [ "yes", "no" ]
default: "yes"
type: bool
default: 'yes'
notes:
- For Windows you can use M(win_template) which uses '\r\n' as C(newline_sequence).
- Including a string that uses a date in the template will result in the template being marked 'changed' each time
@ -100,6 +100,8 @@ notes:
which changes the variable interpolation markers to [% var %] instead of {{ var }}.
This is the best way to prevent evaluation of things that look like, but should not be Jinja2.
raw/endraw in Jinja2 will not work as you expect because templates in Ansible are recursively evaluated."
- You can use the C(copy) module with the C(content:) option if you prefer the template inline,
as part of the playbook.
author:
- Ansible Core Team
- Michael DeHaan

View file

@ -230,7 +230,6 @@ lib/ansible/modules/files/acl.py
lib/ansible/modules/files/archive.py
lib/ansible/modules/files/assemble.py
lib/ansible/modules/files/blockinfile.py
lib/ansible/modules/files/copy.py
lib/ansible/modules/files/ini_file.py
lib/ansible/modules/files/iso_extract.py
lib/ansible/modules/files/replace.py