
    i/                     0   d dl Z d dlZd dlZd dlmZmZmZ ddlmZm	Z	 ddl
mZ ddlmZmZmZ ddlmZmZmZ ddlmZmZ  ej.                  e      Z G d	 d
e      Z G d de      Z G d deee      Z G d de      Z G d de      Z G d de      Z y)    N)AnyCallableSequence   )
JsonObject	JsonValue)BridgeConfig)CockpitProblemCockpitProtocolCockpitProtocolError)EndpointRouterRoutingRule)SubprocessProtocolSubprocessTransportc                       e Zd Zy)	PeerErrorN)__name__
__module____qualname__     ./usr/lib/python3/dist-packages/cockpit/peer.pyr   r      s    r   r   c                       e Zd ZdefdZy)
PeerExited	exit_codec                     || _         y N)r   )selfr   s     r   __init__zPeerExited.__init__   s	    "r   N)r   r   r   intr    r   r   r   r   r      s    ## #r   r   c                       e Zd ZU ded<   ded<   def fdZd&d	Zd
ee   dee   de	de
j                  fdZd'dddedefdZd'dddeddfdZdeg df   ddfdZd&dZdeddfdZdededdfdZdefdZd(dZd&dZdedededdfdZdededdfdZdedededdfd Zdededdfd!Zd"dd#ddeddfd$Zd&d%Z  xZ!S ))Peerzlist[Callable[[], None]]done_callbacksz!asyncio.Future[JsonObject] | Noneinit_futurerouterc                     t         |   |       | j                          t        j                         j                         | _        g | _        y r   )superr    freeze_endpointasyncioget_running_loopcreate_futurer%   r$   )r   r&   	__class__s     r   r    zPeer.__init__!   s@      	"335CCE r   returnNc                    K   t         wr   )NotImplementedErrorr   s    r   do_connect_transportzPeer.do_connect_transport+   s     !!s   	argvenvkwargsc           	         K   t        j                         }t        d |D              }t        || |fdt        t        j
                  fi |i|S w)Nc              3   @   K   | ]  }|j                  d d        yw)=r   N)split).0es     r   	<genexpr>zPeer.spawn.<locals>.<genexpr>1   s     5AQ5s   r4   )r*   r+   dictr   osenviron)r   r3   r4   r5   loopuser_envs         r   spawnz
