o
    Ó2.aˆ  ã                   @   sò   d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlmZ ddlmZ d dlmZ zd dlm  mZ W n eyN   d dlZY nw ejjZG dd„ de	j	ƒZG dd„ dejƒZG d	d
„ d
ejjƒZG dd„ deƒZdS )é    N)ÚBaseHTTPAdapteré   )Ú	constantsc                       sT   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
‡  ZS )Ú	SSHSocketc                    sj   t ƒ  tjtj¡ || _d | _d | _d| jv r!| j d¡\| _| _d| jv r0| j d¡\| _| _d | _	d S )Nú:ú@)
ÚsuperÚ__init__ÚsocketZAF_INETZSOCK_STREAMÚhostÚportÚuserÚsplitÚproc)Úselfr   ©Ú	__class__© ú:/usr/lib/python3/dist-packages/docker/transport/sshconn.pyr	      s   ÿ


zSSHSocket.__init__c                 K   s¦   dg}| j r|d| j g }| jr|d| jg }|d| jdg }d }tjs*dd„ }|}ttjƒ}| dd ¡ | d	d ¡ t	j
d
 |¡|dt	jt	jtjrLd n|d| _d S )NÚsshz-lz-pz--údocker system dial-stdioc                   S   s   t   t jt j¡ d S ©N)ÚsignalÚSIGINTÚSIG_IGNr   r   r   r   Úf2   s   zSSHSocket.connect.<locals>.fZLD_LIBRARY_PATHZSSL_CERT_FILEú T)ÚenvÚshellÚstdoutÚstdinZ
preexec_fn)r   r   r   r   ZIS_WINDOWS_PLATFORMÚdictÚosÚenvironÚpopÚ
subprocessÚPopenÚjoinÚPIPEr   )r   ÚkwargsÚargsZpreexec_funcr   r   r   r   r   Úconnect&   s*   
úzSSHSocket.connectc                 C   s6   | j r| j jjrtdƒ‚| j j |¡}| j j ¡  |S ©Nz<SSH subprocess not initiated.connect() must be called first.)r   r    ÚclosedÚ	ExceptionÚwriteÚflush)r   ÚdataZwrittenr   r   r   Ú_writeD   s
   zSSHSocket._writec                 C   s   |   |¡ d S r   ©r2   ©r   r1   r   r   r   ÚsendallL   s   zSSHSocket.sendallc                 C   s
   |   |¡S r   r3   r4   r   r   r   ÚsendO   s   
zSSHSocket.sendc                 C   s   | j stdƒ‚| j j |¡S r,   )r   r.   r   Úread)r   Únr   r   r   ÚrecvR   s   zSSHSocket.recvc                 C   s    | j s|  ¡  | | j j_| j jS r   )r   r+   r   Zchannel)r   Úmoder   r   r   ÚmakefileX   s   
zSSHSocket.makefilec                 C   s<   | j r| j jjr
d S | j j d¡ | j j ¡  | j  ¡  d S )Ns   

)r   r    r-   r/   r0   Z	terminate©r   r   r   r   Úclose_   s
   zSSHSocket.close)Ú__name__Ú
__module__Ú__qualname__r	   r+   r2   r5   r6   r9   r;   r=   Ú__classcell__r   r   r   r   r      s    r   c                       s&   e Zd Zd‡ fdd„	Zdd„ Z‡  ZS )ÚSSHConnectionNé<   c                    s&   t ƒ jd|d || _|| _|| _d S )NÚ	localhost)Útimeout)r   r	   Ússh_transportrE   Ússh_host)r   rF   rE   r   r   r   r   r	   h   s   ÿ
zSSHConnection.__init__c                 C   sP   | j r| j  ¡ }| | j¡ | d¡ nt| jƒ}| | j¡ | ¡  || _d S )Nr   )	rF   Zopen_sessionZ
settimeoutrE   Zexec_commandr   rG   r+   Úsock)r   rH   r   r   r   r+   p   s   


zSSHConnection.connect)NrC   N)r>   r?   r@   r	   r+   rA   r   r   r   r   rB   g   s    rB   c                       s2   e Zd ZdZd‡ fdd„	Zdd„ Zd	d
„ Z‡  ZS )ÚSSHConnectionPoolr   NrC   é
   c                    s6   t ƒ jd||d d | _|| _|r| ¡ | _|| _d S )NrD   )rE   Úmaxsize)r   r	   rF   rE   Úget_transportrG   )r   Ú
ssh_clientrE   rK   r   r   r   r   r	   €   s   ÿ

