
    Vh]                    z   d dl mZ dZdZdZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dlZd dlZd dlZd dlmZ d dlmZ d dlmZmZmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dl m!Z! d dlm"Z"  ejF                  d      Z$ ejF                  d      Z% ejF                  d      Z& ejF                  d      Z' ejF                  d      Z( ejF                  d      Z) ejF                  d      Z* ejF                  d      Z+ ejF                  d      Z, ejF                  d      Z- ejF                  d      Z. ejF                  d      Z/d Z0d Z1 G d de2      Z3 G d d e4      Z5 G d! d"e4      Z6 G d# d$e6      Z7 G d% d&e6      Z8 G d' d(e6      Z9 G d) d*e6      Z: G d+ d,e5      Z;d- Z<d. Z=e>d/k(  r e=        yy)0    )annotationsa  
---
module: unarchive
version_added: '1.4'
short_description: Unpacks an archive after (optionally) copying it from the local machine
description:
     - The M(ansible.builtin.unarchive) module unpacks an archive. It will not unpack a compressed file that does not contain an archive.
     - By default, it will copy the source file from the local system to the target before unpacking.
     - Set O(remote_src=yes) to unpack an archive which already exists on the target.
     - If checksum validation is desired, use M(ansible.builtin.get_url) or M(ansible.builtin.uri) instead to fetch the file and set O(remote_src=yes).
     - For Windows targets, use the M(community.windows.win_unzip) module instead.
