
    [t                        S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKrSSKJr  SSKJr  SSKJr  SS	KJr  SSKrSSKrSS
KJr  SSKr " S S\5      r " S S\R2                  " \R4                  \5      5      r " S S\5      r " S S\5      r " S S\5      r\" 5       \l         S r! " S S\5      r" " S S\5      r#S r$Sr%S r&g)zEThis package provides DockerImage for examining docker_build outputs.    )absolute_import)division)print_functionN)docker_creds)docker_name)docker_digest)docker_http)zipc                       \ rS rSrSrSrg)DigestMismatchedError&   z7Exception raised when a digest mismatch is encountered. N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       >lib/third_party/containerregistry/client/v2_2/docker_image_.pyr   r   &   s    ?r   r   c                       \ rS rSrSrS rS rS rS rS r	S r
S	 r\R                  S
 5       r\R                  S 5       rS r\R                  S 5       rS rS rS rS rS r\R                  S 5       r\R                  S 5       rS rSrg)DockerImage*   z?Interface for implementations that interact with Docker images.c                     [         R                  " U R                  5       5      n[        US   5       Vs/ s H  o"S   PM	     sn$ s  snf )zEThe ordered collection of filesystem layers that comprise this image.layersdigest)jsonloadsmanifestreversed)selfr   xs      r   	fs_layersDockerImage.fs_layers-   s<    zz$--/*H!)(8*<!=>!=AhK!=>>>s   Ac                     [         R                  " U R                  5       5      n[        [	        UR                  S0 5      R                  S/ 5      5      5      $ )zBThe ordered list of uncompressed layer hashes (matches fs_layers).rootfsdiff_ids)r   r   config_filelistr    get)r!   cfgs     r   r'   DockerImage.diff_ids2   sA    
**T%%'
(C2.22:rBCDDr   c                 Z    [         R                  " U R                  5       5      nUS   S   $ )Nconfigr   )r   r   r   r!   r   s     r   config_blobDockerImage.config_blob7   s&    zz$--/*HHh''r   c                 X    [        U R                  5       U R                  5       /-   5      $ )z>The unique set of blobs that compose to create the filesystem.)setr#   r0   r!   s    r   blob_setDockerImage.blob_set;   s%    t~~4#3#3#5"6677r   c                 
   [         R                  " U R                  5       5      n[        US   5       Vs1 s H!  nUS   [        R
                  ;  d  M  US   iM#     nnUR                  U R                  5       5        U$ s  snf )z0The unique set of blobs which are distributable.r   	mediaTyper   )r   r   r   r    r	   NON_DISTRIBUTABLE_LAYER_MIMESaddr0   )r!   r   r"   distributable_blobss       r   distributable_blob_set"DockerImage.distributable_blob_set?   s~    zz$--/*H (8,--A[>!J!JJ 	(-  
 D,,./s   B 	B c                 h    [         R                  " U R                  5       R                  S5      5      $ )The digest of the manifest.utf8)r   SHA256r   encoder4   s    r   r   DockerImage.digestJ   s$     6 6v >??r   c                     [         R                  " U R                  5       5      nUR                  S[        R
                  5      $ )zThe media type of the manifest.r8   )r   r   r   r*   r	   OCI_MANIFEST_MIMEr/   s     r   
media_typeDockerImage.media_typeN   s-    zz$--/*H<<[%B%BCCr   c                     g)zRThe JSON manifest referenced by the tag/digest.

Returns:
  The raw json manifest
Nr   r4   s    r   r   DockerImage.manifestU       r   c                     g)z&The raw blob bytes of the config file.Nr   r4   s    r   r(   DockerImage.config_file_   rJ   r   c                 6    [        U R                  U5      5      $ )The byte size of the raw blob.)lenblobr!   r   s     r   	blob_sizeDockerImage.blob_sized   s    tyy !!r   c                     g)zThe raw blob of the layer.

Args:
  digest: the 'algo:digest' of the layer being addressed.

Returns:
  The raw blob bytes of the layer.
Nr   rQ   s     r   rP   DockerImage.blobi   rJ   r   c                     U R                  U5      n[        R                  " U5      n[        R                  " SUS9nUR                  5       nU$ )z Same as blob() but uncompressed.rbmodefileobj)rP   ioBytesIOgzipGzipFileread)r!   r   zippedbuffunzippeds         r   uncompressed_blobDockerImage.uncompressed_blobu   s>    YYvF
**V
C4-AvvxHOr   c                     [         R                  R                  U R                  5       U R	                  5       5       H  u  p#X1:X  d  M  Us  $    [        SU-  5      e)NUnmatched "diff_id": "%s"sixmovesr
   r#   r'   
ValueError)r!   diff_idthis_digestthis_diff_ids       r   _diff_id_to_digestDockerImage._diff_id_to_digest}   sO    '*yy}}T^^5E59]]_(F#		 (F 07:
;;r   c                     [         R                  R                  U R                  5       U R	                  5       5       H  u  p#X!:X  d  M  Us  $    [        SU-  5      e)NzUnmatched "digest": "%s"rh   )r!   r   rm   rn   s       r   digest_to_diff_idDockerImage.digest_to_diff_id   sO    '*yy}}T^^5E59]]_(F#		(F /&8
99r   c                 B    U R                  U R                  U5      5      $ )zLike `blob()`, but accepts the `diff_id` instead.

The `diff_id` is the name for the digest of the uncompressed layer.

Args:
  diff_id: the 'algo:digest' of the layer being addressed.

Returns:
  The raw compressed blob bytes of the layer.
)rP   ro   r!   rl   s     r   layerDockerImage.layer   s     99T,,W566r   c                 B    U R                  U R                  U5      5      $ )z!Same as layer() but uncompressed.)rd   ro   ru   s     r   uncompressed_layerDockerImage.uncompressed_layer   s    !!$"9"9'"BCCr   c                     g)zOpen the image for reading.Nr   r4   s    r   	__enter__DockerImage.__enter__   rJ   r   c                     g)zClose the image.Nr   r!   unused_typeunused_valueunused_tracebacks       r   __exit__DockerImage.__exit__   rJ   r   c                 *    [        [        U 5      5      $ )z-A human-readable representation of the image.)strtyper4   s    r   __str__DockerImage.__str__   s    tDz?r   r   N)r   r   r   r   r   r#   r'   r0   r5   r<   r   rF   abcabstractmethodr   r(   rR   rP   rd   ro   rr   rv   ry   r|   r   r   r   r   r   r   r   r   *   s    G?
E
(8	@D   1 1"
  <:7D
 & &  r   r   c                   z   ^  \ rS rSrSrU 4S jrS rS rS rS r	S r
S	 rS
 rS rS rS rS rS rS rSrU =r$ )Delegate   z'Forwards calls to the underlying image.c                 .   > [         TU ]  5         Xl        g)zWConstructor.

Args:
  image: a DockerImage on which __enter__ has already been called.
N)super__init___image)r!   image	__class__s     r   r   Delegate.__init__   s     
GKr   c                 6    U R                   R                  5       $ 	Override.)r   r   r4   s    r   r   Delegate.manifest       ;;!!r   c                 6    U R                   R                  5       $ r   )r   rF   r4   s    r   rF   Delegate.media_type   s    ;;!!##r   c                 6    U R                   R                  5       $ r   )r   r'   r4   s    r   r'   Delegate.diff_ids   r   r   c                 6    U R                   R                  5       $ r   )r   r#   r4   s    r   r#   Delegate.fs_layers   s    ;;  ""r   c                 6    U R                   R                  5       $ r   )r   r0   r4   s    r   r0   Delegate.config_blob       ;;""$$r   c                 6    U R                   R                  5       $ r   )r   r5   r4   s    r   r5   Delegate.blob_set   r   r   c                 6    U R                   R                  5       $ r   )r   r(   r4   s    r   r(   Delegate.config_file   r   r   c                 8    U R                   R                  U5      $ r   )r   rR   rQ   s     r   rR   Delegate.blob_size   s    ;;  ((r   c                 8    U R                   R                  U5      $ r   )r   rP   rQ   s     r   rP   Delegate.blob   s    ;;F##r   c                 8    U R                   R                  U5      $ r   )r   rd   rQ   s     r   rd   Delegate.uncompressed_blob   s    ;;((00r   c                 8    U R                   R                  U5      $ r   )r   rv   ru   s     r   rv   Delegate.layer   s    ;;W%%r   c                 8    U R                   R                  U5      $ r   )r   ry   ru   s     r   ry   Delegate.uncompressed_layer   s    ;;))'22r   c                 ,    [        U R                  5      $ r   )r   r   r4   s    r   r   Delegate.__str__   s    t{{r   )r   )r   r   r   r   r   r   r   rF   r'   r#   r0   r5   r(   rR   rP   rd   rv   ry   r   r   __classcell__r   s   @r   r   r      sQ    /"$"#%"%)$1&3 r   r   c                      ^  \ rS rSrSr\R                  4U 4S jjr  SS jrS r	S r
S rS rS	 rS
 rU 4S jrSS jrS rS rS rSS jrS rS rS rSrU =r$ )FromRegistry   z>This accesses a docker image hosted on a registry (non-local).c                 `   > [         TU ]  5         Xl        X l        X0l        X@l        0 U l        g N)r   r   _name_creds_original_transport_accepted_mimes	_response)r!   namebasic_creds	transportaccepted_mimesr   s        r   r   FromRegistry.__init__   s-    
 
GJK()DNr   c                    [        U R                  [        R                  5      (       a$  SR	                  U R                  R
                  US9nXR                  ;   a  U R                  U   $ U R                  R                  SR	                  [        R                  " U R                  R                  5      U R                  R                  US9[        R                  R                  R                  /US9u  pEU(       a  XPR                  U'   U$ )z=Fetches content of the resources from registry by http calls.{repository}/{suffix}
repositorysuffix!{scheme}://{registry}/v2/{suffix}schemeregistryr   )accepted_codesr   )
isinstancer   r   
Repositoryformatr   r   
_transportRequestr	   Schemer   ri   rj   http_clientOK)r!   r   r   cache_contents         r   _contentFromRegistry._content   s    
 $**k4455&--ZZ**6 . ;f ^^F##((+22%%djj&9&9:ZZ(( 	3 	 		--001% ) 'JA &nnVNr   c                     [         R                  " U R                  S5      R                  S5      5      nSU;  a%  [        R
                  " SR                  U5      5      eUR                  S5      $ )Nztags/list?check_usage_only=truer@   usagez2Malformed JSON response: {}. Missing "usage" field)r   r   r   decoder	   BadStateExceptionr   r*   )r!   responses     r   check_usage_onlyFromRegistry.check_usage_only  sf     zz78??GH h))
>
E
Eh
O  <<  r   c                 j    [         R                  " U R                  S5      R                  S5      5      $ )Nz	tags/listr@   )r   r   r   r   r4   s    r   _tagsFromRegistry._tags  s'     ::dmmK077?@@r   c                 B    U R                  5       R                  S/ 5      $ )Ntags)r   r*   r4   s    r   r   FromRegistry.tags"  s    ::<FB''r   c                 <    U R                  5       nSU;  a  0 $ US   $ )Nr   r   r!   payloads     r   	manifestsFromRegistry.manifests%  s%    jjlG i:r   c                 <    U R                  5       nSU;  a  / $ US   $ )Nchildr   r   s     r   childrenFromRegistry.children,  s%    jjlGgi7r   c                 b    [         R                  " U R                  SS95      nUS   S:H  =(       a)    SU;   =(       a    U R                  5       U R                  ;   $ ! [
        R                   a=  nUR                  [        R                  R                  R                  :X  a   S nAge S nAff = f)NF)validateschemaVersion   r   )r   r   r   rF   r   r	   V2DiagnosticExceptionstatusri   rj   r   	NOT_FOUND)r!   r   errs      r   existsFromRegistry.exists3  s    DMM5M9:h'1, 8X1E 8oo4#7#779,, 	syy,,66	6s   AA B.12B)(B))B.c                    > [        U R                  [        R                  5      (       a  U R                  R                  $ [
        TU ]  5       $ )r?   )r   r   r   Digestr   r   )r!   r   s    r   r   FromRegistry.digest=  s7    $**k0011ZZ7>r   c                 r   [        U R                  [        R                  5      (       aC  SU R                  R                  -   nU R                  X R                  5      R                  S5      $ [        U R                  [        R                  5      (       d   eU R                  SU R                  R                  -   U R                  5      n[        R                  " U5      nU(       a@  X@R                  R                  :w  a'  [        SU R                  R                  < SU< 35      eUR                  S5      $ )r   z
manifests/r@   z?The returned manifest's digest did not match requested digest,  vs. )r   r   r   Tagtagr   r   r   r   r   r   rA   r   )r!   r   pathccomputeds        r   r   FromRegistry.manifestC  s     $**koo..DJJNN*d]]4!5!56==fEE

K$6$67777
--tzz'8'88$:N:N
Oa%%a(h	h**"3"33#::,,h89 	9 XXfr   c                 ^    U R                  U R                  5       5      R                  S5      $ r   r@   )rP   r0   r   r4   s    r   r(   FromRegistry.config_fileT  s%    99T%%'(//77r   c                    SU-   n[        U R                  [        R                  5      (       a$  SR	                  U R                  R
                  US9nU R                  R                  SR	                  [        R                  " U R                  R                  5      U R                  R                  US9S[        R                  R                  R                  /S9u  p4[        US   5      $ )	rN   blobs/r   r   r   r   HEAD)methodr   zcontent-length)r   r   r   r   r   r   r   r   r	   r   r   ri   rj   r   r   int)r!   r   r   respunused_contents        r   rR   FromRegistry.blob_sizeX  s    F$**k4455&--ZZ**6 . ;f  ??22+22%%djj&9&9:ZZ(( 	3 	 		--001 3 3D t$%&&r   c                     U R                  SU-   SS9n[        R                  " U5      nX:w  a  [        SU< SU(       a  UOS< 35      eU$ )r   r  F)r   zAThe returned content's digest did not match its content-address, r  z(content was empty))r   r   rA   r   )r!   r   r  r  s       r   rP   FromRegistry.blobj  sZ     	h'u5A##A&H!Q4I!IKL L Hr   c              #   B  #    [        U R                  [        R                  5      (       a  [	        S5      eSR                  [        R                  " U R                  R                  5      U R                  R                  US9nU R                  R                  U[        R                  R                  R                  /S9 HY  u  p4[        R                   " UR#                  S5      5      nSU;  a  [        R$                  " SU-  5      eUS    H  nUv   M	     M[     g 7f)Nz(Expected docker_name.Registry for "name"z/{scheme}://{registry}/v2/_catalog?n={page_size})r   r   	page_size)r   r@   repositorieszMalformed JSON response: %s)r   r   r   r   rk   r   r	   r   r   r   PaginatedRequestri   rj   r   r   r   r   r   r   )r!   r  urlr   r   wrapper_objectrepos          r   catalogFromRegistry.catalogu  s     $**k4455ABB
;
B
B!!$**"5"56$$ C C
 oo66SYY22556 7 8
zz'.."89n	~	-++)G35 	5 !0$
 18s   DDc                     [         R                  " U R                  U R                  U R                  [         R
                  5      U l        U $ r   )r	   	Transportr   r   r   PULLr   r4   s    r   r|   FromRegistry.__enter__  s9    !++

DKK!9!9;;K;KMDO Kr   c                     g r   r   r   s       r   r   FromRegistry.__exit__      r   c                 J    SR                  [        U R                  5      5      $ )Nz$<docker_image.FromRegistry name: {}>)r   r   r   r4   s    r   r   FromRegistry.__str__  s    188TZZIIr   )r   r   r   r   r   r   )NT)T)d   )r   r   r   r   r   r	   MANIFEST_SCHEMA2_MIMESr   r   r   r   r   r   r   r   r   r   r(   rR   rP   r  r|   r   r   r   r   r   s   @r   r   r      sv    F !, B B	
 !%.
!A
("8'$	.	J Jr   r   c                       \ rS rSrS rSrg)	_FakeTimei  c                     g)NgEDAr   r4   s    r   time_FakeTime.time  s    r   r   N)r   r   r   r   r,  r   r   r   r   r*  r*    s    r   r*  c                     U SS S:H  $ )Nr   r   s   r   )r   s    r   is_compressedr/    s    	ak	!!r   c                   ~   ^  \ rS rSrSr  SU 4S jjr  SS jrS rS rS r	S r
S	 rS
 rS rS rS rS rSrU =r$ )FromTarballi  zAThis decodes the image tarball output of docker_build for upload.c                    > [         TU ]  5         Xl        X0l        0 U l        [
        R                  " 5       U l        X l        S U l	        S U l
        S U l        g r   )r   r   _tarball_compresslevel_memoize	threadingLock_lockr   	_manifest_blob_names_config_blob)r!   tarballr   compresslevelr   s       r   r   FromTarball.__init__  sL     
GM'DM!DJJDNDDr   c                 >   U(       a@  U R                      X4U R                  ;   a  U R                  X4   sSSS5        $  SSS5        [        R                  " U R                  SS9 n UR                  [        U5      5      nUR                  5       nU(       ax  [        U5      (       dh  [        R                  " 5       n[        R                  " SU R                  US9n UR                  U5        UR!                  5         UR#                  5       nORU(       dK  [        U5      (       a;  [        R                  " U5      n[        R                  " SUS9n	U	R                  5       nU(       a$  U R                      X`R                  X4'   SSS5        UsSSS5        $ ! , (       d  f       GNa= f! [         a/    UR                  [        SU-   5      5      R                  5       n GNQf = f! UR!                  5         f = f! , (       d  f       N|= f! , (       d  f       g= f)	z6Fetches a particular path's contents from the tarball.Nr)r   rY   z./wb)rY   r=  rZ   rW   rX   )r8  r5  tarfileopenr3  extractfiler   r_   KeyErrorr/  r[   r\   r]   r^   r4  writeclosegetvalue)
r!   r   memoizeshould_be_compressedtarrb   r   ra   r`   raws
             r   r   FromTarball._content  s    ::'4==8;< :8  
4==s	3s% OOCI&&&(
 
mG&<&<jjlT%8%8#G	
,,w

,,.,,. $g(>(>jj!mms3((*	ZZ8?--4
5 = 
4	3 :  %//t"df 	% ,,. Z9 
4	3sm   !F'H)*F,AH G(1BH7G=	H
F),5G%!H$G%%H(G::H=
H	H
Hc                 $    U R                  USSS9$ )z1Returns the result of _content with gzip applied.FTrI  rJ  )r   )r!   r   s     r   _gzipped_contentFromTarball._gzipped_content  s    ==u4=HHr   c                    [         R                  " U R                  5       R                  S5      5      n[        R
                  SU[        R                  [        U R                  5       5      S./ S.n0 n[        R                  " U R                  5       5      nUS   S   n[        U R                  5       H  u  pgSnXV   n	[        R                  n
Sn/ nXR                  ;   a\  U R                  U	   S	   nU R                  U	   S
   n
U R                  U	   S   nSU R                  U	   ;   a  U R                  U	   S   nO2U R                  U5      n[         R                  " U5      n[        U5      nXsU'   UU
US.nU(       a  XS'   US   R                  U5        M     U R                      X l        X0l        Xl        SSS5        g! , (       d  f       g= f)z.Populates self._manifest and self._blob_names.r@   r   )r   r8   size)r8   r   r.   r   r&   r'   Nr   r   r8   rS  urlsr   )r   rA   r(   rB   r	   MANIFEST_SCHEMA2_MIMECONFIG_JSON_MIMErO   r   r   	enumerate_layers
LAYER_MIME_layer_sourcesrP  appendr8  r9  r:  r;  )r!   r0   r   
blob_namesr.   r'   irv   r   rl   rF   rS  rT  r   layer_manifests                  r   _populate_manifest_and_blobs(FromTarball._populate_manifest_and_blobs  s   &&t'7'7'9'@'@'HIK 66!$55((*+


H JZZ((*+Fh
+Hdll+dg))jdd	''	'""7+H5((1+>
""7+F3T((11$$W-f5$''.##G,7| !n 
!%vx/= ,@ 
n#% 
s   *G
Gc                     U R                   (       d  U R                  5         [        R                  " U R                   SS9$ )r   T	sort_keys)r9  r_  r   dumpsr4   s    r   r   FromTarball.manifest/  s*    >>
'')::dnn55r   c                 V    U R                  U R                  5      R                  S5      $ r	  )r   _config_filer   r4   s    r   r(   FromTarball.config_file5  s"    ==**+226::r   c                     U R                   (       d  U R                  5         U R                   c   eU R                  U R                   U   SSS9$ )r   FrO  )r:  r_  r   rQ   s     r   rd   FromTarball.uncompressed_blob:  sS    
'')'''== "  $ $r   c                     U R                   (       d  U R                  5         XR                  :X  a  U R                  5       R	                  S5      $ U R                   c   eU R                  U R                   U   5      $ r	  )r:  r_  r;  r(   rB   rP  rQ   s     r   rP   FromTarball.blobE  sp    
'')"""&&v..'''   " "r   c                     [        [        U R                  5      U R                  5       5       H  u  p#X:X  d  M  U R	                  USSS9s  $    [        SU-  5      e)r   FrO  rg   )r
   r    rX  r'   r   rk   )r!   rl   rv   rn   s       r   ry   FromTarball.uncompressed_layerP  sT    !$Xdll%;T]]_!M		 }}UE}NN "N 07:
;;r   c                    U R                  SSS9n[        R                  " UR                  S5      5      n[	        U5      S:w  a  [        S5      e[        R                  " U5       HO  u  p4[	        U5      S:w  a  [        S5      e[        R                  " U5       H  u  pVSR                  X5S	9s  s  $    MQ     [        S
5      e)zEResolve the singleton tag this tarball contains using legacy methods.r  F)rI  r@      zUTarball must contain a single repository, or a name must be specified to FromTarball.zNTarball must contain a single tag, or a name must be specified to FromTarball.z{repository}:{tag})r   r  unreachable)
r   r   r   r   rO   rk   ri   	iteritemsr   	Exception)r!   
repo_bytesr  r  r   r  unused_layers          r   _resolve_tagFromTarball._resolve_tagW  s    ~u=J::j//78L
<A E F F l3	Ta G H 	H!$t!4
3#**d*DD "5	 4 M
""r   c                 N   U R                  S5      R                  S5      n[        R                  " U5      nS n/ n/ n[	        U5      S:w  a&  U R
                  (       d  U R                  5       U l        U H|  nU R
                  (       a3  [        U R
                  5      UR                  S5      =(       d    / ;   d  MG  UR                  S5      nUR                  S/ 5      nUR                  S0 5      nM~     U(       d  [        SU R
                  -  5      eX0l
        X@l        XPl        U $ )	Nzmanifest.jsonr@   rp  RepoTagsConfigLayersLayerSourcesz&Unable to find %s in provided tarball.)r   r   r   r   rO   r   rv  r   r*   rk   rg  rX  rZ  )r!   manifest_jsonmanifest_listr.   r   layer_sourcesentrys          r   r|   FromTarball.__enter__i  s    MM/299&AMJJ}-MFFM =QZZ
 &&(
ZZ3tzz?uyy/D/JK8$8R(		."5	  ?$**LMM L' Kr   c                     g r   r   r   s       r   r   FromTarball.__exit__  r$  r   )r:  r4  r;  rg  rZ  rX  r8  r9  r5  r   r3  )N	   )TF)r   r   r   r   r   r   r   rP  r_  r   r(   rd   rP   ry   rv  r|   r   r   r   r   s   @r   r1  r1    s[    I
 	* &+-^I8&t6;
$"<#$'R	 	r   r1  c                      ^  \ rS rSrSr   SU 4S jjrS rS rS rS r	S r
U 4S	 jrU 4S
 jrS rS rS rS r\S 5       rSrU =r$ )FromDiski  a  This accesses a more efficient on-disk format than FromTarball.

FromDisk reads an on-disk format optimized for use with push and pull.

It is expected that the number of layers in config_file's rootfs.diff_ids
matches: count(legacy_base.layers) + len(layers).

Layers are drawn from legacy_base first (it is expected to be the base),
and then from layers.

This is effectively the dual of the save.fast method, and is intended for use
with Bazel's rules_docker.

Args:
  config_file: the contents of the config file.
  layers: a list of pairs.  The first element is the path to a file containing
      the second element's sha256.  The second element is the .tar.gz of a
      filesystem layer.  These are ordered as they'd appear in the manifest.
  uncompressed_layers: Optionally, a list of pairs. The first element is the
      path to a file containing the second element's sha256.
      The second element is the .tar of a filesystem layer.
  legacy_base: Optionally, the path to a legacy base image in FromTarball form
  foreign_layers_manifest: Optionally a tar manifest from the base
      image that describes the ForeignLayers needed by this image.
c                   > [         TU ]  5         Xl        S U l        XPl        / U l        0 U l        U Ha  u  pg[        R                  " US5       nSUR                  5       -   n	S S S 5        U R
                  R                  W	5        XpR                  U	'   Mc     / U l        0 U l        U(       ag  U Ha  u  pg[        R                  " US5       nSUR                  5       -   n	S S S 5        U R                  R                  W	5        XpR                  U	'   Mc     S U l        U(       a  [        U5       n
Xl        S S S 5        g g ! , (       d  f       N= f! , (       d  f       Nv= f! , (       d  f       g = f)Nr@  zsha256:)r   r   _configr9  _foreign_layers_manifestrX  _layer_to_filenamer[   rC  r_   r[  _uncompressed_layers_uncompressed_layer_to_filename_legacy_baser1  )r!   r(   r   uncompressed_layerslegacy_baseforeign_layers_manifest	name_filecontent_filereader
layer_namebaser   s              r   r   FromDisk.__init__  s1    
GLDN$;!DL D%+!779d#v.
 $
ll*%,8j)	 &, !#D+-D(':
#9WWY% 6;;=0* &!!((4;G,,Z8	 (; D{#t  $#  $# &% $#s$   D>E-E >
E	
E	 
E.c                     / nU R                   (       a\  [        R                  " U R                   5      nSU;   a6  US    H-  nUS   [        R                  :X  d  M  UR                  U5        M/     U$ )Nr   r8   )r  r   r   r	   FOREIGN_LAYER_MIMEr[  )r!   foreign_layersr   rv   s       r   _get_foreign_layersFromDisk._get_foreign_layers  sd    N$$D99:h	X	h'E;;#A#AA!!%( ( r   c                 L    U R                  5        H  nUS   U:X  d  M  Us  $    g )Nr   )r  )r!   r   foreign_layers      r   _get_foreign_layer_by_digest%FromDisk._get_foreign_layer_by_digest  s-    113	x	 F	* 4 r   c                 j   / nU R                   (       a2  [        R                  " U R                   R                  5       5      S   nO#U R                  (       a  XR                  5       -  n[        R                  " S[        R                  [        R                  [        U R                  5       5      [        R                  " U R                  5       R                  S5      5      S.UU R                   Vs/ s H&  n[        R                   U R#                  U5      US.PM(     sn-   S.SS9U l        g s  snf )Nr   r   r@   )r8   rS  r   )r   r8   r.   r   Trb  )r  r   r   r   r  r  rd  r	   rU  rV  rO   r(   r   rA   rB   rX  rY  rR   r9  )r!   base_layersr   s      r   _populate_manifestFromDisk._populate_manifest  s	   KJJt0099;<XFk		&	& --//k ZZ 11  00((*+!(()9)9);)B)B6)JK  !%	. !-f "-!7!7 NN62$  !-	. .	
( +DN.s   3-D0c                 z    U R                   (       d  U R                  5         U R                   c   eU R                   $ r   )r9  r  r4   s    r   r   FromDisk.manifest  s/    >>
>>%%%>>r   c                     U R                   $ r   )r  r4   s    r   r(   FromDisk.config_file
  s    <<r   c                    > XR                   ;  a<  U R                  U5      (       a  [        / 5      $ U R                  R	                  U5      $ [
        [        U ]  U5      $ r   )r  r  bytes_checked_legacy_baserd   r   r  )r!   r   r   s     r   rd   FromDisk.uncompressed_blob  sU    ,,,		*	*6	2	2Ry ((::6BB426::r   c                 x  > XR                   ;   a>  [        R                  " U R                   U   S5       nUR                  5       sS S S 5        $ U R                  (       a8  XR                  R                  5       ;   a  U R                  R                  U5      $ [        [        U ]  U5      $ ! , (       d  f       Nj= f)NrW   )	r  r[   rC  r_   r  r'   ry   r   r  )r!   rl   r  r   s      r   ry   FromDisk.uncompressed_layer  s    66677

.
.w
7{{}	 
 W(9(9(B(B(DD11'::43G<< s   B++
B9c                     XR                   ;  a  U R                  R                  U5      $ [        U R                   U   S5       nUR	                  5       sSSS5        $ ! , (       d  f       g= f)r   rW   N)r  r  rP   rC  r_   )r!   r   r  s      r   rP   FromDisk.blob%  sQ    ,,,&&++F33	d%%f-t	4[[] 
5	4	4s   A
A,c                     XR                   ;  a  U R                  R                  U5      $ [        R                  " U R                   U   5      nUR
                  $ r   )r  r  rR   osstatst_size)r!   r   infos      r   rR   FromDisk.blob_size,  sH    ,,,&&0088774**623D<<r   c                     U $ r   r   r4   s    r   r|   FromDisk.__enter__4  s    Kr   c                     g r   r   r   s       r   r   FromDisk.__exit__7  r$  r   c                 J    U R                   c  [        S5      eU R                   $ )Nz:self._legacy_base is None. set legacy_base in constructor.)r  rk   r4   s    r   r  FromDisk._checked_legacy_base:  s,     
F  r   )r  r  r  rX  r  r9  r  r  )NNN)r   r   r   r   r   r   r  r  r  r   r(   rd   ry   rP   rR   r|   r   propertyr  r   r   r   s   @r   r  r    se    : &*!)-!@ D
;	=	  r   r  c                     U(       aH  [         R                  R                  U5      nX:X  a   gU R                  U5      (       a  gUnU(       a  MH  g)NTF)r  r  dirnamer*   )fsr   r  s      r   _in_whiteout_dirr  C  sG    ggood#G 
 
vvgD 	 
r   z.wh.c           
         0 nU R                  5        GH  n[        R                  " U R                  U5      5      n[        R
                  " SUS9 nU GHJ  n[        R                  R                  UR                  5      n[        R                  R                  UR                  5      nUR                  [        5      n	U	(       a  U[        [        5      S n[        R                  R                  [        R                  R                  SX5      5      n
X;   a  M  [!        X*5      (       a  M  U	=(       d    UR#                  5       (       + X*'   U	(       a  GM  UR%                  5       (       a!  UR'                  XeR)                  U5      S9  GM:  UR'                  USS9  GMM     SSS5        GM     g! , (       d  f       GM  = f)zExtract the final filesystem from the image into tar.

Args:
  image: a docker image whose final filesystem to construct.
  tar: the tarfile into which we are writing the final filesystem.
zr:rX   N.)rZ   )r'   r[   r\   ry   rB  rC  r  r  basenamer   r  
startswith_WHITEOUT_PREFIXrO   normpathjoinr  isdirisfileaddfilerD  )r   rK  r  rv   ra   	layer_tartarinfor  r  	tombstoner   s              r   extractr  Q  sD    
" ~~e
**U--e4
5C	4	-' 77##GLL1''//',,/''(89	c"2345( wwS' DE:
 B%%

 3GMMO 3y^^KK)>)>w)GKHKKK.9  
.	-  	-	-s   DF1AF11
G	)'r   
__future__r   r   r   r   r]   r[   r   r  rB  r6  containerregistry.clientr   r   containerregistry.client.v2_2r   r	   httplib2ri   	six.movesr
   six.moves.http_clientrs  r   with_metaclassABCMetaobjectr   r   r   r*  r,  r/  r1  r  r  r  r  r   r   r   <module>r     s    L &  % 
  	  	   1 0 7 5  
  @I @}#$$S[[&9 }@>{ >BlJ; lJf  K	"g	+ g	Tj{ jZ  ,/r   