Peer.spawn.   sL     '')555"4t`bjj9UH9U`Y_``s   AA	init_hostz
str | Nonec                 8   K    j                   J d fd}t        j                   j                               j	                  |       	  j                    d{   }	 d _         j                         sj                          	 |<t        j                  d|         j                  ddd|d|  j                          |S 7 m# t
        t        f$ r  d{  7    w xY w# d _         j                         sj                          w w xY ww)	a  Request that the Peer is started and connected to the router.

        Creates the transport, connects it to the protocol, and participates in
        exchanging of init messages.  If anything goes wrong, the connection
        will be closed and an exception will be raised.

        The Peer starts out in a frozen state (ie: attempts to send messages to
        it will initially be queued). If init_host is not None then an init
        message is sent with the given 'host' field, plus any extra kwargs, and
        the queue is thawed. Otherwise, the caller is responsible for sending
        the init message and thawing the peer.

        In any case, the return value is the init message from the peer.
        Nc                     | u sJ 	 | j                          y # t        j                  $ r Y y t        $ r}j	                  |       Y d }~y d }~ww xY wr   )resultr*   CancelledError	Exceptionclose)taskexcconnect_taskr   s     r   _connect_task_donez&Peer.start.<locals>._connect_task_doneE   sM    <''' ))   

3 s    AAAAz$  sending init message back, host %sinitr   )commandversionhost)rJ   zasyncio.Task[None]r.   Nr   )r%   r*   create_taskr2   add_done_callbackr   BrokenPipeErrordonecancelloggerdebugwrite_controlthaw_endpoint)r   rC   r5   rM   init_messagerL   s   `    @r   startz
Peer.start4   s     +++	  **4+D+D+FG&&'9:	& "&!1!11L  $D  $$&##% LL?KDYVQYYRXY  5 2O, 	
 	  $D  $$&##% 'sI   A
DC CC $A(DC C*"C%#C**C- -*DDc                     dfd}t        j                   | j                  |fi |      j                  |       y )Nc                     | u sJ 	 | j                          y # t        t        t        t        j
                  f$ r Y y w xY wr   )rF   OSErrorr   r
   r*   rG   )rJ   
start_tasks    r   _start_task_donez2Peer.start_in_background.<locals>._start_task_donev   s@    :%%%Z9O9OP s    #A A )rJ   zasyncio.Task[JsonObject]r.   N)r*   rR   r\   rS   )r   rC   r5   ra   r`   s       @r   start_in_backgroundzPeer.start_in_backgroundu   s9    	 ((I)H)HI
$$%56r   callbackc                 :    | j                   j                  |       y r   )r$   append)r   rc   s     r   rS   zPeer.add_done_callback   s    ""8,r   c                      y r   r   r1   s    r   do_superuser_init_donezPeer.do_superuser_init_done       r   messagec                      y r   r   )r   ri   s     r   do_authorizezPeer.do_authorize   rh   r   rO   c                     |dk(  r=| j                   1t        j                  d       | j                   j                  |       y |dk(  r| j	                  |       y |dk(  r| j                          y t        d|       )NrN   z:Got init message with active init_future.  Setting result.	authorizezsuperuser-init-donez$Received unexpected control message )r%   rW   rX   
set_resultrk   rg   r   )r   rO   ri   s      r   transport_control_receivedzPeer.transport_control_received   st    f!1!1!=LLUV''0#g&--'')&)MgY'WXXr   c                 X    t         j                  d| j                  j                         y)NzPeer %s received unexpected EOFT)rW   rX   r-   r   r1   s    r   eof_receivedzPeer.eof_received   s      	68O8OPr   c                    t         j                  d| j                  j                  t	        |      |       || j                  d       nt        |t              rC|j                  dk(  r| j                  d       nz| j                  dd|j                          nYt        |t              r| j                  |j                         n-| j                  dd	|j                  j                   d
|       | j                  R| j                  j                         s8|| j                  j                  |       n| j                  j                          | j                  D ]	  } |         y )NzPeer %s connection lost %s %s
terminated)problem   z
no-cockpitzPeer exited with status )rt   ri   zinternal-error[z] )rW   rX   r-   r   typeshutdown_endpoint
isinstancer   r   r
   attrsr%   rU   set_exceptionrV   r$   )r   rK   rc   s      r   	do_closedzPeer.do_closed   s7   4dnn6M6MtTWyZ]^;""<"8Z(}}#&&|&<&&|G_`c`m`m_nEo&p^,""399-""+;-.s}}/E/E.Fb+P # R
 '0@0@0E0E0G  ..s3  '')++ 	HJ	r   c                 N   t        | j                  t              sJ t        j	                  d| j
                  j                  | j                  j                                | j                  j                         }t        |t              sJ | j                  t        |             y )NzPeer %s exited, status %d)ry   	transportr   rW   rX   r-   r   get_returncoder!   rI   r   )r   
returncodes     r   process_exitedzPeer.process_exited   sr    $..*=>>>0$..2I2I4>>KhKhKjk^^224
*c***

