diff --git a/lib/ansible/modules/files/copy.py b/lib/ansible/modules/files/copy.py index 586aa71a61..c2b652dda8 100644 --- a/lib/ansible/modules/files/copy.py +++ b/lib/ansible/modules/files/copy.py @@ -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 @@ -270,17 +274,17 @@ 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'), + argument_spec=dict( + 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, diff --git a/lib/ansible/modules/files/template.py b/lib/ansible/modules/files/template.py index be24d6a3b9..b159beb01b 100644 --- a/lib/ansible/modules/files/template.py +++ b/lib/ansible/modules/files/template.py @@ -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 diff --git a/test/sanity/pep8/legacy-files.txt b/test/sanity/pep8/legacy-files.txt index 3df38c839b..9c82c4e196 100644 --- a/test/sanity/pep8/legacy-files.txt +++ b/test/sanity/pep8/legacy-files.txt @@ -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