
     3                         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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_image)docker_image_listc                     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_2/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dZd Z	 ddZd Zd Zy)Pushz6Push encapsulates a Registry v2.2 Docker push session.Nc                     || _         t        j                  |||t        j                        | _        || _        || _        y)ap  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__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/   r3   r4   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                         g      \  }}|j                  t
        j                  j                  j                  k(  S )2Check the remote for the given manifest by digest.z{base_url}/manifests/{digest}r;   GETr?   r@   accepted_mimes)r   rA   r*   r/   r   r3   r4   rB   rC   rD   
media_typerE   r   imagerF   rG   s       r   manifest_existszPush.manifest_existsg   s    
  ??22'..^^%elln 	/ 	>II!!$$cii&;&;&E&E
 ((*+ 3 -D. ;;#))//2222r   c                     ||j                         k(  r|j                         j                  d      S |j                  |      S )Nutf8)config_blobconfig_fileencodeblobr   rP   r   s      r   	_get_blobzPush._get_blobw   s<    ""$$ ''//::fr   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   rA   r*   r/   rY   r3   r4   rB   CREATEDrX   s      r   _monolithic_uploadzPush._monolithic_upload|   s_    OO3::^^%f 	; 	6^^E6*		--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)r3   r4   r5   r6   urlsplitparse_qs	urlencode
urlunsplit)	r   r2   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.PUTr\   )_start_uploadr   logginginfork   r   rA   rY   r3   r4   rB   r^   )r   rP   r   mountedr8   s        r   _put_uploadzPush._put_upload   s    **64;;?GXll&/&1HOO^^E6*		--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 )Nrm   PATCHzapplication/octet-streamr?   r]   content_typer@   r8   rn   r\   )ro   r   rp   rq   r9   r   r	   DockerImagerY   r   rA   r3   r4   rB   
NO_CONTENTACCEPTEDr^   rk   )r   sourcer   rr   r8   rW   rF   rG   s           r   patch_uploadzPush.patch_upload   s-   **64;;?GXll&/%%h/HD&,223^^FF+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)r|   rX   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                         g      \  }}|j                  t        j                  j                  j                  k(  ry|j                  d      S )rJ   z{base_url}/manifests/{tag})r<   r   rK   rL   Nzdocker-content-digest)r   rA   r*   r/   r   r   r3   r4   rB   rC   rD   rN   rE   getrO   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           	         |r|j                         }nt        | j                        }| j                  j	                  dj                  | j                         |      d|j                         |j                         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_digestrn   rv   N)r   r   r   r   rA   r*   r/   manifestrN   r3   r4   rB   rC   r^   rz   )r   rP   
use_digestr   s       r   put_manifestzPush.put_manifest   s    
 llnm$TZZ0mOO.55^^%] 	6 	D^^%%'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_fromr[   Nr\   r8   )r*   r/   r3   r4   rB   rz   joinr   r5   r6   quoter.   r^   r   rA   rE   r   )	r   r   r"   r2   r@   repor   rF   rG   s	            r   ro   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.)rH   rp   rq   r~   rX   s      r   _upload_onezPush._upload_one  s?    ll.7NN5&!LL#V,r   c           	         | j                  |      rt        | j                  t        j                        rO| j                  |      |j                         k(  rt        j                  d       yt        j                  d       n4t        j                  d       nt        |t        j                        r)|D ]#  \  }}|5  | j                  |d       dd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# 1 sw Y   xY wc c}w # 1 sw Y   /xY w)	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)rQ   r   r   r   r   r   r   rp   rq   
image_listDockerImageListuploadr   distributable_blob_setr   
concurrentfuturesThreadPoolExecutorsubmitas_completedresultr   )	r   rP   r   _childr   executorfuture_to_paramsfutures	            r   r   zPush.upload$  s    E"	DJJ	0""5)U\\^;
,,I
J
NO89	E:55	6(!U
++e+
- U  
!	002&' 3 00mm 1 %(0  668
8 OOD,,eV<ufoM8 	 
 !((556FGF
--/ H% 	e
3! U
% %s*    G G'G:6GG	GG(c                     | S r    r&   s    r   	__enter__zPush.__enter__M  s    Kr   c                     |r!t        j                  d| j                         y t        j                  d| j                         y )NzError during upload of: %szFinished upload of: %s)rp   errorr   rq   )r   exception_typeunused_valueunused_tracebacks       r   __exit__zPush.__exit__P  s.    mm0$**=LL)4::6r   )Nr   )Fr   )__name__
__module____qualname____doc__r$   r   r,   r/   r9   rH   rQ   rY   r_   rk   rs   r|   r~   r   r   ro   r   r   r   r   r   r   r   r   r   *   s    > 8&
*4
33 
8G88@%2-0 . !N6-  &4R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 creds 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   rA   r*   r+   r)   r.   r   r3   r4   rB   rC   rz   )r   r    r!   docker_transportr   rG   s         r   Deleter   X  s     !**4	+6+=+=? '..@GG##DMM2==__%	 H '
 ii++..		0E0E0N0NO / Q!^r   )r   
__future__r   r   r   rp   concurrent.futuresr   containerregistry.clientr   r   containerregistry.client.v2_2r   r	   r
   r   httplib2six.moves.http_clientr3   six.moves.urllib.parser   objectr   r   r   r   r   <module>r      sL    L &  %   1 0 5 6 I   j76 j7\	Qr   