
     3                         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J	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rS r " S S\5      rS rg)zEThis package manages pushes to and deletes from a v2 docker registry.    )absolute_import)division)print_functionN)docker_creds)docker_name)docker_http)docker_image)docker_image_listc                     [        U [        R                  5      (       a  U R                  $ [        U [        R                  5      (       d   eU R
                  $ N)
isinstancer   TagtagDigestdigest)names    @lib/third_party/containerregistry/client/v2_2/docker_session_.py_tag_or_digestr   "   s?    koo&&88OdK..////;;    c                       \ rS rSrS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S rS r SS jr SS jrS r SS jrS rS rSrg)Push*   z6Push encapsulates a Registry v2.2 Docker push session.Nc                 ~    Xl         [        R                  " XU[        R                  5      U l        X@l        XPl        g)a@  Constructor.

If multiple threads are used, the caller *must* ensure that the provided
transport is thread-safe, as well as the image that is being uploaded.
It is notable that tarfile and httplib2.Http in Python are NOT threadsafe.

Args:
  name: the fully-qualified name of the tag to push
  creds: credential provider for authorizing requests
  transport: the http transport to use for sending requests
  mount: list of repos from which to mount blobs.
  threads: the number of threads to use for uploads.

Raises:
  ValueError: an incorrectly typed argument was supplied.
N)_namer   	TransportPUSH
_transport_mount_threads)selfr   creds	transportmountthreadss         r   __init__Push.__init__-   s2    , J!++D,7,<,<>DOKMr   c                     U R                   $ r   )r   r    s    r   r   	Push.nameI   s    ::r   c                     SR                  [        R                  " U R                  R                  5      U R                  R                  S9$ )Nz{scheme}://{registry})schemeregistry)formatr   Schemer   r,   r(   s    r   _scheme_and_hostPush._scheme_and_hostL   s?    "))!!$**"5"56$$ * & &r   c                 j    U R                  5       SR                  U R                  R                  S9-   $ )Nz/v2/{repository})
repository)r/   r-   r   r2   r(   s    r   	_base_urlPush._base_urlQ   s8      "%7%>%>::(( &? &* * *r   c                     [         R                  R                  R                  R	                  U R                  5       US9$ )N)baseurl)sixmovesurllibparseurljoinr/   )r    locations     r   _get_absolute_urlPush._get_absolute_urlU   s8    99!!))""$( * 4 4r   c                 b   U R                   R                  SR                  U R                  5       US9S[        R
                  R                  R                  [        R
                  R                  R                  /S9u  p#UR                  [        R
                  R                  R                  :H  $ )z%Check the remote for the given layer.z{base_url}/blobs/{digest}base_urlr   HEADmethodaccepted_codes)
r   Requestr-   r3   r8   r9   http_clientOK	NOT_FOUNDstatus)r    r   respunused_contents       r   blob_existsPush.blob_existsZ   s      ??22#**^^%f 	+ 	6II!!$$cii&;&;&E&E
	 3 D ;;#))//2222r   c                    U R                   R                  SR                  U R                  5       UR	                  5       S9S[
        R                  R                  R                  [
        R                  R                  R                  /UR                  5       /S9u  p#UR                  [
        R                  R                  R                  :H  $ )2Check the remote for the given manifest by digest.z{base_url}/manifests/{digest}rA   GETrE   rF   accepted_mimes)r   rG   r-   r3   r   r8   r9   rH   rI   rJ   