zSSHConnectionPool.__init__c                 C   s   t | j| j| jƒS r   )rB   rF   rE   rG   r<   r   r   r   Ú	_new_connŠ   s   zSSHConnectionPool._new_connc                 C   sj   d }z| j j| j|d}W n! ty   tj | d¡‚ tjy.   | jr,tj 	| d¡‚Y nw |p4|  
¡ S )N)ÚblockrE   zPool is closed.z>Pool reached maximum size and no more connections are allowed.)ÚpoolÚgetrO   ÚAttributeErrorÚurllib3Ú
exceptionsZClosedPoolErrorÚqueueZEmptyZEmptyPoolErrorrN   )r   rE   Zconnr   r   r   Ú	_get_conn   s   þù	zSSHConnectionPool._get_conn)NrC   rJ   N)r>   r?   r@   Zschemer	   rN   rV   rA   r   r   r   r   rI   }   s
    
rI   c                       sb   e Zd Zejjjg d¢ Zdejej	df‡ fdd„	Z
dd„ Zdd	„ Zddd„Z‡ fdd„Z‡  ZS )ÚSSHHTTPAdapter)ÚpoolsrE   rM   Ú
ssh_paramsÚmax_pool_sizerC   Fc                    sj   d | _ |s|  |¡ |  ¡  || _| d¡r|tdƒd … | _|| _|| _t|dd„ d| _	t
ƒ  ¡  d S )Nzssh://c                 S   s   |   ¡ S r   )r=   )Úpr   r   r   Ú<lambda>º   s    z)SSHHTTPAdapter.__init__.<locals>.<lambda>)Zdispose_func)rM   Ú_create_paramiko_clientÚ_connectrG   Ú
startswithÚlenrE   rZ   ÚRecentlyUsedContainerrX   r   r	   )r   Úbase_urlrE   Zpool_connectionsrZ   Z	shell_outr   r   r   r	   ª   s   

ÿzSSHHTTPAdapter.__init__c                 C   sB  t  d¡ t j¡ t ¡ | _tj 	|¡}|j
|j|jdœ| _tj d¡}tj |¡r’t ¡ }t|ƒ}| |¡ W d   ƒ n1 sBw   Y  | |j
¡}d|v r\t | jd ¡| jd< d|v rg|d | jd< |jd u rwd|v rw|d | jd< |jd u r‡d|v r‡|d | jd	< d
|v r’|d
 | jd< | j ¡  | j t ¡ ¡ d S )NÚparamiko)Úhostnamer   Úusernamez~/.ssh/configZproxycommandrH   rd   r   r   re   ZidentityfileZkey_filename)ÚloggingZ	getLoggerZsetLevelZWARNINGrc   Z	SSHClientrM   ÚurllibÚparseZurlparserd   r   re   rY   r"   ÚpathÚ
expanduserÚexistsZ	SSHConfigÚopenÚlookupZProxyCommandZssh_confZload_system_host_keysZset_missing_host_key_policyZWarningPolicy)r   rb   Zssh_config_fileÚconfr   Zhost_configr   r   r   r]   ¾   s8   
ý
ÿ
ÿ
z&SSHHTTPAdapter._create_paramiko_clientc                 C   s"   | j r| j jdi | j¤Ž d S d S )Nr   )rM   r+   rY   r<   r   r   r   r^   Ý   s   ÿzSSHHTTPAdapter._connectNc                 C   s¨   | j st| j | j| j| jdS | jj7 | j |¡}|r%|W  d   ƒ S | j r1| j  ¡ s1|  	¡  t| j | j| j| jd}|| j|< W d   ƒ |S 1 sMw   Y  |S )N)rM   rE   rK   r   )
rM   rI   rE   rZ   rG   rX   ÚlockrQ   rL   r^   )r   ZurlZproxiesrP   r   r   r   Úget_connectioná   s2   ü
ýü
ñïzSSHHTTPAdapter.get_connectionc                    s"   t ƒ  ¡  | jr| j ¡  d S d S r   )r   r=   rM   r<   r   r   r   r=   ü   s   
ÿzSSHHTTPAdapter.closer   )r>   r?   r@   ÚrequestsZadaptersZHTTPAdapterZ	__attrs__r   ZDEFAULT_NUM_POOLSZDEFAULT_MAX_POOL_SIZEr	   r]   r^   rp   r=   rA   r   r   r   r   rW   ¤   s    ý
rW   )rc   rU   Zurllib.parserg   Zrequests.adaptersrq   rf   r"   r   r
   r%   Z docker.transport.basehttpadapterr   Ú r   Zhttp.clientZclientZhttplibZrequests.packages.urllib3ZpackagesrS   ÚImportErrorÚ_collectionsra   r   ZHTTPConnectionrB   ZconnectionpoolZHTTPConnectionPoolrI   rW   r   r   r   r   Ú<module>   s,    ÿO'