a ì)g‹ã@s$ddlmZmZmZeZdZdZdZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlZddlZddlmZmZddlmZddlmZdd lmZdd lmZdaGd d „d e ƒZ!d d„Z"dd„Z#dd„Z$dd„Z%dd„Z&dd„Z'dd„Z(dd„Z)e*dkr e)ƒdS)é)Úabsolute_importÚdivisionÚprint_functionaj --- module: copy version_added: historical short_description: Copy 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(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 in the C(content) field will result in unpredictable output. - For Windows targets, use the M(ansible.windows.win_copy) module instead. options: src: description: - Local path to a file to copy to the remote server. - This can be absolute or relative. - If path is a directory, it is copied recursively. In this case, if path ends 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 the C(rsync) command line tool. type: path content: description: - 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 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: 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' force: description: - Influence whether the remote file must always be replaced. - 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' mode: description: - 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 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, 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 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: - 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 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' follow: description: - This flag indicates that filesystem links in the destination, if they exist, should be followed. type: bool default: no version_added: '1.8' local_follow: description: - This flag indicates that filesystem links in the source tree, if they exist, should be followed. type: bool default: yes version_added: '2.4' checksum: description: - SHA1 checksum of the file being transferred. - Used to validate that the copy of the file was successful. - If this is not provided, ansible will use the local calculated checksum of the src file. type: str version_added: '2.5' extends_documentation_fragment: - decrypt - files - validate - action_common_attributes - action_common_attributes.files - action_common_attributes.flow notes: - The M(ansible.builtin.copy) module recursively copy facility does not scale to lots (>hundreds) of files. seealso: - module: ansible.builtin.assemble - module: ansible.builtin.fetch - module: ansible.builtin.file - module: ansible.builtin.template - module: ansible.posix.synchronize - module: ansible.windows.win_copy author: - Ansible Core Team - Michael DeHaan attributes: action: support: full async: support: none bypass_host_loop: support: none check_mode: support: full diff_mode: support: full platform: platforms: posix safe_file_operations: support: full vault: support: full version_added: '2.2' aõ - name: Copy file with owner and permissions ansible.builtin.copy: src: /srv/myfiles/foo.conf dest: /etc/foo.conf owner: foo group: foo mode: '0644' - name: Copy file with owner and permission, using symbolic representation ansible.builtin.copy: src: /srv/myfiles/foo.conf dest: /etc/foo.conf owner: foo group: foo mode: u=rw,g=r,o=r - name: Another symbolic mode example, adding some permissions and removing others ansible.builtin.copy: src: /srv/myfiles/foo.conf dest: /etc/foo.conf owner: foo group: foo mode: u+rw,g-wx,o-rwx - name: Copy a new "ntp.conf" file into place, backing up the original if it differs from the copied version ansible.builtin.copy: src: /mine/ntp.conf dest: /etc/ntp.conf owner: root group: root mode: '0644' backup: yes - name: Copy a new "sudoers" file into place, after passing validation with visudo ansible.builtin.copy: src: /mine/sudoers dest: /etc/sudoers validate: /usr/sbin/visudo -csf %s - name: Copy a "sudoers" file on the remote machine for editing ansible.builtin.copy: src: /etc/sudoers dest: /etc/sudoers.edit remote_src: yes validate: /usr/sbin/visudo -csf %s - name: Copy using inline content ansible.builtin.copy: content: '# This file was moved to /etc/other.conf' dest: /etc/mine.conf - name: If follow=yes, /path/to/file will be overwritten by contents of foo.conf ansible.builtin.copy: src: /etc/foo.conf dest: /path/to/link # link to /path/to/file follow: yes - name: If follow=no, /path/to/link will become a file and be overwritten by contents of foo.conf ansible.builtin.copy: src: /etc/foo.conf dest: /path/to/link # link to /path/to/file follow: no a; dest: description: Destination file/path. returned: success type: str sample: /path/to/file.txt src: description: Source file used for the copy on the target machine. returned: changed type: str 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: str sample: 2a5aeecc61dc98c4d780b14b330e3282 checksum: description: SHA1 checksum of the file after running copy. returned: success type: str sample: 6e642bb8dd5c2e027bf21dd923337cbb4214f827 backup_file: description: Name of backup file created. returned: changed and if backup=yes type: str sample: /path/to/file.txt.2015-02-12@22:09~ gid: description: Group id of the file, after execution. returned: success type: int sample: 100 group: description: Group of the file, after execution. returned: success type: str sample: httpd owner: description: Owner of the file, after execution. returned: success type: str sample: httpd uid: description: Owner id of the file, after execution. returned: success type: int sample: 100 mode: description: Permissions of the target, after execution. returned: success type: str sample: "0644" size: description: Size of the target, after execution. returned: success type: int sample: 1220 state: description: State of the target, after execution. returned: success type: str sample: file N)Úto_bytesÚ to_native)Ú AnsibleModule)Ú get_bin_path)Úget_best_parsable_locale)ÚPY3c@seZdZdd„ZdS)ÚAnsibleModuleErrorcCs ||_dS)N©Úresults)Úselfr ©rú8/usr/lib/python3.9/site-packages/ansible/modules/copy.pyÚ__init__4szAnsibleModuleError.__init__N)Ú__name__Ú __module__Ú __qualname__rrrrrr 3sr cCsjtdƒ}|d|g}dd„|Dƒ}ttƒ}tj|t|||dd\}}}|dkrftd d  |¡||¡ƒ‚dS) NÚsetfaclz-bcSsg|] }t|ƒ‘qSr)r)Ú.0ÚxrrrÚ @ózclear_facls..)ÚLANGÚLC_ALLÚ LC_MESSAGES)Zenviron_updaterz1Error running "{0}": stdout: "{1}"; stderr: "{2}"ú )rr ÚmoduleÚ run_commandÚdictÚ RuntimeErrorÚformatÚjoin)ÚpathrZ acl_commandZ b_acl_commandÚlocaleÚrcÚoutÚerrrrrÚ clear_facls<s r)cCsztj |¡\}}t|dd}|dkr.d|gfStj |¡s^|dkrPtddid‚t|ƒ\}}n ||gfS| |¡||fS) zi Return the first pre-existing directory and a list of the new directories that will be created. Úsurrogate_or_strict©ÚerrorsÚÚ.ú/Úmsgz0The '/' directory doesn't exist on this machine.r )Úosr$ÚsplitrÚexistsr Úsplit_pre_existing_dirÚappend)ÚdirnameÚheadÚtailZb_headÚpre_existing_dirÚnew_directory_listrrrr4Gs     r4cCs@|r.csg|]}tj ˆ|¡‘qSrrB©rÚfrErrrurcsg|]}tj ˆ|¡‘qSrrBrCrErrrrcsg|]}tj ˆ|¡‘qSrrBrGrErrrƒrcsg|]}tj ˆ|¡‘qSrrBrCrErrrrcsg|]}tj ˆ|¡‘qSrrBrGrErrr‘rcsg|]}tj ˆ|¡‘qSrrBrCrErrr›rcsg|]}tj ˆ|¡‘qSrrBrGrErrrŸr)ÚparamsÚ check_moder1ÚwalkÚset_owner_if_differentÚpwdÚgetpwnamÚpw_uidÚstatÚst_uidÚset_group_if_differentÚgrpÚgetgrnamÚgr_gidÚst_gid) r$rr?r@rAÚdirnamesÚ filenamesZ owner_changedÚdirÚfileÚuidZ group_changedÚgidrrErÚchown_recursivefst                 r]cCsød}|jd}|jd}|jd}t ||¡j}t|ƒr| | |d¡|d urV| | |d¡tj  | ¡r’tj | ¡r’|dur’t | ¡} t | | ¡tj  | ¡sötj | ¡röt  | | ¡t  | | ¡|d urÞ| | |d¡|d urö| | |d¡tj  | ¡s.tj  | ¡r.t j | | | dt| |ƒd}qH|S) zFCopy files that exist in `src` directory only to the `dest` directory.Fr@rAr^Tr*r+©ÚsymlinksN)rIr_r`Ú left_onlyrbrJr1r$r#rrcÚisdirrfÚcopytreer]rdreÚisfilergrLrRrh)rirjrr?r@rAr^rtrkrlrmrnrorprrrÚcopy_left_onlyÆsP           &   &       rxc Csœd}t ||¡j}|D]€}tj ||¡}tj ||¡}t|dd}t|dd} t|| |ƒ} t|| |ƒ} | sn| rrd}|p”t tj ||¡tj ||¡|ƒ}q|S)NFr*r+T) r_r`Ú common_dirsr1r$r#rrqrxÚcopy_common_dirs) rirjrr?ryrkrlrmrnroÚdiff_files_changedÚleft_only_changedrrrrzûs    &rzc)CsÔ tttddtddtdddtdddtddd tddd tddtd dtddtddtddtddd d ddd atjd }t|dd}tjd}tjj|vr¸d tjj|¡}t|dd}tjd}tjd}tj  dd¡}tj  dd¡}tjd}tjd} tjd} tjd} tjd} tjd} tjd}tj  |¡sXtj d|dt  |tj ¡sxtj d|dtjdd kr¤d!t t |¡j¡tjd<tjd} d}d}d}d}tj |¡r>zt |¡}Wn<ttfy}zt d"t|ƒ¡WYd}~n d}~00zt |¡}Wnty:Yn0n&| rdtj |¡sdt  d#t|ƒ¡|r„||kr„tj d$||d%| tj¡r¢|r¦tj ||¡}t|dd}tj |¡}t|dd}tj  |¡s¢zt|ƒ\}}WnPty8}z6|jd&d' |¡7<tj fi|j ¤ŽWYd}~n d}~00tj!rVtj"d(|d|d)t #|¡t $tj¡}tjd*}|durŠ||d<nd|d<t%||t||ƒtj |¡ràtj &|¡}|rÆ|}tj ||¡}t|dd}tj  |¡r\tj '|¡r|rtj (|¡}t|dd}|s2tj"d+||dd,t  |tj ¡ròtj |¡ròt |¡}n–tj  tj |¡¡sòzt tj |¡¡WnPtyØ}z6d-t|ƒ )¡vrÄtj d.tj |¡dWYd}~n d}~00tj d/tj |¡dt  tj |¡tj*¡s.tjd0s.tj d1tj |¡dd}||ksJtj '|¡r tj!sz’|rttj  |¡rtt +|¡}tj '|¡ršt ,|¡t-|d2ƒ .¡|r2| dur¸t /|| d¡| durÐt 0|| d¡| durèt 1|| d¡d3|vrtj d4|dt 2||¡\}}}|d5kr2tj d6|||d7|}| rÖtj |¡rÖt3j4tj |¡d8\} }t5 6||¡zt5 7||¡WnVtyÔ}z<|j8t8j9kr¾| d kr¾t d9 t|ƒ¡¡n‚WYd}~n d}~00t:r&t;td:ƒr&zd;t <|¡v}!Wn*t=y$}zd}!WYd}~n d}~00tj>||tjd0d<t:rät;td:ƒrät? @¡d=krä| sä|!räz tA|ƒWnnty¬}zd>t|ƒvr–n‚WYd}~n@d}~0tByâ}zd?t|ƒvrÌn‚WYd}~n d}~00Wn2ttfytj d@||ftC D¡dAYn0d}nd}|du r||du r|| r|tj tjd ¡ r|ttjd dd}ttjddd}| tjj¡rätj tjd¡rätE||tƒ}"tF||tƒ}#tG||tƒ}$tH|tƒ}%|"sà|#sà|$sà|%räd}| tjj¡ rvtj  tjd¡ svttj &|¡dd}&ttj ||&¡dd}ttj tjd dB¡dd}tj! sht5jI||| dCtH|tƒd}| tjj¡ sˆtj tjd¡ rˆttj &|¡dd}&ttj ||&¡dd}ttj tjd dB¡dd}tj! stj  |¡ st5jI||| dCd}tH|tƒtj! r0tj  |¡ s0d}tj  |¡ rˆtE||tƒ}"tF||tƒ}#tG||tƒ}$tH|tƒ}%|" s„|# s„|$ s„|% rˆd}| tjj¡ s|tj  tjd¡ s|ttj &tjd ¡dd}&ttj ||&¡dd}tj! sbtj  |¡ sbt #|¡ttj tjd dB¡dd}tE||tƒ}"tF||tƒ}#tG||tƒ}$tH|tƒ}%|" s^|# s^|$ s^|% rbd}tj! r|tj  |¡ s|d}t|||||dD}'| rœ||'dE<tj$tj|dF}(t J|(|'dG¡|'dG<tj"fi|'¤ŽdS)HNr$)ÚtypeÚstrT)r}Zno_log)r}ÚrequiredÚboolF)r}ÚdefaultÚraw) riÚ_original_basenameZcontentrjÚbackupÚforceÚvalidateÚdirectory_modeÚ remote_srcr^ÚchecksumÚfollow)Z argument_specZadd_file_common_argsZsupports_check_moderir*r+rjz.{0}{1}r„r…rƒr†rŠr^Úmoder@rArˆr‰zSource %s not found)r0zSource %s not readableZpreservez0%03oz5Unable to calculate src checksum, assuming change: %sz+Cannot copy invalid source '%s': not a filezBCopied file does not match the expected checksum. Transfer failed.)r0r‰Zexpected_checksumr0z Could not copy to {0}z"dest directory %s would be created)r0r?rir‡zfile already exists)r0rirjr?zpermission deniedz*Destination directory %s is not accessiblez'Destination directory %s does not existÚ unsafe_writeszDestination %s not writableÚwz%szvalidate must contain %%s: %srzfailed to validate)r0Ú exit_statusÚstdoutÚstderr)rYzUnable to copy stats {0}Ú listxattrzsystem.posix_acl_access)rŒZLinuxrzOperation not supportedzfailed to copy: %s to %s)r0Ú tracebackr-rr)rjriZmd5sumr‰r?Ú backup_file)r$r?)Krr rrIrr1r$Úsepr"Úgetr3Z fail_jsonÚaccessÚR_OKrPÚS_IMODEÚst_moderwZsha1ÚOSErrorÚIOErrorÚwarnrZmd5Ú ValueErrorruÚendswithr#r6r4r Úresultr rJZ exit_jsonÚmakedirsZload_file_common_argumentsr=ÚbasenamercÚrealpathÚlowerÚW_OKZ backup_localÚunlinkÚopenÚcloseZset_mode_if_differentrLrRrÚtempfileZmkstemprfrgÚcopystatÚerrnoZENOSYSr Úhasattrr‘Ú ExceptionZ atomic_moveÚplatformÚsystemr)r!r’Ú format_excrqrxrzr]rvr<))riZb_srcrjZb_destr„r…rƒr†rŠr^r‹r@rArˆr‰r?Z checksum_destZ checksum_srcZ md5sum_srcÚer6Z b_dirnamer9r:r>r‡r¡r“r&r'r(Zb_mysrcÚ_Z src_has_aclsr{r|Zcommon_dirs_changedZowner_group_changedZ b_basenameZres_argsZ file_argsrrrÚmain s¶     ôï               (ý   (          .$        &  $    $ $     $      ÿr²Ú__main__)+Z __future__rrrr}Z __metaclass__Z DOCUMENTATIONZEXAMPLESZRETURNrªr_rSr1Zos.pathr­rMrfrPr¨r’Zansible.module_utils._textrrZansible.module_utils.basicrZ#ansible.module_utils.common.processrZ"ansible.module_utils.common.localer Zansible.module_utils.sixr rr¬r r)r4r=r]rqrxrzr²rrrrrÚsFA?       A5.