options:
  src:
    description:
      - If O(remote_src=no) (default), local path to archive file to copy to the target server; can be absolute or relative. If O(remote_src=yes), path on the
        target server to existing archive file to unpack.
      - If O(remote_src=yes) and O(src) contains V(://), the remote machine will download the file from the URL first. (version_added 2.0). This is only for
        simple cases, for full download support use the M(ansible.builtin.get_url) module.
    type: path
    required: true
  dest:
    description:
      - Remote absolute path where the archive should be unpacked.
      - The given path must exist. Base directory is not created by this module.
    type: path
    required: true
  copy:
    description:
      - If true, the file is copied from local controller to the managed (remote) node, otherwise, the plugin will look for src archive on the managed machine.
      - This option has been deprecated in favor of O(remote_src).
      - This option is mutually exclusive with O(remote_src).
    type: bool
    default: yes
  creates:
    description:
      - If the specified absolute path (file or directory) already exists, this step will B(not) be run.
      - The specified absolute path (file or directory) must be below the base path given with O(dest).
    type: path
    version_added: "1.6"
  io_buffer_size:
    description:
      - Size of the volatile memory buffer that is used for extracting files from the archive in bytes.
    type: int
    default: 65536
    version_added: "2.12"
  list_files:
    description:
      - If set to True, return the list of files that are contained in the tarball.
    type: bool
    default: no
    version_added: "2.0"
  exclude:
    description:
      - List the directory and file entries that you would like to exclude from the unarchive action.
      - Mutually exclusive with O(include).
    type: list
    default: []
    elements: str
    version_added: "2.1"
  include:
    description:
      - List of directory and file entries that you would like to extract from the archive. If O(include)
        is not empty, only files listed here will be extracted.
      - Mutually exclusive with O(exclude).
    type: list
    default: []
    elements: str
    version_added: "2.11"
  keep_newer:
    description:
      - Do not replace existing files that are newer than files from the archive.
    type: bool
    default: no
    version_added: "2.1"
  extra_opts:
    description:
      - Specify additional options by passing in an array.
      - Each space-separated command-line option should be a new element of the array. See examples.
      - Command-line options with multiple elements must use multiple lines in the array, one for each element.
    type: list
    elements: str
    default: []
    version_added: "2.1"
  remote_src:
    description:
      - Set to V(true) to indicate the archived file is already on the remote system and not local to the Ansible controller.
      - This option is mutually exclusive with O(copy).
    type: bool
    default: no
    version_added: "2.2"
  validate_certs:
    description:
      - This only applies if using a https URL as the source of the file.
      - This should only set to V(false) used on personally controlled sites using self-signed certificate.
      - Prior to 2.2 the code worked as if this was set to V(true).
    type: bool
    default: yes
    version_added: "2.2"
extends_documentation_fragment:
- action_common_attributes
- action_common_attributes.flow
- action_common_attributes.files
- decrypt
- files
attributes:
    action:
      support: full
    async:
      support: none
    bypass_host_loop:
      support: none
    check_mode:
      support: partial
      details: Not supported for gzipped tar files.
    diff_mode:
      support: partial
      details: Uses gtar's C(--diff) arg to calculate if changed or not. If this C(arg) is not supported, it will always unpack the archive.
    platform:
      platforms: posix
    safe_file_operations:
      support: none
    vault:
      support: full
todo:
    - Re-implement tar support using native tarfile module.
    - Re-implement zip support using native zipfile module.
notes:
    - Requires C(zipinfo) and C(gtar)/C(unzip) command on target host.
    - Requires C(zstd) command on target host to expand I(.tar.zst) files.
    - Can handle I(.zip) files using C(unzip) as well as I(.tar), I(.tar.gz), I(.tar.bz2), I(.tar.xz), and I(.tar.zst) files using C(gtar).
    - Does not handle I(.gz) files, I(.bz2) files, I(.xz), or I(.zst) files that do not contain a I(.tar) archive.
    - Existing files/directories in the destination which are not in the archive
      are not touched. This is the same behavior as a normal archive extraction.
    - Existing files/directories in the destination which are not in the archive
      are ignored for purposes of deciding if the archive should be unpacked or not.
seealso:
- module: community.general.archive
- module: community.general.iso_extract
- module: community.windows.win_unzip
author: Michael DeHaan
au  
- name: Extract foo.tgz into /var/lib/foo
  ansible.builtin.unarchive:
    src: foo.tgz
    dest: /var/lib/foo

- name: Unarchive a file that is already on the remote machine
  ansible.builtin.unarchive:
    src: /tmp/foo.zip
    dest: /usr/local/bin
    remote_src: yes

- name: Unarchive a file that needs to be downloaded (added in 2.0)
  ansible.builtin.unarchive:
    src: https://example.com/example.zip
    dest: /usr/local/bin
    remote_src: yes

- name: Unarchive a file with extra options
  ansible.builtin.unarchive:
    src: /tmp/foo.zip
    dest: /usr/local/bin
    extra_opts:
    - --transform
    - s/^xxx/yyy/
ab  
dest:
  description: Path to the destination directory.
  returned: always
  type: str
  sample: /opt/software
files:
  description: List of all the files in the archive.
  returned: When O(list_files) is V(True)
  type: list
  sample: '["file1", "file2"]'
gid:
  description: Numerical ID of the group that owns the destination directory.
  returned: always
  type: int
  sample: 1000
group:
  description: Name of the group that owns the destination directory.
  returned: always
  type: str
  sample: "librarians"
handler:
  description: Archive software handler used to extract and decompress the archive.
  returned: always
  type: str
  sample: "TgzArchive"
mode:
  description: String that represents the octal permissions of the destination directory.
  returned: always
  type: str
  sample: "0755"
owner:
  description: Name of the user that owns the destination directory.
  returned: always
  type: str
  sample: "paul"
size:
  description: The size of destination directory in bytes. Does not include the size of files or subdirectories contained within.
  returned: always
  type: int
  sample: 36
src:
  description:
    - The source archive's path.
    - If O(src) was a remote web URL, or from the local ansible controller, this shows the temporary location where the download was stored.
  returned: always
  type: str
  sample: "/home/paul/test.tar.gz"
state:
  description: State of the destination. Effectively always "directory".
  returned: always
  type: str
  sample: "directory"
uid:
  description: Numerical ID of the user that owns the destination directory.
  returned: always
  type: int
  sample: 1000
N)partial)ZipFile)to_bytes	to_nativeto_text)AnsibleModule)get_bin_path)get_best_parsable_locale)
fetch_file)quote)
BadZipFilez: Uid differs$z: Gid differs$z: Mode differs$z: Mod time differs$z4: : Warning: Cannot stat: No such file or directory$z2: Warning: Cannot stat: No such file or directory$z([r-][w-][SsTtx-]){3}z: Invalid ownerz: Invalid groupz: Symlink differs$z: Contents differ$z: Size differs$c                    t        j                  d      }t        | d      5 }t        t	        |j
                  |      d      D ]  }t        j                  ||      } 	 ddd       |dz  S # 1 sw Y   |dz  S xY w)z# Return a CRC32 checksum of a file     rbNl    )binasciicrc32openiterr   read)pathbuffer_sizecrcfb_blocks        I/home/dcms/DCMS/lib/python3.12/site-packages/ansible/modules/unarchive.pyr   r     sy     ..
C	dD	 /QGAFFK8#> 	/G..#.C	// / s   <A,,A9c                0    t        j                  dd|       S )z6 Quote meta-characters in the args for the unix shell z([^A-Za-z0-9_])z\\\1)resub)strings    r   shell_escaper!   $  s    66$gv66r   c                      e Zd Zy)UnarchiveErrorN)__name__
__module____qualname__ r   r   r#   r#   )  s    r   r#   c                  L    e Zd Zd Zd Zd Zd Zed        Zd Z	d Z
d Zd	 Zy
)
ZipArchivec                b   || _         || _        || _        |j                  d   | _        || _        |j                  d   | _        |j                  d   | _        g | _        | j
                  j                  d   | _	        d | _
        d | _        g | _        t               | _        d| _        d| _        y )N
