
    )"                        S 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SK
r
SSK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Jr  SSKJr  SSKr " S S\5      rS r " S S\5      r S r!S r"S r#\RH                       S"S j5       r% " S S\5      r&S r'S r(S r)S r*\RV                  " SS94S jr,S  r-S! r.g)#z1Functions for reading the skaffold events stream.    )absolute_import)division)print_function)unicode_literalsN)json_stream)config)log)
properties)console_attr)update_manager)filesc                       \ rS rSrSrSrg)StopThreadError'   z-The thread has been stopped by a ThreadEvent. N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       /lib/googlecloudsdk/command_lib/code/skaffold.pyr   r   '   s    5r   r   c                     [        5       e)zRaise a KeyboardInterrupt.)KeyboardInterrupt)unused_signumunused_stacks     r   _KeyboardInterruptHandlerr   -   s    r   c                   *    \ rS rSrSrS rS rS rSrg)_SigInterruptedHandler2   z;Context manager to capture SIGINT and send it to a handler.c                     S U l         Xl        g N)_orig_handler_handler)selfhandlers     r   __init___SigInterruptedHandler.__init__5   s    DMr   c                     [         R                  " [         R                  5      U l        [         R                   " [         R                  U R                  5        g r#   )signal	getsignalSIGINTr$   r%   r&   s    r   	__enter__ _SigInterruptedHandler.__enter__9   s/    ))&--8D
MM&--/r   c                 b    [         R                   " [         R                  U R                  5        g r#   )r+   r-   r$   )r&   exc_type	exc_valuetbs       r   __exit___SigInterruptedHandler.__exit__=   s    
MM&--!3!34r   )r%   r$   N	r   r   r   r   r   r(   r/   r5   r   r   r   r   r    r    2   s    C05r   r    c                     [         R                  " 5       R                  (       ac  [        R                  R                  S/5      (       a>  [        R                  R                  [         R                  " 5       R                  SS5      $ g )Nskaffoldbin)	r   Pathssdk_rootr   UpdateManagerEnsureInstalledAndRestartospathjoinr   r   r   _FindOrInstallSkaffoldComponentrB   A   sP    lln""<<j\JJ77<<//
CC	r   c                      [         R                  R                  R                  R	                  5       =(       d'    [        5       =(       d    [        R                  " S5      n U (       d  [        S5      eU $ )z)Find the path to the skaffold executable.r9   zUnable to locate skaffold.)	r
   VALUEScodeskaffold_path_overrideGetrB   
file_utilsFindExecutableOnPathEnvironmentError)r9   s    r   _FindSkaffoldrK   H   s[     33779 2%'2%%j1  

7
88	/r   c                  j    [         R                  " [        R                  " [	        5       S/5      5      $ )zGet skaffold version string.version)sixensure_text
subprocesscheck_outputrK   r   r   r   
GetVersionrR   S   s#    	00-/91MN	OOr   c              #   x  #    [        5       SSU S/nU(       a	  USU-  /-  nU(       a	  USU-  /-  nU(       a  US/-  nU(       a	  USU-  /-  n[        [        5         [        R                  R                  5       nU(       a&  UR                  S UR                  5        5       5        [        R                  " 5       R                  (       aM  [        R                  " US	   [        R                  -   [        R                  " 5       R                  -   5      US	'    [        R                  " XgS
9nUv   [&        R(                  R+                  5         [&        R,                  R+                  5         SSS5        g! [          a#    WR#                  5         UR%                  5          Nqf = f! , (       d  f       g= f7f)a  Run skaffold and catch keyboard interrupts to kill the process.

Args:
  skaffold_config: Path to skaffold configuration yaml file.
  context_name: Kubernetes context name.
  namespace: Kubernetes namespace name.
  env_vars: Additional environment variables with which to run skaffold.
  debug: If true, turn on debugging output.
  events_port: If set, turn on the events api and expose it on this port.

Yields:
  The skaffold process.
devz-fz--port-forwardz--kube-context=%sz--namespace=%sz-vdebugz--rpc-http-port=%sc              3   ~   #    U  H3  u  p[         R                  " U5      [         R                  " U5      4v   M5     g 7fr#   )rN   
ensure_str).0namevalues      r   	<genexpr>Skaffold.<locals>.<genexpr>~   s0      6$4[T ..&u(=>$4s   ;=PATH)envN)rK   r    r   r?   environcopyupdateitemsr   r;   r<   rN   rV   pathseprP   Popenr   	terminatewaitsysstdoutflushstderr)	skaffold_configcontext_name	namespaceenv_varsdebugevents_portcmdr]   ps	            r   Skaffoldrr   X   s^    ( 
%8HI#,.//Cy())C
I;C ;.//C 78 **//
C	jj 6$,NN$46 6||~NN3v;#;#)<<>#:#:$; <c&k


3
(ag
 JJJJ) 98  kkmffh 98sC   AF:B=F)E94<F)0	F:9*F&#F)%F&&F))
F73F:c                   *    \ rS rSrSrS rS rS rSrg)PrintUrlThreadContext   a  Context manager that starts a thread that prints outs local urls.

When entering the context, start a thread that watches the skaffold events
stream api, find the portForward events, and prints out the local urls
for a service. This will continue until the context is exited.
c                     [         R                  " 5       U l        [         R                  " [        XU R                  4S9U l        g)zInitialize PrintUrlThreadContext.

Args:
  service_name: Name of the service.
  events_port: Port number of the skaffold events stream api.
)targetargsN)	threadingEvent_stopThread	_PrintUrl_thread)r&   service_namero   s      r   r(   PrintUrlThreadContext.__init__   s3     "DJ##4::FHDLr   c                 8    U R                   R                  5         g r#   )r~   startr.   s    r   r/   PrintUrlThreadContext.__enter__   s    LLr   c                 8    U R                   R                  5         g r#   )r{   set)r&   rx   s     r   r5   PrintUrlThreadContext.__exit__   s    JJNNr   )r{   r~   Nr7   r   r   r   rt   rt      s    	Hr   rt   c           	           [         R                  " [        UU5      5       n[        X05       H  nUR	                  5       (       a
    SSS5        g[
        R                  " 5       nSR                  UR                  SS9SU-  UR                  5       S9nUR                  S5        [        R                  R                  UR                  USS	95        M     SSS5        g! , (       d  f       g= f! [         a     gf = f)
a  Read the local url of a service from the event stream and print it.

Read the event stream api and find the portForward events. Print the local
url as determined from the portFoward events. This function will continuously
listen to the event stream and print out all local urls until eitherthe event
stream connection closes or the stop event is set.

Args:
  service_name: Name of the service.
  events_port: Port number of the skaffold events stream api.
  stop: threading.Event event.
Nz Service URL: {bold}{url}{normal}T)boldzhttp://localhost:%s/)r   urlnormal   blue)color)
contextlibclosing_OpenEventStreamRetryGetServiceLocalPortis_setr   GetConsoleAttrformatGetFontCodere   r	   statusPrintColorizer   )r   ro   stopresponseportconmsgs          r   r}   r}      s    			1+268 
9<D%h=$;;==

9 
9 ))+077d+&-??$ 8 & 			!

