
    %/                         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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Zd
 Z G d de      Zd Zy)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                     t        | t        j                        r| j                  S t        | t        j                        sJ | j
                  S N)
isinstancer   TagtagDigestdigest)names    >lib/third_party/containerregistry/client/v2/docker_session_.py_tag_or_digestr   "   s9    koo&88OdK..///;;    c                       e Zd Z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d Zd Zd Z	 ddZd Zd Zd Zd Zy)Pushz4Push encapsulates a Registry v2 Docker push session.Nc                     || _         t        j                  |||t        j                        | _        || _        || _        y)ae  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__zPush.__init__-   s:    , DJ!++D%,7,<,<>DODKDMr   c                     | j                   S r   )r   r   s    r   r   z	Push.nameI   s    ::r   c                     dj                  t        j                  | j                  j                        | j                  j                        S )Nz{scheme}://{registry})schemeregistry)formatr   Schemer   r(   r%   s    r   _scheme_and_hostzPush._scheme_and_hostL   s?    "))!!$**"5"56$$ * & &r   c                 p    | j                         dj                  | j                  j                        z   S )Nz/v2/{repository})
repository)r+   r)   r   r-   r%   s    r   	_base_urlzPush._base_urlQ   s8      "%7%>%>::(( &? &* * *r   c                     t         j                  j                  j                  j	                  | j                         |      S )N)baseurl)sixmovesurllibparseurljoinr+   )r   locations     r   _get_absolute_urlzPush._get_absolute_urlU   s8    99!!))""$( * 4 4r   c                 p   | j                   j                  dj                  | j                         |      dt        j
                  j                  j                  t        j
                  j                  j                  g      \  }}|j                  t        j
                  j                  j                  k(  S )z%Check the remote for the given layer.z{base_url}/blobs/{digest}base_urlr   HEADmethodaccepted_codes)
r   Requestr)   r.   r2   r3   http_clientOK	NOT_FOUNDstatus)r   r   respunused_contents       r   blob_existszPush.blob_existsZ   s      ??22#**^^%f 	+ 	6II!!$$cii&;&;&E&E
	 3 D. ;;#))//2222r   c                    | j                   j                  dj                  | j                         |j	                               dt
        j                  j                  j                  t
        j                  j                  j                  g      \  }}|j                  t
        j                  j                  j                  k(  S )2Check the remote for the given manifest by digest.z{base_url}/manifests/{digest}r:   GETr=   )r   r@   r)   r.   r   r2   r3   rA   rB   rC   rD   )r   imagerE   rF   s       r   manifest_existszPush.manifest_existsg   s      ??22'..^^%elln 	/ 	>II!!$$cii&;&;&E&E
	 3 D. ;;#))//2222r   c                     | j                   j                  dj                  | j                         |      d|j	                  |      t
        j                  j                  j                  g       y )Nz){base_url}/blobs/uploads/?digest={digest}r:   POSTr>   bodyr?   )	r   r@   r)   r.   blobr2   r3   rA   CREATEDr   rK   r   s      r   _monolithic_uploadzPush._monolithic_uploadt   s]    OO3::^^%f 	; 	6ZZ		--556  8r   c                    t         j                  j                  j                  j	                  |      \  }}}}}t         j                  j                  j                  j                  |      }|g|d<   t         j                  j                  j                  j                  |d      }t         j                  j                  j                  j                  |||||f      S )Nr   T)doseq)r2   r3   r4   r5   urlsplitparse_qs	urlencode