extra_optsio_buffer_sizeexcludeinclude )unzipcmd_path)zipinfozipinfo_cmd_path)srcb_dest	file_argsparamsoptsmoduler,   excludesincludesinclude_filesr2   r4   _files_in_archivedict	_infodictzipinfoflagbinaries)selfr5   r6   r7   r:   s        r   __init__zZipArchive.__init__/  s    "MM,/	$mm,<=i0![[//	: $!#
r   c                    |ddd   }d}t        dd      D ]/  }t        dd      D ]  }||d|z  z      dv s|d|d|z  z   z  z  }  1 || z  S )zA Convert a Unix permission string (rw-r--r--) into a mode (0644) Nr      )rwxst   )range)rC   modestrumaskrevstrmodejis          r   _permstr_to_octalzZipArchive._permstr_to_octalC  sy    2q! 	-A1a[ -!a!e)$(AAA!a!e),,D-	- vr   c                   | j                   j                  | j                  d| j                  g      \  }}}|r3| j                   j	                  |       t        d| j                  z        |j                         dd D ]P  }|j                  d d      }| j                  j                  |d          t        |d         | j                  |d   <   R y )Nz-vz,Neither python zipfile nor unzip can read %srG         )r:   run_commandr2   r5   debugr#   
splitlinessplitr>   appendintr@   )rC   rcouterrlinefieldss         r   _legacy_file_listzZipArchive._legacy_file_listP  s    {{..tTXX/NOCKKc" !ORVRZRZ!Z[[NN$Qr* 	7DZZa(F""))&)4(+F1IDNN6!9%	7r   c                    | j                   r| j                   |   S 	 t        | j                        }	 |j                         D ].  }t	        |j
                        | j                   |j                  <   0 	 | j                   |   S # t        $ r |j                          t        d      w xY w# t        $ rH}|j                  d   j                         j                  d      r| j                          n Y d }~d }~ww xY w)Nz#Unable to list files in the archiver   bad magic number)r@   r   r5   infolistr_   CRCfilename	Exceptioncloser#   r   argslower
startswithre   )rC   r   archiveitemes        r   _crc32zZipArchive._crc32[  s    >>>>$''	Ldhh'GL#,,. BD47MDNN4==1B ~~d##	  L$%JKKL  	vvay ++,>? &&( )		s#   B, AB %B),	C=5>C88C=c                r   | j                   r| j                   S g | _         	 t        | j                        }	 |j                         D ]  }| j                  rM| j                  D ]=  }t        j
                  ||      s| j                   j                  t        |             ? \d}| j                  r+| j                  D ]  }t        j
                  ||      sd} n |r| j                   j                  t        |              	 |j                          | j                   S # t        $ r,}|j                          t        dt        |      z        d }~ww xY w# t        $ rS}|j                  d   j                         j                  d      r| j!                          n Y d }~| j                   S d }~ww xY w)NFT'Unable to list files in the archive: %sr   rg   )r>   r   r5   namelistr=   fnmatchr^   r   r;   rk   rl   r#   r   rm   rn   ro   re   )rC   rp   memberr.   exclude_flagr-   rr   s          r   files_in_archivezZipArchive.files_in_archiver  s   !!)))!#	dhh'G_%..0 MF))'+'9'9 QG&vw? $ 6 6 = =i>O PQ (-==+/== *#*??67#C37L$)*  , 2299)F:KLM$ MMO%%%  _$%NQZ[\Q]%]^^_/  	vvay ++,>? &&( )0 %%%9	sB   E AD" <AD" D" &D" "	E+'EE	F6#>F11F6c                   t        j                  d      }|j                  |      }d}|r`	 t        |j	                         d         dk  r|}n<t        |j	                         d         dkD  rd}nd |j	                         dz   D        }n|}t        j                  t        j                  |            S # t
        $ r |}Y 5w xY w)	z7 Return a valid time object from the given time string z.^(\d{4})(\d{2})(\d{2})\.(\d{2})(\d{2})(\d{2})$)	     r}   r   r   r   r   r   r   r   r|   ;  )	r~            ;   r   r   r   r   c              3  2   K   | ]  }t        |        y w)N)r_   ).0ms     r   	<genexpr>z/ZipArchive._valid_time_stamp.<locals>.<genexpr>  s      LAQ Ls   )r   r   r   )	r   compilematchr_   groups
ValueErrortimemktimestruct_time)rC   timestamp_strDT_REr   epoch_date_time	date_times         r   _valid_time_stampzZipArchive._valid_time_stamp  s    

LMM*8,u||~a()D0 /I*+d2 CI L)1K LI
 (I{{4++I677  ,+	,s   AB5 5CCc           
     j   | j                   r&| j                  | j                   dd| j                  g}n| j                  dd| j                  g}| j                  r|j	                  dg| j                  z          | j
                  r|j	                  | j
                         | j                  j                  |      \  }}}| j                  j                  |       |}d}d}|dk(  rd}nd}t        j                  d      }t        j                  |       t        j                         }	t        j                         }