c89 >
9 
9 
9 
 
s;    C0 %CC0 BCC0 
C-)C0 -C0 0
C=<C=c                 z    [         R                  R                  R                  R	                  [        U 5      5      $ )z4Open a connection to the skaffold events api output.)rN   movesurllibrequesturlopen_GetEventsUrlro   s    r   OpenEventsStreamr      s(    				!	!	)	)-*D	EEr   c              #   h   #    [        U 5       H  n[        X!5      (       d  M  US   S   v   M!     g7f)zGet the local port for a service.

This function yields the new local port every time a new port forwarding
connection is created.

Args:
  response: urlopen response.
  service_name: Name of the service.

Yields:
  Local port number.
	portEvent	localPortN)ReadEventStream_IsPortEventForService)r   r   events      r   r   r      s1      x(ee22+{++ )s   22c              #      #    [         R                  " U 5       H&  n[        U[        5      (       d  M  US   S   nUv   M(     g7f)zRead the events from the skaffold event stream.

Args:
  response: urlopen response.

Yields:
  Events from the JSON payloads.
resultr   N)r   ReadJsonStream
isinstancedict)r   payloadr   s      r   r   r      s@      ++H5ggt$$Hg&E
K	 6s   AAr   )secondsc                 6   UR                  5       (       d   [        U 5      $ [        5       e! [        R                  R                  R
                  R                   a"    UR                  UR                  5       5         Of = fUR                  5       (       d  M  Ny)a  Open a connection to the skaffold events api output.

This function retries opening the connection until opening is succesful or
stop_event is set.

Args:
  events_port: Port of the events api.
  stop_event: A threading.Event object.
  retry_interval: Interval for which to sleep between tries.

Returns:
  urlopen response.
Raises:
  StopThreadError: The stop_event was set before a connection was established.
)
r   r   rN   r   r   errorURLErrorre   total_secondsr   )ro   
stop_eventretry_intervals      r   r   r      s{    $ 6k** 	 99!!** 6oon22456 s   
, AB ?B c                 H    SR                  [        R                  " U 5      S9$ )Nz(http://localhost:{events_port}/v1/eventsr   )r   rN   	text_typer   s    r   r   r     s&    	3	:	:--, 
; 
. .r   c                 J    U R                  S0 5      R                  S5      U:H  $ )Nr   resourceName)get)r   r   s     r   r   r     s#    	;	#	'	'	7<	GGr   )NNNFN)/r   
__future__r   r   r   r   r   datetimeos.pathr?   r+   rP   rf   ry   googlecloudsdk.command_lib.coder   googlecloudsdk.corer   r	   r
   googlecloudsdk.core.consoler   googlecloudsdk.core.updaterr   googlecloudsdk.core.utilr   rH   rN   BaseExceptionr   r   objectr    rB   rK   rR   contextmanagerrr   rt   r}   r   r   r   	timedeltar   r   r   r   r   r   <module>r      s    8 &  % '      
  7 & # * 4 6 8 
6m 6
5V 5P
 3 3lF 4BF
,$$ *2););A)F4.
Hr   