
    [t                        d Z ddlmZ ddlmZ ddlm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 dd	lmZ ddlZddlZdd
lmZ ddlZ G d de      Z G d d ej2                  ej4                  e            Z G d de      Z G d de      Z G d de      Z e       e_         d Z! G d de      Z" G d de      Z#d Z$dZ%d Z&y)zEThis package provides DockerImage for examining docker_build outputs.    )absolute_import)division)print_functionN)docker_creds)docker_name)docker_digest)docker_http)zipc                       e Zd ZdZy)DigestMismatchedErrorz7Exception raised when a digest mismatch is encountered.N)__name__
__module____qualname____doc__     >lib/third_party/containerregistry/client/v2_2/docker_image_.pyr   r   &   s    ?r   r   c                      e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
ej                  d	        Zej                  d
        Zd Zej                  d        Zd Zd Zd Zd Zd Zej                  d        Zej                  d        Zd Zy)DockerImagez?Interface for implementations that interact with Docker images.c                     t        j                  | j                               }t        |d         D cg c]  }|d   	 c}S c c}w )zEThe ordered collection of filesystem layers that comprise this image.layersdigest)jsonloadsmanifestreversed)selfr   xs      r   	fs_layerszDockerImage.fs_layers-   s>    zz$--/*H!)(8*<!=>!=AAhK!=>>>s   Ac                     t        j                  | j                               }t        t	        |j                  di       j                  dg                   S )zBThe ordered list of uncompressed layer hashes (matches fs_layers).rootfsdiff_ids)r   r   config_filelistr   get)r   cfgs     r   r"   zDockerImage.diff_ids2   sA    
**T%%'
(C2.22:rBCDDr   c                 X    t        j                  | j                               }|d   d   S )Nconfigr   )r   r   r   r   r   s     r   config_blobzDockerImage.config_blob7   s&    zz$--/*HHh''r   c                 X    t        | j                         | j                         gz         S )z>The unique set of blobs that compose to create the filesystem.)setr   r*   r   s    r   blob_setzDockerImage.blob_set;   s%    t~~4#3#3#5"6677r   c                     t        j                  | j                               }t        |d         D ch c]  }|d   t        j
                  vr|d    }}|j                  | j                                |S c c}w )z0The unique set of blobs which are distributable.r   	mediaTyper   )r   r   r   r   r	   NON_DISTRIBUTABLE_LAYER_MIMESaddr*   )r   r   r   distributable_blobss       r   distributable_blob_setz"DockerImage.distributable_blob_set?   s|    zz$--/*H (8,--A[>!J!JJ 	
(-  
 D,,./s   !A8c                 f    t        j                  | j                         j                  d            S )The digest of the manifest.utf8)r   SHA256r   encoder-   s    r   r   zDockerImage.digestJ   s$     6 6v >??r   c                     t        j                  | j                               }|j                  dt        j
                        S )zThe media type of the manifest.r0   )r   r   r   r%   r	   OCI_MANIFEST_MIMEr)   s     r   
media_typezDockerImage.media_typeN   s-    zz$--/*H<<[%B%BCCr   c                      y)z^The JSON manifest referenced by the tag/digest.

    Returns:
      The raw json manifest
    Nr   r-   s    r   r   zDockerImage.manifestU       r   c                      y)z&The raw blob bytes of the config file.Nr   r-   s    r   r#   zDockerImage.config_file_   r>   r   c                 6    t        | j                  |            S )The byte size of the raw blob.)lenblobr   r   s     r   	blob_sizezDockerImage.blob_sized   s    tyy !!r   c                      y)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   rD   s     r   rC   zDockerImage.blobi   r>   r   c                     | j                  |      }t        j                  |      }t        j                  d|      }|j                         }|S )z Same as blob() but uncompressed.rbmodefileobj)rC   ioBytesIOgzipGzipFileread)r   r   zippedbuffunzippeds         r   uncompressed_blobzDockerImage.uncompressed_blobu   s>    YYvF
**V
C4-AvvxHOr   c                     t         j                  j                  | j                         | j	                               D ]  \  }}||k(  s|c S  t        d|z        )NUnmatched "diff_id": "%s"sixmovesr
   r   r"   
ValueError)r   diff_idthis_digestthis_diff_ids       r   _diff_id_to_digestzDockerImage._diff_id_to_digest}   sS    '*yy}}T^^5E59]]_(F#l		 (F 07:
;;r   c                     t         j                  j                  | j                         | j	                               D ]  \  }}||k(  s|c S  t        d|z        )NzUnmatched "digest": "%s"rX   )r   r   r]   r^   s       r   digest_to_diff_idzDockerImage.digest_to_diff_id   sS    '*yy}}T^^5E59]]_(F#l		(F /&8
99r   c                 B    | j                  | j                  |            S )a	  Like `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.
    )rC   r_   r   r\   s     r   layerzDockerImage.layer   s     99T,,W566r   c                 B    | j                  | j                  |            S )z!Same as layer() but uncompressed.)rU   r_   rc   s     r   uncompressed_layerzDockerImage.uncompressed_layer   s    !!$"9"9'"BCCr   c                      y)zOpen the image for reading.Nr   r-   s    r   	__enter__zDockerImage.__enter__   r>   r   c                      y)zClose the image.Nr   r   unused_typeunused_valueunused_tracebacks       r   __exit__zDockerImage.__exit__   r>   r   c                 *    t        t        |             S )z-A human-readable representation of the image.)strtyper-   s    r   __str__zDockerImage.__str__   s    tDz?r   N)r   r   r   r   r   r"   r*   r.   r4   r   r<   abcabstractmethodr   r#   rE   rC   rU   r_   ra   rd   rf   rh   rn   rr   r   r   r   r   r   *   s    G?
E
(8	@D   1 1"
  <:7D
 & &  r   r   c                   p     e Zd ZdZ fdZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Z xZS )Delegatez'Forwards calls to the underlying image.c                 0    t         |           || _        y)zcConstructor.

    Args:
      image: a DockerImage on which __enter__ has already been called.
    N)super__init___image)r   image	__class__s     r   ry   zDelegate.__init__   s     
GDKr   c                 6    | j                   j                         S 	Override.)rz   r   r-   s    r   r   zDelegate.manifest       ;;!!r   c                 6    | j                   j                         S r~   )rz   r<   r-   s    r   r<   zDelegate.media_type   s    ;;!!##r   c                 6    | j                   j                         S r~   )rz   r"   r-   s    r   r"   zDelegate.diff_ids   r   r   c                 6    | j                   j                         S r~   )rz   r   r-   s    r   r   zDelegate.fs_layers   s    ;;  ""r   c                 6    | j                   j                         S r~   )rz   r*   r-   s    r   r*   zDelegate.config_blob       ;;""$$r   c                 6    | j                   j                         S r~   )rz   r.   r-   s    r   r.   zDelegate.blob_set   r   r   c                 6    | j                   j                         S r~   )rz   r#   r-   s    r   r#   zDelegate.config_file   r   r   c                 8    | j                   j                  |      S r~   )rz   rE   rD   s     r   rE   zDelegate.blob_size   s    ;;  ((r   c                 8    | j                   j                  |      S r~   )rz   rC   rD   s     r   rC   zDelegate.blob   s    ;;F##r   c                 8    | j                   j                  |      S r~   )rz   rU   rD   s     r   rU   zDelegate.uncompressed_blob   s    ;;((00r   c                 8    | j                   j                  |      S r~   )rz   rd   rc   s     r   rd   zDelegate.layer   s    ;;W%%r   c                 8    | j                   j                  |      S r~   )rz   rf   rc   s     r   rf   zDelegate.uncompressed_layer   s    ;;))'22r   c                 ,    t        | j                        S r~   )rp   rz   r-   s    r   rr   zDelegate.__str__   s    t{{r   )r   r   r   r   ry   r   r<   r"   r   r*   r.   r#   rE   rC   rU   rd   rf   rr   __classcell__r|   s   @r   rv   rv      sL    /"$"#%"%)$1&3r   rv   c                        e Zd ZdZej
                  f fd	Z	 	 ddZd Zd Z	d Z
d Zd Zd	 Z fd
ZddZd Zd Zd ZddZd Zd Zd Z xZS )FromRegistryz>This accesses a docker image hosted on a registry (non-local).c                 h    t         |           || _        || _        || _        || _        i | _        y N)rx   ry   _name_creds_original_transport_accepted_mimes	_response)r   namebasic_creds	transportaccepted_mimesr|   s        r   ry   zFromRegistry.__init__   s5    
 
GDJDK(D)DDNr   c                    t        | j                  t        j                        r'dj	                  | j                  j
                  |      }|| j                  v r| j                  |   S | j                  j                  dj	                  t        j                  | j                  j                        | j                  j                  |      t        j                  j                  j                  g|      \  }}|r|| j                  |<   |S )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   rY   rZ   http_clientOK)r   r   r   cache_contents         r   _contentzFromRegistry._content   s    
 $**k445&--ZZ**6 . ;f ^^F##((+22%%djj&9&9:ZZ(( 	3 	 		--001% ) 'JAw &dnnVNr   c                     t        j                  | j                  d      j                  d            }d|vr$t	        j
                  dj                  |            |j                  d      S )Nztags/list?check_usage_only=truer7   usagez2Malformed JSON response: {}. Missing "usage" field)r   r   r   decoder	   BadStateExceptionr   r%   )r   responses     r   check_usage_onlyzFromRegistry.check_usage_only  sf     zz78??GH h))
>
E
Eh
O  <<  r   c                 h    t        j                  | j                  d      j                  d            S )Nz	tags/listr7   )r   r   r   r   r-   s    r   _tagszFromRegistry._tags  s'     ::dmmK077?@@r   c                 B    | j                         j                  dg       S )Ntags)r   r%   r-   s    r   r   zFromRegistry.tags"  s    ::<FB''r   c                 8    | j                         }d|vri S |d   S )Nr   r   r   payloads     r   	manifestszFromRegistry.manifests%  s%    jjlG i:r   c                 8    | j                         }d|vrg S |d   S )Nchildr   r   s     r   childrenzFromRegistry.children,  s%    jjlGgi7r   c                 J   	 t        j                  | j                  d            }|d   dk(  xr" d|v xr | j                         | j                  v S # t
        j                  $ r<}|j                  t        j                  j                  j                  k(  rY d }~y d }~ww xY w)NF)validateschemaVersion   r   )r   r   r   r<   r   r	   V2DiagnosticExceptionstatusrY   rZ   r   	NOT_FOUND)r   r   errs      r   existszFromRegistry.exists3  s    DMM5M9:h'1, 8X1E 8oo4#7#779,, 	syy,,66	6s   AA B"&1BBB"c                     t        | j                  t        j                        r| j                  j                  S t
        |          S )r6   )r   r   r   Digestr   rx   )r   r|   s    r   r   zFromRegistry.digest=  s4    $**k001ZZ7>r   c                 P   t        | j                  t        j                        rDd| j                  j                  z   }| j                  || j                        j                  d      S t        | j                  t        j                        sJ | j                  d| j                  j                  z   | j                        }t        j                  |      }|r>|| j                  j                  k7  r%t        d| j                  j                  d|      |j                  d      S )r   z
manifests/r7   z?The returned manifest's digest did not match requested digest,  vs. )r   r   r   Tagtagr   r   r   r   r   r   r8   r   )r   r   pathccomputeds        r   r   zFromRegistry.manifestC  s     $**koo.DJJNN*d]]4!5!56==fEE

K$6$6777
--tzz'8'88$:N:N
Oa%%a(h	h$**"3"33#::,,h89 	9 XXfr   c                 ^    | j                  | j                               j                  d      S r   r7   )rC   r*   r   r-   s    r   r#   zFromRegistry.config_fileT  s%    99T%%'(//77r   c                    d|z   }t        | j                  t        j                        r'dj	                  | j                  j
                  |      }| j                  j                  dj	                  t        j                  | j                  j                        | j                  j                  |      dt        j                  j                  j                  g      \  }}t        |d         S )	rA   blobs/r   r   r   r   HEAD)methodr   zcontent-length)r   r   r   r   r   r   r   r   r	   r   r   rY   rZ   r   r   int)r   r   r   respunused_contents        r   rE   zFromRegistry.blob_sizeX  s    F$**k445&--ZZ**6 . ;f  ??22+22%%djj&9&9:ZZ(( 	3 	 		--001 3 3D. t$%&&r   c                     | j                  d|z   d      }t        j                  |      }||k7  rt        d|d|r|      d      |S )r   r   F)r   zAThe returned content's digest did not match its content-address, r   z(content was empty))r   r   r8   r   )r   r   r   r   s       r   rC   zFromRegistry.blobj  sq     	h'u5A##A&H!Q!IKL L4I!IKL L Hr   c              #   4  K   t        | j                  t        j                        rt	        d      dj                  t        j                  | j                  j                        | j                  j                  |      }| j                  j                  |t        j                  j                  j                  g      D ]S  \  }}t        j                   |j#                  d            }d|vrt        j$                  d|z        |d   D ]  }|  U y w)Nz(Expected docker_name.Registry for "name"z/{scheme}://{registry}/v2/_catalog?n={page_size})r   r   	page_size)r   r7   repositorieszMalformed JSON response: %s)r   r   r   r   r[   r   r	   r   r   r   PaginatedRequestrY   rZ   r   r   r   r   r   r   )r   r   urlr   r   wrapper_objectrepos          r   catalogzFromRegistry.catalogu  s     $**k445ABB
;
B
B!!$**"5"56$$ C C
 oo66SYY22556 7 8
7zz'.."89n	~	-++)G35 	5 !0$
 18s   DDc                     t        j                  | j                  | j                  | j                  t         j
                        | _        | S r   )r	   	Transportr   r   r   PULLr   r-   s    r   rh   zFromRegistry.__enter__  s9    !++

DKK!9!9;;K;KMDO Kr   c                      y r   r   rj   s       r   rn   zFromRegistry.__exit__      r   c                 J    dj                  t        | j                              S )Nz$<docker_image.FromRegistry name: {}>)r   rp   r   r-   s    r   rr   zFromRegistry.__str__  s    188TZZIIr   )NT)T)d   )r   r   r   r   r	   MANIFEST_SCHEMA2_MIMESry   r   r   r   r   r   r   r   r   r   r#   rE   rC   r   rh   rn   rr   r   r   s   @r   r   r      sp    F !, B B	
 !%.
!A
("8'$	.	Jr   r   c                       e Zd Zd Zy)	_FakeTimec                      y)NgEDAr   r-   s    r   timez_FakeTime.time  s    r   N)r   r   r   r   r   r   r   r   r     s    r   r   c                     | dd dk(  S )Nr   r   s   r   )r   s    r   is_compressedr     s    	ak	!!r   c                   p     e Zd ZdZ	 	 d fd	Z	 	 ddZd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Z xZS )FromTarballzAThis decodes the image tarball output of docker_build for upload.c                     t         |           || _        || _        i | _        t        j                         | _        || _        d | _	        d | _
        d | _        y r   )rx   ry   _tarball_compresslevel_memoize	threadingLock_lockr   	_manifest_blob_names_config_blob)r   tarballr   compresslevelr|   s       r   ry   zFromTarball.__init__  sR     
GDM'DDM!DJDJDNDDr   c                    |r@| j                   5  ||f| j                  v r| j                  ||f   cddd       S 	 ddd       t        j                  | j                  d      5 }	 |j                  t        |            }|j                         }|rtt        |      sit        j                         }t        j                  d| j                  |      }	 |j                  |       |j!                          |j#                         }nI|sGt        |      r<t        j                  |      }t        j                  d|      }	|	j                         }|r&| j                   5  || j                  ||f<   ddd       |cddd       S # 1 sw Y   IxY w# t        $ r/ |j                  t        d|z               j                         }Y 6w xY w# |j!                          w xY w# 1 sw Y   qxY w# 1 sw Y   yxY w)	z6Fetches a particular path's contents from the tarball.Nr)r   rJ   z./wb)rJ   r  rK   rH   rI   )r   r   tarfileopenr   extractfilerp   rP   KeyErrorr   rL   rM   rN   rO   r   writeclosegetvalue)
r   r   memoizeshould_be_compressedtarrS   r   rR   rQ   raws
             r   r   zFromTarball._content  s    ::&'4==8&:;< :8  
4==s	3s% OOCI&&&(
 
mG&<jjlT%8%8#G	
,,w

,,.,,. $g(>jj!mms3((*	ZZ8?$--34
5 = 
4	3 :  %//t"df 	% ,,. Z9 
4	3sm   !F$G+&*FAG+G
%A8G+G/	G+F4GG+GG+
GG+G(	$G++G4c                 *    | j                  |dd      S )z1Returns the result of _content with gzip applied.FTr  r  )r   )r   r   s     r   _gzipped_contentzFromTarball._gzipped_content  s    ==u4=HHr   c                    t        j                  | j                         j                  d            }t        j
                  d|t        j                  t        | j                               dg d}i }t        j                  | j                               }|d   d   }t        | j                        D ]  \  }}d}||   }	t        j                  }
d}g }|	| j                  v rZ| j                  |	   d	   }| j                  |	   d
   }
| j                  |	   d   }d| j                  |	   v rD| j                  |	   d   }n1| j                  |      }t        j                  |      }t        |      }|||<   ||
|d}|r||d<   |d   j                  |        | j                   5  || _        || _        || _        ddd       y# 1 sw Y   yxY w)z.Populates self._manifest and self._blob_names.r7   r   )r   r0   size)r0   r   r(   r   r!   r"   Nr   r   r0   r  urlsr   )r   r8   r#   r9   r	   MANIFEST_SCHEMA2_MIMECONFIG_JSON_MIMErB   r   r   	enumerate_layers
LAYER_MIME_layer_sourcesr  appendr   r   r  r  )r   r*   r   
blob_namesr(   r"   ird   r   r\   r<   r  r  r   layer_manifests                  r   _populate_manifest_and_blobsz(FromTarball._populate_manifest_and_blobs  s   &&t'7'7'9'@'@'HIK 66!$55((*+


H JZZ((*+Fh
+Hdll+5dg))jdd	D''	'""7+H5((1+>
""7+F3T((11$$W-f5$''.##G,7|j !n 
!%vx/= ,@ 
dn#d%d 
s   !G  G	c                 |    | j                   s| j                          t        j                  | j                   d      S )r   T	sort_keys)r   r#  r   dumpsr-   s    r   r   zFromTarball.manifest/  s*    >>
'')::dnn55r   c                 V    | j                  | j                        j                  d      S r   )r   _config_filer   r-   s    r   r#   zFromTarball.config_file5  s"    ==**+226::r   c                     | j                   s| j                          | j                   J | j                  | j                   |   dd      S )r   Fr  )r  r#  r   rD   s     r   rU   zFromTarball.uncompressed_blob:  sS    
'')'''== "  $ $r   c                     | j                   s| j                          || j                  k(  r| j                         j	                  d      S | j                   J | j                  | j                   |         S r   )r  r#  r  r#   r9   r  rD   s     r   rC   zFromTarball.blobE  sr    
'')"""&&v..'''   " "r   c                     t        t        | j                        | j                               D ]   \  }}||k(  s| j	                  |dd      c S  t        d|z        )r   Fr  rW   )r
   r   r  r"   r   r[   )r   r\   rd   r^   s       r   rf   zFromTarball.uncompressed_layerP  sX    !$Xdll%;T]]_!M	L	 }}UE}NN "N 07:
;;r   c                    | j                  dd      }t        j                  |j                  d            }t	        |      dk7  rt        d      t        j                  |      D ]Q  \  }}t	        |      dk7  rt        d      t        j                  |      D ]  \  }}dj                  ||	      c c S  S t        d
      )zEResolve the singleton tag this tarball contains using legacy methods.r   F)r  r7      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   rB   r[   rY   	iteritemsr   	Exception)r   
repo_bytesr   r   r   r   unused_layers          r   _resolve_tagzFromTarball._resolve_tagW  s    ~u=J::j//78L
<A E F F l3t	Ta G H 	H!$t!4
3#**d*DD "5	 4 M
""r   c                    | j                  d      j                  d      }t        j                  |      }d }g }g }t	        |      dk7  r!| j
                  s| j                         | _        |D ]n  }| j
                  r+t        | j
                        |j                  d      xs g v s:|j                  d      }|j                  dg       }|j                  di       }p |st        d| j
                  z        || _
        || _        || _        | S )	Nzmanifest.jsonr7   r.  RepoTagsConfigLayersLayerSourcesz&Unable to find %s in provided tarball.)r   r   r   r   rB   r   r4  rp   r%   r[   r)  r  r  )r   manifest_jsonmanifest_listr(   r   layer_sourcesentrys          r   rh   z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 DDL'D Kr   c                      y r   r   rj   s       r   rn   zFromTarball.__exit__  r   r   )N	   )TF)r   r   r   r   ry   r   r  r#  r   r#   rU   rC   rf   r4  rh   rn   r   r   s   @r   r   r     sV    I
 	* &+-^I8&t6;
$"<#$'R	r   r   c                        e Zd ZdZ	 	 	 d fd	Zd Zd Zd Zd Zd Z	 fdZ
 fd	Zd
 Zd Zd Zd Zed        Z xZS )FromDiska  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         |           || _        d | _        || _        g | _        i | _        |D ]a  \  }}t        j                  |d      5 }d|j                         z   }	d d d        | j
                  j                  	       || j                  |	<   c g | _        i | _        |rf|D ]a  \  }}t        j                  |d      5 }d|j                         z   }	d d d        | j                  j                  	       || j                  |	<   c d | _        |rt        |      5 }
|
| _        d d d        y y # 1 sw Y   xY w# 1 sw Y   gxY w# 1 sw Y   y xY w)Nr  zsha256:)rx   ry   _configr   _foreign_layers_manifestr  _layer_to_filenamerL   r	  rP   r  _uncompressed_layers_uncompressed_layer_to_filename_legacy_baser   )r   r#   r   uncompressed_layerslegacy_baseforeign_layers_manifest	name_filecontent_filereader
layer_namebaser|   s              r   ry   zFromDisk.__init__  s?    
GDLDN$;D!DL D%+!L779d#v.
 $
ll*%,8dj)	 &, !#D+-D(':
#9lWWY% 6;;=0* &!!((4;G,,Z8	 (; D{#t  $#  $# &% $#s$   D5E#E5D>	E
	Ec                     g }| j                   rUt        j                  | j                         }d|v r2|d   D ]*  }|d   t        j                  k(  s|j                  |       , |S )Nr   r0   )rD  r   r   r	   FOREIGN_LAYER_MIMEr  )r   foreign_layersr   rd   s       r   _get_foreign_layerszFromDisk._get_foreign_layers  sd    N$$D99:h	X	h'E;;#A#AA!!%( ( r   c                 F    | j                         D ]  }|d   |k(  s|c S  y )Nr   )rT  )r   r   foreign_layers      r   _get_foreign_layer_by_digestz%FromDisk._get_foreign_layer_by_digest  s-    113	x	 F	* 4 r   c                 R   g }| j                   r1t        j                  | j                   j                               d   }n| j                  r|| j                         z  }t        j                  dt        j                  t        j                  t        | j                               t        j                  | j                         j                  d            d|| j                  D cg c]%  }t        j                   | j#                  |      |d' c}z   dd      | _        y c c}w )Nr   r   r7   )r0   r  r   )r   r0   r(   r   Tr%  )rH  r   r   r   rD  rT  r'  r	   r  r  rB   r#   r   r8   r9   r  r  rE   r   )r   base_layersr   s      r   _populate_manifestzFromDisk._populate_manifest  s   KJJt0099;<XFk		&	& T--//k ZZ 11  00((*+!(()9)9);)B)B6)JK  !%	. !-f "-!7!7 NN62$  !-	. .	
( +DN.s   '*D$c                 n    | j                   s| j                          | j                   J | j                   S r~   )r   rZ  r-   s    r   r   zFromDisk.manifest  s/    >>
>>%%%>>r   c                     | j                   S r~   )rC  r-   s    r   r#   zFromDisk.config_file
  s    <<r   c                     || j                   vr7| j                  |      rt        g       S | j                  j	                  |      S t
        t        |   |      S r~   )rE  rW  bytes_checked_legacy_baserU   rx   rA  )r   r   r|   s     r   rU   zFromDisk.uncompressed_blob  sT    T,,,		*	*6	2Ry ((::6BB426::r   c                 ^   || j                   v r=t        j                  | j                   |   d      5 }|j                         cd d d        S | j                  r7|| j                  j                         v r| j                  j                  |      S t        t        |   |      S # 1 sw Y   _xY w)NrH   )	rG  rL   r	  rP   rH  r"   rf   rx   rA  )r   r\   rN  r|   s      r   rf   zFromDisk.uncompressed_layer  s    $66677

.
.w
7{{}	 
 W(9(9(B(B(DD11'::43G<< s   B##B,c                     || j                   vr| j                  j                  |      S t        | j                   |   d      5 }|j	                         cddd       S # 1 sw Y   yxY w)r   rH   N)rE  r_  rC   r	  rP   )r   r   rN  s      r   rC   zFromDisk.blob%  sS    T,,,&&++F33	d%%f-t	4[[] 
5	4	4s   AA&c                     || j                   vr| j                  j                  |      S t        j                  | j                   |         }|j
                  S r~   )rE  r_  rE   osstatst_size)r   r   infos      r   rE   zFromDisk.blob_size,  sJ    T,,,&&0088774**623D<<r   c                     | S r   r   r-   s    r   rh   zFromDisk.__enter__4  s    Kr   c                      y r   r   rj   s       r   rn   zFromDisk.__exit__7  r   r   c                 H    | j                   t        d      | j                   S )Nz:self._legacy_base is None. set legacy_base in constructor.)rH  r[   r-   s    r   r_  zFromDisk._checked_legacy_base:  s,     
F  r   )NNN)r   r   r   r   ry   rT  rW  rZ  r   r#   rU   rf   rC   rE   rh   rn   propertyr_  r   r   s   @r   rA  rA    se    : &*!)-!@ D
;	=	  r   rA  c                     |r=t         j                  j                  |      }||k(  r	 y| j                  |      ry|}|r=y)NTF)rc  r   dirnamer%   )fsr   rl  s      r   _in_whiteout_dirrn  C  sE    ggood#Gw 
 
vvgD 	 
r   z.wh.c           
      F   i }| j                         D ]~  }t        j                  | j                  |            }t	        j
                  d|      5 }|D ]0  }t        j                  j                  |j                        }t        j                  j                  |j                        }|j                  t              }	|	r|t        t              d }t        j                  j                  t        j                  j                  d||            }
|
|v rt!        ||
      r|	xs |j#                          ||
<   |	r|j%                         r$|j'                  ||j)                  |             |j'                  |d       3 	 ddd        y# 1 sw Y   xY w)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:rI   N.)rK   )r"   rL   rM   rf   r  r	  rc  r   basenamer   rl  
startswith_WHITEOUT_PREFIXrB   normpathjoinrn  isdirisfileaddfiler
  )r{   r  rm  rd   rR   	layer_tartarinforq  rl  	tombstoner   s              r   extractr|  Q  sF    
" ~~e
**U--e4
5C	4	-' 77##GLL1''//',,/''(89	c"2345( wwS'8 DE2:
 B%

 3GMMO 34^^KK)>)>w)GKHKKK.9  
.	-  	-	-s   C,F?A
FF 	)'r   
__future__r   r   r   rs   rN   rL   r   rc  r  r   containerregistry.clientr   r   containerregistry.client.v2_2r   r	   httplib2rY   	six.movesr
   six.moves.http_clientr1  r   with_metaclassABCMetaobjectr   rv   r   r   r   r   r   rA  rn  rs  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   