t        j                         }t        j                         }	 t!        j"                  |      j$                  }	 t+        j,                  |      j.                  }d x}}| j4                  d   r<	 t!        j6                  | j4                  d         }|j$                  }|j:                  }n	 |}|}d x}}| j4                  d	   r<	 t+        j>                  | j4                  d	         }|j.                  }|j@                  }n	 |}|}|jC                         D ]  }d}|jE                  d d
      }tG        |      dk7  r'tG        |d         dvr8tG        |d         dk7  rJ|d   d   dvs tI        |d   dd        jK                  d      su|d   d   }|d   dd  }|d   }|d   }t9        |d         }tM        |d
   d      }|| j                  v r	|d|z  z  }|d   dk(  r|dk7  r|d|d|dz  }d}n|dk(  rd}n|dk(  rd }n|d!k(  rd }tG        |      dk(  r|d   dk(  rd"}n
|d#k(  rd"}nd$}|}n2tG        |      d
k(  r|d%k(  rd"}nd$}|}nd&|	jO                         v r|}nd}tG        |      d'k7  stP        jS                  |      stU        d(|z        t        jV                  jY                  | jZ                  t]        |d            } 	 t        j^                  |       }!dk(  rRte        jf                  |!jh                        s3d}| j`                  jc                  |       |d-|z  z  }|d.|d+|d,z  }"|d k(  rTte        jj                  |!jh                        s5d}d}| j`                  jc                  |       |d/|z  z  }|d.|d+|d,z  }{|dk(  rRte        jl                  |!jh                        s3d}| j`                  jc                  |       |d0|z  z  }|d.|d+|d,z  }to        d1|z        }"| jq                  |d         }#te        jj                  |!jh                        r| j                  jr                  d2   r|#|!jt                  kD  r+d}| j`                  jc                  |       |d3|z  z  }d4|"d5<   nte        jj                  |!jh                        rz|#|!jt                  k  rk|d6|z  z  }| j                  jc                  |       |#|!jt                  k7  r7d}| j`                  jc                  |       |d7||#|!jt                  fz  z  }d4|"d5<   te        jj                  |!jh                        r+||!jv                  k7  rd}|d8|||!jv                  fz  z  }d9|"d<   te        jj                  |!jh                        rKty        | | jz                        }$|$| j}                  |      k7  r!d}|d:|| j}                  |      |$fz  z  }d.|"d<   |dk7  r| j4                  d;   rHt        | j4                  d;   t8              r| j4                  d;   }%nE	 t9        | j4                  d;   d      }%n*|d!k(  r| j                  |d      }%n| j                  ||      }%%te        j                  |!jh                        k7  r/d}d>|"d?<   |d@||%te        j                  |!jh                        fz  z  }d x}'}(	 t!        j"                  |!j                        j$                  }'|dk7  r||k7  s||k7  rtU        dA|dB|dC|      |'r|'|k7  rd}|d|dD|'dE|dFz  }dG|"d<   n|(r|(|k7  rd}|d|dH|(dI|dFz  }dG|"d<   d x})}*	 t+        j,                  |!j                        j.                  })|dk7  r"||k7  s||k7  r||
vrtU        dJ|dB|dC|      |)r|)|k7  rd}|d|dK|)dL|dFz  }dM|"d<   n|*r|*|k7  rd}|d|dN|*dO|dFz  }dM|"d<   |s|| j`                  vr| j`                  jc                  |       |djY                  |"      dP|d,z  } | j`                  rd}t        ||||||Q      S # t&        t(        f$ r |}Y w xY w# t(        t0        t2        f$ r |}Y w xY w# t(        $ r` 	 t!        j"                  t9        | j4                  d               }n/# t&        t(        t0        f$ r t!        j"                  |      }Y nw xY wY .w xY w# t<        $ r Y "w xY w# t0        t(        f$ r` 	 t+        j,                  t9        | j4                  d	               }n/# t(        t0        t2        f$ r t+        j,                  |      }Y nw xY wY \w xY w# t<        $ r Y Pw xY w# t<        $ r5 d}| j`                  jc                  |       |d)|z  z  }|d*d+|d,z  }Y w xY w# t<        $ r}&	 t        j                  |!| j4                  d;         }%nR# t0        $ rF}&| j                  j                  |d<t        |&      z  t        j                         =       Y d }&~&nd }&~&ww xY wY d }&~&d }&~&ww xY w# t&        t(        f$ r |!j                  }(Y ww xY w# t(        t0        t2        f$ r |!j                  }*Y w xY w)RNz-Tz-s-xr/   r   TFownergrouprX      )rX   r   
   rY      zdl-?r}   zrwxstah-rM   rG   surrogate_or_stricterrorszPath %s is excluded on request