:j)*r   channelc                 X    | j                   t        d      | j                  |||       y )Nz7Received unexpected channel control message before init)r%   r   send_channel_controlr   r   rO   ri   s       r   channel_control_receivedzPeer.channel_control_received   s,    '&'`aa!!'7G<r   datac                 V    | j                   t        d      | j                  ||       y )Nz,Received unexpected channel data before init)r%   r   send_channel_datar   r   r   s      r   channel_data_receivedzPeer.channel_data_received   s*    '&'UVVw-r   c                 B    | j                   J | j                  |       y r   r%   rY   r   s       r   do_channel_controlzPeer.do_channel_control   "    '''7#r   c                 D    | j                   J | j                  ||       y r   )r%   write_channel_datar   s      r   do_channel_datazPeer.do_channel_data   s$    '''.r   rQ   groupc                 B    | j                   J | j                  |       y r   r   )r   rQ   r   ri   s       r   do_killzPeer.do_kill   r   r   c                 $    | j                          y r   )rI   r1   s    r   do_closezPeer.do_close   s    

r   r.   Nr   )rK   zException | Noner.   N)"r   r   r   __annotations__r   r    r2   r   strr   r*   	TransportrB   r   r   r\   rb   r   rS   rg   rk   ro   boolrq   r|   r   r   bytesr   r   r   r   r   __classcell__r-   s   @r   r#   r#      s   ..44!v !"a aHSM aS aU\UfUf a>\ >I >R\ >B
7\ 
7I 
7Z^ 
7-(2t8*< - -J 4 	Y# 	Y
 	Yt 	Yd 8+= =c =J =[_ =
.S . .$ .$# $ $j $UY $/s /% /D /$L $ $
 $W[ $r   r#   c                   f     e Zd ZU eed<   eed<   ee   ed<   ee   ed<   dedef fdZddZ	 xZ
S )	ConfiguredPeerconfigmethodargsr4   r&   c                     || _         |j                  | _        |j                  | _        |j                  | _        t        |   |       y r   )r   r   rB   r   r?   r4   r(   r    r   r&   r   r-   s      r   r    zConfiguredPeer.__init__   s8    mmLL	>> r   c                    K   | j                   J | j                  | j                   | j                         d {    y 7 wr   )r   rB   r4   r1   s    r   r2   z#ConfiguredPeer.do_connect_transport   s2     yy$$$jjDHH---s   8AA Ar   )r   r   r   r	   r   r   r   r   r    r2   r   r   s   @r   r   r      s:    K
3-	#!v !| !.r   r   c                   h     e Zd ZU eed<   eed<   ded<   dedef fdZdeddfd	Zdd
Z	ddZ
 xZS )PeerRoutingRuler   matchzPeer | Nonepeerr&   c                 b    t         |   |       || _        |j                  | _        d | _        y r   )r(   r    r   r   r   r   s      r   r    zPeerRoutingRule.__init__   s)     \\
	r   optionsr.   c                 "   | j                   j                         D ]I  \  }}||vrt        j                  d|        y |%||   |k7  s.t        j                  d|||   |        y  | j                  t        | j                  | j                        | _        | j                  j                  | j                         | j                  j                  sJ | j                  j                  | j                  j                         | j                  S )Nz+        rejecting because key %s is missingz;        rejecting because key %s has wrong value %s (vs %s))rC   )r   itemsrW   rX   r   r   r&   r   rS   peer_closedrC   rb   )r   r   keyvalues       r   
apply_rulezPeerRoutingRule.apply_rule   s     ****, 	JC'!JCP WS\U%:Z\_ahilamotu	 99&t{{DKK@DIII''(8(89;;((((II))DKK4I4I)Jyyr   c                     d | _         y r   )r   r1   s    r   r   zPeerRoutingRule.peer_closed  s	    	r   c                 R    | j                   | j                   j                          y y r   )r   rI   r1   s    r   shutdownzPeerRoutingRule.shutdown  s    99 IIOO !r   r   )r   r   r   r	   r   r   r   r    r   r   r   r   r   s   @r   r   r      sE    
v | *  (r   r   c                   J    e Zd ZU g Zded<   deddfdZdee   ddfd	Z	dd
Z
y)PeersRoutingRulezlist[PeerRoutingRule]rulesr   r.   zEndpoint | Nonec                 N   t         j                  dt        | j                               | j                  D ]X  }t         j                  d|j                  j
                         |j                  |      }|At         j                  d       |c S  t         j                  d       y )Nz    considering %d rulesz      considering %sz        selectedz      no peer rules matched)rW   rX   lenr   r   namer   )r   r   ruleendpoints       r   r   zPeersRoutingRule.apply_rule  s}    /TZZAJJ 	 DLL/1A1ABw/H#/0	  	23r   bridge_configsNc                 b   | j                   }g | _         |D ]  }|j                  sd|j                  v rt        |      D ]$  }|j                  |k(  s|j                  |        n t        | j                  |      }| j                   j                  |        |D ]  }|j                           y )NrQ   )
r   
privilegedr   listr   remover   r&   re   r   )r   r   	old_rulesr   r   s        r   set_configszPeersRoutingRule.set_configs'  s    JJ	
$ 	$F  Ffll$: Y <;;&($$T*< 't{{F;JJd#	$"  	DMMO	r   c                 F    | j                   D ]  }|j                           y r   )r   r   )r   r   s     r   r   zPeersRoutingRule.shutdown?  s    JJ 	DMMO	r   r   )r   r   r   r   r   r   r   r   r	   r   r   r   r   r   r   r     s>    %'E"'	* 	1B 	(<*@ T 0r   r   )!r*   loggingr>   typingr   r   r   jsonutilr   r   packagesr	   protocolr
   r   r   r&   r   r   r   
transportsr   r   	getLoggerr   rW   r   rH   r   r#   r   r   r   r   r   r   <module>r      s      	 * * + " K K 1 1 ?			8	$	 	# #
@?. @F.T .$$k $N({ (r   