
    %/                         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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_imagec                     [        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/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 rS rS rS rSrg)Push*   z4Push encapsulates a Registry v2 Docker push session.Nc                 ~    Xl         [        R                  " XU[        R                  5      U l        X@l        XPl        g)a5  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: 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   r1   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,   r2   r7   r8   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                  /S9u  p#UR                  [
        R                  R                  R                  :H  $ )2Check the remote for the given manifest by digest.z{base_url}/manifests/{digest}r@   GETrC   )r   rF   r,   r2   r   r7   r8   rG   rH   rI   rJ   )r   imagerK   rL   s       r   manifest_existsPush.manifest_existsg   s      ??22'..^^%elln 	/ 	>II!!$$cii&;&;&E&E
	 3 D ;;#))//2222r   c                     U R                   R                  SR                  U R                  5       US9SUR	                  U5      [
        R                  R                  R                  /S9  g )Nz){base_url}/blobs/uploads/?digest={digest}r@   POSTrD   bodyrE   )	r   rF   r,   r2   blobr7   r8   rG   CREATEDr   rR   r   s      r   _monolithic_uploadPush._monolithic_uploadt   s]    OO3::^^%f 	; 	6ZZ		--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)r7   r8   r9   r:   urlsplitparse_qs	urlencode
urlunsplit)	r   r6   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                  U5      [        R                  R                  R                  /S9  g )NLayer %s mounted.PUTrW   )_start_uploadr   logginginfori   r   rF   rY   r7   r8   rG   rZ   )r   rR   r   mountedr<   s        r   _put_uploadPush._put_upload   s}    **6;;?Gll&/1HOOZZ		--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                  U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 )Nrl   PATCHzapplication/octet-stream)rD   rX   content_typerE   r<   rm   rW   )rn   r   ro   rp   r=   r   r	   DockerImagerY   r   rF   r7   r8   rG   
NO_CONTENTACCEPTEDrZ   ri   )r   sourcer   rq   r<   rY   rK   rL   s           r   patch_uploadPush.patch_upload   s(   **6;;?Gll&/%%h/HD&,2233[[ 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                  /S9u  pUR                  [        R                  R                  R                  :X  a  gUR                  S5      $ )rP   z{base_url}/manifests/{tag})rA   r   rQ   rC   Nzdocker-content-digest)r   rF   r,   r2   r   r   r7   r8   rG   rH   rI   rJ   get)r   rK   rL   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 R                   R                  SR                  U R                  5       [	        U R
                  5      S9SUR                  5       R                  S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})rA   tag_or_digestrm   utf8rW   N)r   rF   r,   r2   r   r   manifestencoder7   r8   rG   rH   rZ   ry   )r   rR   s     r   put_manifestPush.put_manifest   s    OO.55^^%(4 	6 	6 ^^$$V,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/)rA   &zfrom= z5{base_url}/blobs/uploads/?mount={digest}&{mount_from})rA   r   
mount_fromrV   NrW   r<   )r,   r2   r7   r8   rG   ry   joinr   r9   r:   quoter1   rZ   r   rF   rJ   r   )	r   r   r"   r6   rE   repor   rK   rL   s	            r   rn   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.)rM   ro   rp   r~   r[   s      r   _upload_onePush._upload_one  s@    ll.7NN5!LL#V,r   c           	      T   U R                  U5      (       a  [        U R                  [        R                  5      (       aP  U R                  5       UR                  5       :X  a  [        R                  " S5        g[        R                  " S5        O[        R                  " S5        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%                  U5        gs  snf ! , (       d  f       N%= f)zKUpload the layers of the given image.

Args:
  image: the image to upload.
z0Tag points to the right manifest, skipping push.Nz7Manifest exists, skipping blob uploads and pushing tag.z!Manifest exists, skipping upload.   )max_workers)rS   r   r   r   r   r   r   ro   rp   r   blob_setr   
concurrentfuturesThreadPoolExecutorsubmitas_completedresultr   )r   rR   r   executorfuture_to_paramsfutures         r   uploadPush.upload  sI    E""	DJJ	0	0""$6
,,I
J
NO89	!	NN$&' % 00mm 1 %(0  ..*
* OOD,,e<uoM* 	 
 !((556FGF
--/ H% 	e
% %s   F(F8FF
F'c                     U $ r    r'   s    r   	__enter__Push.__enter__1  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)ro   errorr   rp   )r   exception_typeunused_valueunused_tracebacks       r   __exit__Push.__exit__4  s.    mm0$**=LL)4::6r   )r   r   r   r   )Nr   r   )__name__
__module____qualname____firstlineno____doc__r$   r   r.   r2   r=   rM   rS   r\   ri   rr   r{   r~   r   r   rn   r   r   r   r   __static_attributes__r   r   r   r   r   *   st    < 8&
*4
338G88>%2-$ !N6-B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 credentials to use for deletion.
  transport: the transport to use to contact the registry.
z8{scheme}://{registry}/v2/{repository}/manifests/{entity})r*   r+   r1   entityDELETErC   N)r   r   r   rF   r,   r-   r+   r1   r   r7   r8   rG   rH   ry   )r   r    r!   docker_transport_rL   s         r   Deleter   <  s     !**4	+6+=+=? '..@GG##DMM2==__%	 H '
 ii++..		0E0E0N0NO / Q!^r   )r   
__future__r   r   r   ro   concurrent.futuresr   containerregistry.clientr   r   containerregistry.client.v2r   r	   httplib2six.moves.http_clientr7   six.moves.urllib.parser   objectr   r   r   r   r   <module>r      sI    L &  %   1 0 3 4   N76 N7dQr   