rF   /dzPath z incorrectly tagged as "z", but is a directory.
lL-r   ?	rwxrwxrwxzrwx---z	rw-rw-rw-zrwxa---bsd	   z"ZIP info perm format incorrect, %szPath %s is missing
>z
++++++.?? 
z/File %s already exists, but not as a directory
cz7Directory %s already exists, but not as a regular file
z2Directory %s already exists, but not as a symlink
z.%s.......??
keep_newerz!File %s is older, replacing file
rL      z!File %s is newer, excluding file
z$File %s differs in mtime (%f vs %f)
z#File %s differs in size (%d vs %d)
rK   z5File %s differs in CRC32 checksum (0x%08x vs 0x%08x)
rR   z%s)r   msg	exceptionp   z*Path %s differs in permissions (%o vs %o)
zCannot change ownership of  to z
, as user z is owned by user z, not by user z as expected
oz is owned by uid z, not by uid z!Cannot change group ownership of z is owned by group z, not by group gz is owned by gid z, not by gid  )
unarchivedr`   ra   rb   cmddiff)KrA   r4   r5   r;   extendr=   r:   rZ   r[   osrP   platformsystem	getgroupsgetuidgetgidpwdgetpwuidpw_name	TypeErrorKeyErrorgrpgetgrgidgr_namer   OverflowErrorr7   getpwnamr_   pw_uidrk   getgrnamgr_gidr\   r]   len	frozensetissubsetr   rn   ZIP_FILE_MODE_REr   r#   r   joinr6   r   lstatr<   r^   statS_ISDIRst_modeS_ISREGS_ISLNKlistr   r8   st_mtimest_sizer   r,   rs   
isinstancer	   _symbolic_mode_to_octal	fail_jsonr   	traceback
format_excrU   S_IMODEst_uidst_gidr?   )+rC   r   r`   ra   rb   old_outr   r   rP   
systemtyper   run_uidrun_gid	run_owner	run_group	fut_ownerfut_uidtpw	fut_groupfut_gidtgrrc   changepcsztypepermstrversionostypesizer   ftype
file_umaskr6   stitemized	timestampr   rR   rr   r   uidr   gids+                                              r   is_unarchivedzZipArchive.is_unarchived  ss   (($*:*:D$QC(($dhh?C==JJx$--/0JJt))*{{..s3C#7JJ 
__&
 ))+))+	 W-55I	 W-55I
 #"	G>>'"0ll4>>'#:; IjjG%	 G #"	G>>'"0ll4>>'#:; IjjG%	 G&&( a	>DF**T1%C3x1} 3q6{*,3q6{b  1vay&iAqr
.C.L.LZ.XF1IE!fQRjG!fGVFs1v;D3q6*?@D t}}$9D@@ Bx3C<Z^`effC### 7|q 8s?)G()G)G"
W"i')G)G"
***,,"

 7|q (8(>(>w(G$%IG%STT
 WW\\$++xEZ/[\FXXf% |DLL$<$$T*IDPPud;;|DLL$<"
$$T*QTXXXud;;|DLL$<$$T*LtSSud;;NU23H
 ..s1v6I ||BJJ';;%%l3 2;;.!%,,T2CdJJ&)bjj1i"++6MCdJJ,,T2  BKK/!%,,T2F$PY[][f[fIggg&) ||BJJ'DBJJ,>=tRZZ@XXX! ||BJJ'FD$7$78$++d++!FSW[]a]h]him]npsVtttC"%HQK
 | >>&)!$.."8#>#~~f5|#&t~~f'=q#AD c\11'1=D11':FD4<<

33!F"%HQKHDRVX\XdXdegeoeoXpKqqqC EC RYY/77
 !|i!77g;M$Z^`ikt%uvv)+VZ\aclmm!TXZ]_fgg! EC RYY/77 !|i!77g;MSZbhSh$`dfoqz%{||)+X\^cenoo!TXZ]_fgg! t}},MM((.RWWX%6==Ca	>F ==J
 zbcsRVWWq 8$ 	 I	  *m4 	 I	   00,,s4>>'+B'CDC!8Z8 0,,w/C00   ) 00 ,,s4>>'+B'CDC *m< 0,,w/C00  n  $$T*-44ud;;f  ) ||'4'L'LRQUQ_Q_`fQg'h#- | $ 5 54TIVWLEXdmdxdxdz 5 { {||( x(  ii ( j-8  ii s&  $e* f 7"f 3h "h j jk*)m,6)n*e?>e?ff	h)+gh)h>h hhh	hhj
++ij
)j j
jj
	j
	jj:kk	m)(#lm$	m<mm$mm$$m),n
n n21n2c                   | j                   dg}| j                  r|j                  | j                         |j                  | j                         | j
                  r|j                  dg| j
                  z          | j                  r|j                  | j                         |j                  d| j                  g       | j                  j                  |      \  }}}t        ||||      S )Nz-or   z-dr   r`   ra   rb   )r2   r9   r   r^   r5   r;   r=   r6   r:   rZ   r?   )rC   r   r`   ra   rb   s        r   	unarchivezZipArchive.unarchive  s    }}d#99JJtyy!

488
 ==JJv-.JJt))*