urlunsplit)	r   r1   r   r'   netlocpathquery_stringfragmentqss	            r   _add_digestzPush._add_digest}   s    		'', 1FFD,						(	(	6B8BxL99##))33Bd3CL99!!,,ffd.:H.F G Gr   c                 :   | j                  || j                        \  }}|rt        j                  d|       y | j	                  ||      }| j
                  j                  |d|j                  |      t        j                  j                  j                  g       y )NLayer %s mounted.PUTrO   )_start_uploadr   logginginfor`   r   r@   rQ   r2   r3   rA   rR   )r   rK   r   mountedr7   s        r   _put_uploadzPush._put_upload   s    **64;;?GXll&/&1HOOZZ		--556	  8r   c           	         | j                  || j                        \  }}|rt        j                  d|       y | j	                  |      }|}t        |t        j                        r|j                  |      }| j                  j                  |d|dt        j                  j                  j                  t        j                  j                  j                  t        j                  j                  j                   g      \  }}| j#                  |d   |      }| j	                  |      }| j                  j                  |dd t        j                  j                  j                   g       y )Nrb   PATCHzapplication/octet-stream)r>   rP   content_typer?   r7   rc   rO   )rd   r   re   rf   r8   r   r	   DockerImagerQ   r   r@   r2   r3   rA   
NO_CONTENTACCEPTEDrR   r`   )r   sourcer   rg   r7   rQ   rE   rF   s           r   patch_uploadzPush.patch_upload   s+   **64;;?GXll&/%%h/HD&,223[[ d??22/II!!,,cii.C.C.L.LII!!))
 3 D. Z 0&9H%%h/HOO		--556	  8r   c                 (    | j                  ||       y)z(Upload the aufs .tgz for a single layer.N)rp   rS   s      r   	_put_blobzPush._put_blob   s    . 	eV$r   c                    | j                   j                  dj                  | j                         | j                  j
                        dt        j                  j                  j                  t        j                  j                  j                  g      \  }}|j                  t        j                  j                  j                  k(  ry|j                  d      S )rI   z{base_url}/manifests/{tag})r;   r   rJ   r=   Nzdocker-content-digest)r   r@   r)   r.   r   r   r2   r3   rA   rB   rC   rD   get)r   rE   rF   s      r   _remote_tag_digestzPush._remote_tag_digest   s      ??22$++^^%

 	, 	  II!!$$cii&;&;&E&E
 3 D. {{cii++55588+,,r   c                    | j                   j                  dj                  | j                         t	        | j
                              d|j                         j                  d      t        j                  j                  j                  t        j                  j                  j                  t        j                  j                  j                  g       y)z#Upload the manifest for this image.z${base_url}/manifests/{tag_or_digest})r;   tag_or_digestrc   utf8rO   N)r   r@   r)   r.   r   r   manifestencoder2   r3   rA   rB   rR   rn   )r   rK   s     r   put_manifestzPush.put_manifest   s    OO.55^^%(4 	6 	6 ^^$$V,II!!$$cii&;&;&C&CII!!**
  	r   c           
         |sFdj                  | j                               }t        j                  j                  j
                  g}ndj                  | j                  D cg c]C  }dt        j                  j                  j                  j                  |j                  d      z   E c}      }dj                  | j                         ||      }t        j                  j                  j                  t        j                  j                  j
                  g}| j                  j                  |dd	|
      \  }}|j                  t        j                  j                  j                  k(  |j!                  d      fS c c}w )zFPOST to begin the upload process with optional cross-repo mount param.z{base_url}/blobs/uploads/)r;   &zfrom= z5{base_url}/blobs/uploads/?mount={digest}&{mount_from})r;   r   
mount_fromrN   NrO   r7   )r)   r.   r2   r3   rA   rn   joinr   r4   r5   quoter-   rR   r   r@   rD   rt   )	r   r   r!   r1   r?   repor   rE   rF   s	            r   rd   zPush._start_upload   sB   
 '..8H.Ic		--667n 88kk!d CII$$**00"E
E! 	j DJJ>>#Fz K Kc ))


'
')>)>)G)Gn  ??22Fn 3 FD. ;;#))//777*9MMMs   "AE?c                     | j                  |      rt        j                  d|       y| j                  ||       t        j                  d|       y)z@Upload a single layer, after checking whether it exists already.zLayer %s exists, skippingNzLayer %s pushed.)rG   re   rf   rr   rS   s      r   _upload_onezPush._upload_one  s?    ll.7NN5&!LL#V,r   c           	      ,   | j                  |      rt        | j                  t        j                        rM| j                         |j                         k(  rt        j                  d       yt        j                  d       nt        j                  d       n| j                  dk(  r(|j                         D ]  }| j                  ||        nt        j                  j                  | j                        5 }|j                         D ci c]"  }|j                  | j                  ||      ||f$ }}t        j                  j!                  |      D ]  }|j#                           	 ddd       | j%                  |       yc c}w # 1 sw Y    xY w)zWUpload 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)rL   r   r   r   r   ru   r   re   rf   r   blob_setr   
concurrentfuturesThreadPoolExecutorsubmitas_completedresultr{   )r   rK   r   executorfuture_to_paramsfutures         r   uploadzPush.upload  sI    E"	DJJ	0""$6
,,I
J
NO89	!	NN$&' % 00mm 1 %(0  ..*
* OOD,,eV<ufoM* 	 
 !((556FGF
--/ H% 	e
% %s   :F
'F46F
F

Fc                     | S r    r%   s    r   	__enter__zPush.__enter__1  s    Kr   c                     |r!t        j                  d| j                         y t        j                  d| j                         y )NzError during upload of: %szFinished upload of: %s)re   errorr   rf   )r   exception_typeunused_valueunused_tracebacks       r   __exit__zPush.__exit__4  s.    mm0$**=LL)4::6r   )Nr   r   )__name__
__module____qualname____doc__r#   r   r+   r.   r8   rG   rL   rT   r`   rh   rp   rr   ru   r{   rd   r   r   r   r   r   r   r   r   r   *   st    < 8&
*4
338G88>%2-$ !N6-B7r   r   c           
         t        j                  | ||t         j                        }|j                  dj	                  t        j
                  | j                        | j                  | j                  t        |             dt        j                  j                  j                  t        j                  j                  j                  g      \  }}y)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(   r-   entityDELETEr=   N)r   r   r   r@   r)   r*   r(   r-   r   r2   r3   rA   rB   rn   )r   r   r    docker_transport_rF   s         r   Deleter   <  s     !**4	+6+=+=? '..@GG##DMM2==__%	 H '
 ii++..		0E0E0N0NO / Q!^r   )r   
__future__r   r   r   re   concurrent.futuresr   containerregistry.clientr   r   containerregistry.client.v2r   r	   httplib2six.moves.http_clientr2   six.moves.urllib.parser   objectr   r   r   r   r   <module>r      sI    L &  %   1 0 3 4   N76 N7dQr   