media_typerK   r    imagerL   rM   s       r   manifest_existsPush.manifest_existsg   s    
  ??22'..^^%elln 	/ 	>II!!$$cii&;&;&E&E
 ((*+ 3 -D ;;#))//2222r   c                     X!R                  5       :X  a  UR                  5       R                  S5      $ UR                  U5      $ )Nutf8)config_blobconfig_fileencodeblobr    rW   r   s      r   	_get_blobPush._get_blobw   s:    ""$$ ''//::fr   c                     U R                   R                  SR                  U R                  5       US9SU R	                  X5      [
        R                  R                  R                  /S9  g )Nz){base_url}/blobs/uploads/?digest={digest}rA   POSTrE   bodyrF   )	r   rG   r-   r3   ra   r8   r9   rH   CREATEDr`   s      r   _monolithic_uploadPush._monolithic_upload|   s]    OO3::^^%f 	; 	6^^E*		--556  8r   c                    [         R                  R                  R                  R	                  U5      u  p4pVn[         R                  R                  R                  R                  U5      nU/US'   [         R                  R                  R                  R                  USS9n[         R                  R                  R                  R                  X4UXg45      $ )Nr   T)doseq)r8   r9   r:   r;   urlsplitparse_qs	urlencode
urlunsplit)	r    r7   r   r+   netlocpathquery_stringfragmentqss	            r   _add_digestPush._add_digest   s    		'', 1FD						(	(	6B8BxL99##))33Bd3CL99!!,,fd.:.F G Gr   c                 :   U R                  X R                  5      u  p4U(       a  [        R                  " SU5        g U R	                  XB5      nU R
                  R                  USU R                  X5      [        R                  R                  R                  /S9  g )NLayer %s mounted.PUTre   )_start_uploadr   logginginforu   r   rG   ra   r8   r9   rH   rg   )r    rW   r   mountedr=   s        r   _put_uploadPush._put_upload   s}    **6;;?Gll&/1HOO^^E*		--556	  8r   c           	         U R                  X R                  5      u  p4U(       a  [        R                  " SU5        g U R	                  U5      nUn[        U[        R                  5      (       a  U R                  X5      nU R                  R                  USUS[        R                  R                  R                  [        R                  R                  R                  [        R                  R                  R                   /S9u  pgU R#                  US   U5      nU R	                  U5      nU R                  R                  USS [        R                  R                  R                   /S9  g )Nrx   PATCHzapplication/octet-streamrE   rf   content_typerF   r=   ry   re   )rz   r   r{   r|   r>   r   r	   DockerImagera   r   rG   r8   r9   rH   
NO_CONTENTACCEPTEDrg   ru   )r    sourcer   r}   r=   r_   rL   rM   s           r   patch_uploadPush.patch_upload   s(   **6;;?Gll&/%%h/HD&,2233^^F+d??22/II!!,,cii.C.C.L.LII!!))
 3 D Z 0&9H%%h/HOO		--556	  8r   c                 &    U R                  X5        g)z(Upload the aufs .tgz for a single layer.N)r   r`   s      r   	_put_blobPush._put_blob   s    . 	e$r   c                    U R                   R                  SR                  U R                  5       U R                  R
                  S9S[        R                  R                  R                  [        R                  R                  R                  /UR                  5       /S9u  p#UR                  [        R                  R                  R                  :X  a  gUR                  S5      $ )rQ   z{base_url}/manifests/{tag})rB   r   rR   rS   Nzdocker-content-digest)r   rG   r-   r3   r   r   r8   r9   rH   rI   rJ   rU   rK   getrV   s       r   _remote_tag_digestPush._remote_tag_digest   s      ??22$++^^%

 	, 	  II!!$$cii&;&;&E&E
 ((*+ 3 -D {{cii++55588+,,r   c           	         U(       a  UR                  5       nO[        U R                  5      nU R                  R	                  SR                  U R                  5       US9SUR                  5       UR                  5       [        R                  R                  R                  [        R                  R                  R                  [        R                  R                  R                  /S9  g)z#Upload the manifest for this image.z${base_url}/manifests/{tag_or_digest})rB   tag_or_digestry   r   N)r   r   r   r   rG   r-   r3   manifestrU   r8   r9   rH   rI   rg   r   )r    rW   
use_digestr   s       r   put_manifestPush.put_manifest   s    
 llnm$TZZ0mOO.55^^%] 	6 	D^^%%'II!!$$cii&;&;&C&CII!!**
  	r   c           
         U(       dC  SR                  U R                  5       S9n[        R                  R                  R
                  /nOSR                  U R                   Vs/ s HD  nS[        R                  R                  R                  R                  UR                  S5      -   PMF     sn5      nSR                  U R                  5       XS9n[        R                  R                  R                  [        R                  R                  R
                  /nU R                  R                  USS	US
9u  pxUR                  [        R                  R                  R                  :H  UR!                  S5      4$ s  snf )zFPOST to begin the upload process with optional cross-repo mount param.z{base_url}/blobs/uploads/)rB   &zfrom= z5{base_url}/blobs/uploads/?mount={digest}&{mount_from})rB   r   
mount_fromrd   Nre   r=   )r-   r3   r8   r9   rH   r   joinr   r:   r;   quoter2   rg   r   rG   rK   r   )	r    r   r#   r7   rF   repor   rL   rM   s	            r   rz   Push._start_upload   s>   
 '..8H.Ic		--667n 88kk!d CII$$**00"E
E! 	j DJJ>>#F K Kc ))


'
')>)>)G)Gn  ??22Fn 3 FD ;;#))//777*9MMMs   $AE<c                     U R                  U5      (       a  [        R                  " SU5        gU R                  X5        [        R                  " SU5        g)z@Upload a single layer, after checking whether it exists already.zLayer %s exists, skippingNzLayer %s pushed.)rN   r{   r|   r   r`   s      r   _upload_onePush._upload_one  s@    ll.7NN5!LL#V,r   c           	         U R                  U5      (       a  [        U R                  [        R                  5      (       aR  U R                  U5      UR                  5       :X  a  [        R                  " S5        g[        R                  " S5        GO9[        R                  " S5        GO![        U[        R                  5      (       a'  U H   u  p4U   U R                  USS9  SSS5        M"     OU R                  S:X  a)  UR                  5        H  nU R                  X5        M     O[        R                   R#                  U R                  S9 nUR                  5        Vs0 s H!  nUR%                  U R                  X5      X4_M#     nn[        R                   R'                  U5       H  nUR)                  5         M     SSS5        U R+                  XS9  g! , (       d  f       GM   = fs  snf ! , (       d  f       N6= f)	zUpload the layers of the given image.

Args:
  image: the image to upload.
  use_digest: use the manifest digest (i.e. not tag) as the image reference.
z0Tag points to the right manifest, skipping push.Nz7Manifest exists, skipping blob uploads and pushing tag.z!Manifest exists, skipping upload.T)r      )max_workers)rX   r   r   r   r   r   r   r{   r|   
image_listDockerImageListuploadr   distributable_blob_setr   
concurrentfuturesThreadPoolExecutorsubmitas_completedresultr   )	r    rW   r   _childr   executorfuture_to_paramsfutures	            r   r   Push.upload$  s    E""	DJJ	0	0""5)U\\^;
,,I
J
NO89	E:55	6	6(!
++e+
- U  
!	002&' 3 00mm 1 %(0  668
8 OOD,,e<uoM8 	 
 !((556FGF
--/ H% 	e3! U
% %s*   GG3#(G.8G3
G+	.G33
Hc                     U $ r    r(   s    r   	__enter__Push.__enter__M  s    Kr   c                     U(       a"  [         R                  " SU R                  5        g [         R                  " SU R                  5        g )NzError during upload of: %szFinished upload of: %s)r{   errorr   r|   )r    exception_typeunused_valueunused_tracebacks       r   __exit__Push.__exit__P  s.    mm0$**=LL)4::6r   )r   r   r   r   )Nr   )Fr   )__name__
__module____qualname____firstlineno____doc__r%   r   r/   r3   r>   rN   rX   ra   rh   ru   r~   r   r   r   r   rz   r   r   r   r   __static_attributes__r   r   r   r   r   *   s    > 8&
*4
33 
8G88@%2-0 . !N6-  &4R7r   r   c           
         [         R                  " XU[         R                  5      nUR                  SR	                  [         R
                  " U R                  5      U R                  U R                  [        U 5      S9S[        R                  R                  R                  [        R                  R                  R                  /S9u  pEg)zDelete a tag or digest.

Args:
  name: a tag or digest to be deleted.
  creds: the creds to use for deletion.
  transport: the transport to use to contact the registry.
z8{scheme}://{registry}/v2/{repository}/manifests/{entity})r+   r,   r2   entityDELETErD   N)r   r   r   rG   r-   r.   r,   r2   r   r8   r9   rH   rI   r   )r   r!   r"   docker_transportr   rM   s         r   Deleter   X  s     !**4	+6+=+=? '..@GG##DMM2==__%	 H '
 ii++..		0E0E0N0NO / Q!^r   )r   
__future__r   r   r   r{   concurrent.futuresr   containerregistry.clientr   r   containerregistry.client.v2_2r   r	   r
   r   httplib2six.moves.http_clientr8   six.moves.urllib.parser   objectr   r   r   r   r   <module>r      sL    L &  %   1 0 5 6 I   j76 j7\	Qr   