D$++&'{{..s3C55r   c           	        g }| j                   D ]  }	 t        | |d   t        |d                ! |r#ddj                  dj                  |            fS | j                  d| j                  g}| j                  j                  |      \  }}}|dk(  ry| j                  j                  |       dd	| j                  d
|fS # t        $ r |j	                  |d          Y w xY w)Nr}   r   Fz7Unable to find required '{missing}' binary in the path.z' or ')missingz-lTN	Command "" could not handle archive: )rB   setattrr
   r   r^   formatr   r2   r5   r:   rZ   r[   )rC   r   br   r`   ra   rb   s          r   can_handle_archivezZipArchive.can_handle_archive  s     	%A%adL1$67	% SZZckcpcpqxcyZzzz}}dDHH-{{..s3C7#T]]TWXXX  %qt$%s   CC#"C#N)r$   r%   r&   rD   rU   re   rs   propertyrz   r   r   r   r  r'   r   r   r)   r)   -  sC    
(	7$. #& #&J8*yXv	6"Yr   r)   c                  :    e Zd Zd Zd Zed        Zd Zd Zd Z	y)
TgzArchivec                   || _         || _        || _        |j                  d   | _        || _        | j
                  j                  r4| j
                  j                  dd| j
                  j                  z         | j
                  j                  d   D cg c]  }|j                  d       c}| _
        | j
                  j                  d   | _        d | _        d | _        d| _        g | _        y c c}w )	Nr+   Tz>remote module (%s) does not support check mode when using gtar)skippedr   r-   r   r.   z-z)r5   r6   r7   r8   r9   r:   
check_mode	exit_json_namerstripr;   r=   r2   tar_typezipflagr>   )rC   r5   r6   r7   r:   r   s         r   rD   zTgzArchive.__init__  s    "MM,/	;;!!KK!!$4tw{  xC  xC  xI  xI  5I!  J6:kk6H6H6STdS)T![[//	:!# Us   C1c                    | j                   dg}| j                  j                  |      \  }}}d }|j                  d      rd}|S |j                  d      rd|v rd}|S )Nz	--versionbsdtarr   tarGNUgnu)r2   r:   rZ   ro   )rC   r   r`   ra   rb   r  s         r   _get_tar_typezTgzArchive._get_tar_type  se    }}k*005S#>>(#H  ^^E"u|Hr   c           
     t   | j                   r| j                   S | j                  dd| j                  g}| j                  r|j	                  | j                         | j
                  r|j                  dg| j
                  z          | j                  r,|j                  | j                  D cg c]  }d|z   	 c}       |j                  d| j                  g       | j                  r|j                  | j                         t        | j                        }| j                  j                  || j                  t        ||||            \  }}}|dk7  r)| j                  j                  |       t        d	|z        |j!                         D ]  }t#        t%        j&                  |      d         }|j)                  d
      r|dd  }d}| j                  r+| j                  D ]  }	t+        j*                  ||	      sd} n |rv| j                   j	                  t#        |              | j                   S c c}w )Nz--list-C--show-transformed-names
--exclude=-fLANGLC_ALLLC_MESSAGESLANGUAGEcwdenviron_updater   ru   r   r}   FT)r>   r2   r6   r  r^   r9   r   r;   r5   r=   r   r:   rZ   r?   r[   r#   r\   r   codecsescape_decodero   rw   )
rC   r   r   localer`   ra   rb   rj   ry   r-   s
             r   rz   zTgzArchive.files_in_archive)  s   !!)))}}hdkk:<<JJt||$99JJ23dii?@==JJ$--@Qq(@A

D$((#$JJt))*)$++6{{..sTX^dms  BH  SY  UZ.  [C7KKc" !JS!PQQ( 	CH !!5!5h!?!BCH
 ""3'#AB< L}}#}} Gx9'+
  &&--i.AB'	C* %%%A As   *H5c           
     ,   | j                   dd| j                  g}| j                  r|j                  | j                         | j                  r|j                  dg| j                  z          | j                  d   r*|j                  dt        | j                  d         z          | j                  d   r*|j                  dt        | j                  d         z          | j                  j                  d   r|j                  d	       | j                  r,|j                  | j                  D cg c]  }d
|z   	 c}       |j                  d| j                  g       | j                  r|j                  | j                         t        | j                        }| j                  j                  || j                  t        ||||            \  }}}d}|}d}t!        j"                         }	|j%                         |j%                         z   D ]  }
t&        j)                  |
      r|	dk(  r,| j                  d   st*        j)                  |
      r||
dz   z  }|	dk(  r,| j                  d   st,        j)                  |
      r||
dz   z  }| j                  d   st.        j)                  |
      r||
dz   z  }t0        t2        t4        t6        t8        t:        t<        g}|D ]  }|j)                  |
      s||
dz   z  }  |rd}t        |||||      S c c}w )Nz--diffr  r  r   --owner=r   --group=r   --keep-newer-filesr  r  r  r"  Tr/   r   r   rR   F)r   r`   ra   rb   r   )r2   r6   r  r^   r9   r   r7   r   r:   r8   r;   r5   r=   r   rZ   r?   r   r   r\   EMPTY_FILE_REsearchOWNER_DIFF_REGROUP_DIFF_REMODE_DIFF_REMOD_TIME_DIFF_REMISSING_FILE_REINVALID_OWNER_REINVALID_GROUP_RESYMLINK_DIFF_RECONTENT_DIFF_RESIZE_DIFF_RE)rC   r   r   r'  r`   ra   rb   r   r   r   rc   differ_regexesregexs                r   r   zTgzArchive.is_unarchivedV  s   }}hdkk:<<JJt||$99JJ23dii?@>>'"JJzE$..*A$BBC>>'"JJzE$..*A$BBC;;l+JJ+,==JJ$--@Qq(@A

D$((#$JJt))*)$++6{{..sTX^dms  BH  SY  UZ.  [C 
))+ &&(3>>+;; 	'D ##D)!|DNN7$;@T@TUY@Ztd{"!|DNN7$;@T@TUY@Ztd{">>&)l.A.A$.Gtd{" /3C /?N
 ( '<<%4$;&C'!	'( JzbcsLLQ As   .Lc           
        | j                   dd| j                  g}| j                  r|j                  | j                         | j                  r|j                  dg| j                  z          | j                  d   r*|j                  dt        | j                  d         z          | j                  d   r*|j                  dt        | j                  d         z          | j                  j                  d   r|j                  d	       | j                  r,|j                  | j                  D cg c]  }d
|z   	 c}       |j                  d| j                  g       | j                  r|j                  | j                         t        | j                        }| j                  j                  || j                  t        ||||            \  }}}t        ||||      S c c}w )Nz	--extractr  r  r   r)  r   r*  r   r+  r  r  r  r"  r   )r2   r6   r  r^   r9   r   r7   r   r:   r8   r;   r5   r=   r   rZ   r?   )rC   r   r   r'  r`   ra   rb   s          r   r   zTgzArchive.unarchive  s   }}k4=<<JJt||$99JJ23dii?@>>'"JJzE$..*A$BBC>>'"JJzE$..*A$BBC;;l+JJ+,==JJ$--@Qq(@A

D$((#$JJt))*)$++6{{..sTX^dms  BH  SY  UZ.  [C55 As   .G"c                   	 t        d      | _        | j                         | _        | j                  dk7  rdd| j                  d| j                  dfS 	 | j
                  ry		 dd| j                  z  fS # t        $ r% 	 t        d      | _        n# t        $ r Y Y yw xY wY w xY w# t        $ r'}dd| j                  d
t        |      fcY d }~S d }~ww xY w)Ngtarr  )Fz:Unable to find required 'gtar' or 'tar' binary in the pathr  Fr  z" detected as tar type z. GNU tar required.r   r  zNCommand "%s" found no files in archive. Empty archive files are not supported.)r
   r2   r   r  r  rz   r#   r   )rC   rr   s     r   r  zTgzArchive.can_handle_archive  s    	[(0DM **,==E!W[WdWdfjfsfsttt	f$$! % fimivivvvv'  	[[ ,U 3 [Z[ 	[  	fXabcXdeee	fsS   A5 B& 5	B#?BB#	BB#BB#"B#&	C/CCCN)
r$   r%   r&   rD   r  r  rz   r   r   r  r'   r   r   r	  r	    s3    $ *& *&X5Mn6*wr   r	  c                       e Zd Z fdZ xZS )
TarArchivec                @    t         t        |   ||||       d| _        y )Nr/   )superr>  rD   r  rC   r5   r6   r7   r:   	__class__s        r   rD   zTarArchive.__init__  s    j$(fiHr   r$   r%   r&   rD   __classcell__rB  s   @r   r>  r>    s     r   r>  c                       e Zd Z fdZ xZS )TarBzipArchivec                @    t         t        |   ||||       d| _        y )Nz-j)r@  rG  rD   r  rA  s        r   rD   zTarBzipArchive.__init__  s    nd,S&)VLr   rC  rE  s   @r   rG  rG         r   rG  c                       e Zd Z fdZ xZS )TarXzArchivec                @    t         t        |   ||||       d| _        y )Nz-J)r@  rK  rD   r  rA  s        r   rD   zTarXzArchive.__init__  s    lD*3	6Jr   rC  rE  s   @r   rK  rK    rI  r   rK  c                       e Zd Z fdZ xZS )TarZstdArchivec                @    t         t        |   ||||       d| _        y )Nz--use-compress-program=zstd)r@  rN  rD   r  rA  s        r   rD   zTarZstdArchive.__init__  s!    nd,S&)VL 5r   rC  rE  s   @r   rN  rN    s    5 5r   rN  c                  (     e Zd Z fdZ fdZ xZS )ZipZArchivec                N    t         t        |   ||||       d| _        d| _        y )Nz-Zl)r0   )r1   r4   )r@  rQ  rD   rA   rB   rA  s        r   rD   zZipZArchive.__init__  s)    k4)#vy&I 
r   c                    t         t        |          \  }}|s||fS | j                  | j                  g}| j
                  j                  |      \  }}}d|j                         v rydd|z  fS )Nr3   r   Fz/Command "unzip -Z" could not handle archive: %s)r@  rQ  r  r4   rA   r:   rZ   rn   )rC   unzip_available	error_msgr   r`   ra   rb   rB  s          r   r  zZipZArchive.can_handle_archive  sy    %*;%P%R""I-- $$d&6&67{{..s3C		#G#MMMr   )r$   r%   r&   rD   r  rD  rE  s   @r   rQ  rQ    s    
N Nr   rQ  c                ,   t         t        t        t        t        t
        t        g}t               }|D ]7  } || |||      }|j                         \  }}	|r|c S |j                  |	       9 dj                  |      }
|j                  d| d|
       y )Nr   zFailed to find handler for "zD". Make sure the required command to extract the file is installed.
r   )r)   rQ  r	  r>  rG  rK  rN  setr  addr   r   )r5   destr7   r:   handlersreasonshandlerobj
can_handlereason
reason_msgs              r   pick_handlerrb    s    KZQ]_mnHeG c4F3"557VJF 7#J
  EH  JT  U  Vr   c                 Z
   t        t        t        dd      t        dd      t        dd      t        d      t        dd      t        dd      t        dd	g 
      t        dd	g 
      t        dd	g 
      t        dd      t        dd      t        dd      t        dd            dddg      } | j                  d   }| j                  d   }t        j                  j                  |      }t        |d      }t        j                  j                  |      s"| j                  dj                  ||             | j                  d   }| j                  | j                        }t        j                  j                  |      s>|s| j                  d|z         n&d|v rt        | |      }n| j                  d|z         t        j                  |t        j                        s| j                  d|z         t        j                  j                  |      }	 t        j                  j!                  |      dk(  r| j                  d|z         t        j                  j'                  |      s| j                  d |z         t)        ||||       }t        |j*                  j,                  ||!      }	|j/                         }
| j0                  r
|
d"    |	d#<   nI|
d"   rd|	d#<   n>	 |j3                         |	d$<   |	d$   d%   dk7  r | j                  d0d&d'|d(|i|	 d|	d#<   |
j7                  d)d      r
d*|
d)   i|	d)<   |	j7                  d)d      r| j0                  sg }|j8                  D ]z  }t        j                  j;                  |t        |d            |d<   	 | j=                  ||	d#   d+      |	d#<   d-|v sQ|jA                  d-      d   }||vsj|jC                  |       | |r,|D ]'  }|d-||d<   	 | j=                  ||	d#   d+      |	d#<   ) | j                  d.   r|j8                  |	d/<    | jD                  d0i |	 y # t"        $ r,}| j                  d|dt%        |             Y d }~'d }~ww xY w# t4        $ r  | j                  d0d&d'|d(|i|	 Y w xY w# t4        t>        f$ r+} | j                  d0d&d,t%        |      z  i|	 Y d }~'d }~ww xY w# t4        t>        f$ r+} | j                  d0d&d,t%        |      z  i|	 Y d }~/d }~ww xY w)1Nr   T)typerequiredboolF)rd  default)rd  r   str)rd  elementsrg  r_   i   )r5   rZ  
remote_srccreates
list_filesr   r-   r.   r+   validate_certsr,   copydecrypt)r.   r-   )argument_specadd_file_common_argssupports_check_modemutually_exclusiver5   rZ  r   r   zNRelative destination path '{dest}' was resolved to absolute path '{abs_dest}'.)rZ  abs_destrj  zSource '%s' failed to transferrW  z://zSource '%s' does not existzSource '%s' not readabler   z)Invalid archive '%s', the file is 0 byteszSource 'z' not readable, z#Destination '%s' is not a directory)r]  rZ  r5   r   changedextract_resultsr`   r   zfailed to unpack r   r   prepared)expandz1Unexpected error when accessing exploded file: %sr   rl  filesr'   )#r	   r?   r8   r   r   abspathr   isabswarnr  load_file_common_argumentsexistsr   r   accessR_OKgetsizerk   r   isdirrb  rB  r$   r   r  r   IOErrorgetrz   r   set_fs_attributes_if_differentOSErrorr]   r^   r  )r:   r5   rZ  rt  r6   rj  r7   rr   r]  res_argscheck_resultstop_foldersrj   top_folder_pathr   s                  r   mainr    s(   &406D17f%77fubAfubA%DVT:UI>
 640fd3#
& " 231F6 --
C== Dwwt$Hh'<=F77==dkkqu  AIk  J  	K|,J11&--@I 77>>#!AC!GHc\VS)C!=!CD99S"''"7#=> ''//#
CS77??31$!Ls!RS
 77== BTIJ3	6:GG--66TsKH ))+M
 "/"==	|	$#	'*1*;*;*=H&')*40A5   [C%N[RZ[ #'HY '&f(=> ||FD!&*;*;00 	8H "VXhOd5e fIfu&,&K&KIW_`iWjsx&K&y# h"*.."5a"8"+5&&7	8   y/3Q$7	&!y*0*O*OPY[cdm[nw|*O*}HY'y }}\"#44F x E  SsIaLQRRS6  	XFWT!JWhW	X$ W% u   t%X[def[g%gtksttu  ) y$F$$x)\_hij_k)kxowxxysZ   #7Q 08R	 'R3S0	R!RR	#R0/R03S- S((S-0T*? T%%T*__main__)?
__future__r   DOCUMENTATIONEXAMPLESRETURNr   r%  rw   r   r   r   r   r   r   r   r   	functoolsr   zipfiler   +ansible.module_utils.common.text.convertersr   r   r   ansible.module_utils.basicr	   #ansible.module_utils.common.processr
   "ansible.module_utils.common.localer   ansible.module_utils.urlsr   shlexr   r   r   r.  r/  r0  r1  r,  r2  r   r3  r4  r5  r6  r7  r   r!   rk   r#   objectr)   r	  r>  rG  rK  rN  rQ  rb  r  r$   r'   r   r   <module>r     s   #L\6:
x    
 	  
 	      T T 4 < G 0   

,-

,-rzz,-2::45 

RS"**RS2::67 2::01 2::01 "**23"**23rzz,-7
	Y 	^Y ^YBkw kw^ Z : 	5Z 	5N* N2
V|!~ zF r   