o
    3gC                     @  s  d dl m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
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mZmZ zd dlZW n eya   G d
d dZe ZY nw edZG dd deZG dd deZG dd dZ	dddZdS )    )annotationsNshquote)ProcessLineTimedOut
iter_lines)PopenAddons)BaseRemoteMachine)ShellSession)	LocalPath)
RemotePathStatResc                   @  s   e Zd Zdd Zdd ZdS )paramikoc                 C  s   dS )NF selfr   r   Y/home/garg/my-data/venv/lib/python3.10/site-packages/plumbum/machines/paramiko_machine.py__bool__      zparamiko.__bool__c                 C     t d)NzNo module named paramiko)ImportErrorr   namer   r   r   __getattr__      zparamiko.__getattr__N)__name__
__module____qualname__r   r   r   r   r   r   r      s    r   zplumbum.paramikoc                   @  sb   e Zd Z			dddZdd Zdd Zdd	 Zed
d ZeZ	dd Z
dd ZdddZeZdS )ParamikoPopenNc	           	      C  sH   || _ |j| _|| _|| _|| _|| _d | _d | _|| _|| _	|| _
d S N)argvchannelstdinstdoutstderrcustom_encoding
returncodepid
stdin_filestdout_filestderr_file)	r   r   r!   r"   r#   encodingr'   r(   r)   r   r   r   __init__#   s   
zParamikoPopen.__init__c                 C  s"   | j d u r| j r|  S | j S r   )r%   r    exit_status_readywaitr   r   r   r   poll:   s   zParamikoPopen.pollc                 C  s,   | j d u r| j  | jj| _ |   | j S r   )r%   r    recv_exit_statusexit_statuscloser   r   r   r   r-   ?   s
   


zParamikoPopen.waitc                 C  s"   | j   | j   | j   d S r   )r    shutdown_readshutdown_writer1   r   r   r   r   r1   F   s   

zParamikoPopen.closec                   C  r   )Nz6Cannot kill remote processes, we don't have their PIDs)OSErrorr   r   r   r   killK   s   zParamikoPopen.killc                 C  s   t  r   NotImplementedError)r   sigr   r   r   send_signalT   s   zParamikoPopen.send_signalc              	   C  sB  g }g }| j }d|| j| jfd|| j| jfg}d}|r}|rPz| }W n ttfy0   d }Y nw t	d| |sE|
  d }| j
  n| j| | j  |d t| }|| \}}}	}
|	 }|sj||= n|
rv|
| |
  n|| |s|   ddd |D | j}dd	d |D | j}||fS )
N12r   zcommunicate: %r    c                 s      | ]}|V  qd S r   r   .0sr   r   r   	<genexpr>{       z,ParamikoPopen.communicate.<locals>.<genexpr>c                 s  r>   r   r   r?   r   r   r   rB   |   rC   )r'   r"   r(   r#   r)   readline
ValueErrorr4   loggerdebugr1   r!   writeflushlenappendr-   joinencoder$   )r   r"   r#   infilesourcesiline_namecollpipeoutfiler   r   r   communicateW   sF   



zParamikoPopen.communicatec                 K  s$   |d urt dt| fdti|S )Nz=The 'timeout' parameter is not supported with ParamikoMachine_iter_lines)r7   r   rW   )r   timeoutkwargsr   r   r   r      s
   zParamikoPopen.iter_lines)NNNr   )r   r   r   r+   r.   r-   r1   staticmethodr5   	terminater9   rV   r   __iter__r   r   r   r   r   "   s    


(r   c                   @  s   e Zd ZdZG dd dejZ																d/d	d
Zdd Zdd Ze	dd Z
				d0ddddZ						d1ddZdd Zdd Zdd Zdd  Zd2d"d#Zd$d% Zd&d' Zd(d) Zd*d+ Zd3d-d.ZdS )4ParamikoMachinea	  
    An implementation of :class:`remote machine <plumbum.machines.remote.BaseRemoteMachine>`
    over Paramiko (a Python implementation of openSSH2 client/server). Invoking a remote command
    translates to invoking it over SSH ::

        with ParamikoMachine("yourhostname") as rem:
            r_ls = rem["ls"]
            # r_ls is the remote `ls`
            # executing r_ls() is equivalent to `ssh yourhostname ls`, only without
            # spawning a new ssh client

    :param host: the host name to connect to (SSH server)

    :param user: the user to connect as (if ``None``, the default will be used)

    :param port: the server's port (if ``None``, the default will be used)

    :param password: the user's password (if a password-based authentication is to be performed)
                     (if ``None``, key-based authentication will be used)

    :param keyfile: the path to the identity file (if ``None``, the default will be used)

    :param load_system_host_keys: whether or not to load the system's host keys (from ``/etc/ssh``
                                  and ``~/.ssh``). The default is ``True``, which means Paramiko
                                  behaves much like the ``ssh`` command-line client

    :param missing_host_policy: the value passed to the underlying ``set_missing_host_key_policy``
                                of the client. The default is ``None``, which means
                                ``set_missing_host_key_policy`` is not invoked and paramiko's
                                default behavior (reject) is employed

    :param encoding: the remote machine's encoding (defaults to UTF8)

    :param look_for_keys: set to False to disable searching for discoverable
                          private key files in ``~/.ssh``

    :param connect_timeout: timeout for TCP connection

    .. note:: If Paramiko 1.15 or above is installed, can use GSS_API authentication

    :param bool gss_auth: ``True`` if you want to use GSS-API authentication

    :param bool gss_kex: Perform GSS-API Key Exchange and user authentication

    :param bool gss_deleg_creds: Delegate GSS-API client credentials or not

    :param str gss_host: The targets name in the kerberos database. default: hostname

    :param bool get_pty: Execute remote commands with allocated pseudo-tty. default: False

    :param bool load_system_ssh_config: read system SSH config for ProxyCommand configuration. default: False
    c                   @  s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )zParamikoMachine.RemoteCommandc                 G     t S r   NotImplementedr   _r   r   r   __or__   r   z$ParamikoMachine.RemoteCommand.__or__c                 G  r^   r   r_   ra   r   r   r   __gt__   r   z$ParamikoMachine.RemoteCommand.__gt__c                 G  r^   r   r_   ra   r   r   r   
__rshift__   r   z(ParamikoMachine.RemoteCommand.__rshift__c                 G  r^   r   r_   ra   r   r   r   __ge__   r   z$ParamikoMachine.RemoteCommand.__ge__c                 G  r^   r   r_   ra   r   r   r   __lt__   r   z$ParamikoMachine.RemoteCommand.__lt__c                 G  r^   r   r_   ra   r   r   r   
__lshift__   r   z(ParamikoMachine.RemoteCommand.__lshift__N)	r   r   r   rc   rd   re   rf   rg   rh   r   r   r   r   RemoteCommand   s    ri   NTutf8r   Fc                 C  s  || _ i }|r| d| | _||d< n|| _t | _|r#| j  |d ur+||d< |d ur3||d< |d ur;||d< |d urE| j| |	d urM|	|d< |
d urU|
|d< |rk||d< ||d	< ||d
< |sg|}||d< |rt }tt	j
ddd}|| W d    n1 sw   Y  tt ||}t|d |d< W d    n1 sw   Y  | jj|fi | || _d | _|| _t| ||
 d S )N@usernameportkey_filenamepasswordlook_for_keysrX   gss_authgss_kexgss_deleg_credsgss_hostz~/.ssh/configzutf-8)r*   proxycommandsock)host_fqhostr   	SSHClient_clientload_system_host_keysset_missing_host_key_policy	SSHConfigopenospath
expanduserparse
contextlibsuppressKeyErrorlookupProxyCommandconnect_keep_alive_sftp_get_ptyr   r+   )r   rw   userrm   ro   keyfiler{   missing_host_policyr*   rp   connect_timeout
keep_aliverq   rr   rs   rt   get_ptyload_system_ssh_configrY   
ssh_configf
hostConfigr   r   r   r+      sT   



zParamikoMachine.__init__c                 C  s   d| j  S )Nzparamiko://)rx   r   r   r   r   __str__     zParamikoMachine.__str__c                 C  s   t |  | j  d S r   )r   r1   rz   r   r   r   r   r1     s   
zParamikoMachine.closec                 C  s   | j s	| j | _ | j S )z
        Returns an SFTP client on top of the current SSH connection; it can be used to manipulate
        files directly, much like an interactive FTP/SFTP session
        )r   rz   	open_sftpr   r   r   r   sftp  s   zParamikoMachine.sftpvt100P      )new_sessionc                C  s   | j  }|| j | }|r|||| |d |  |dd}|dd}	|	dd}
t
dg||	|
| j}t|| j|S )NTwbrbz<shell>)rz   get_transportset_keepaliver   open_sessionr   set_combine_stderrinvoke_shellmakefilemakefile_stderrr   r$   r	   )r   isattytermwidthheightr   transchanr!   r"   r#   procr   r   r   session!  s   


zParamikoMachine.sessionc              
   C  s   g }| j  }	|r|	| |dt|p| jdg |	r.|d |dd |	 D  ||  d	|}
t
|
 | jj|
d| jd\}}}t||||| j|||d	S )
Ncdz&&envc                 s  s&    | ]\}}| d t | V  qdS )=Nr   )r@   kvr   r   r   rB   J  s   $ z(ParamikoMachine.popen.<locals>.<genexpr> r<   )r   )r'   r(   r)   )r   getdeltaupdateextendstrcwdrK   items	formulaterL   rF   rG   rz   exec_commandr   r   r$   )r   argsr!   r"   r#   r   r   r   r   envdeltacmdlinesisoser   r   r   popen8  s,   




zParamikoMachine.popenc                 C  s   t |trtd|t |tr|j| krtd|dt |tr*td|| t |tr3|n| |t |tr?|S t|S )Nzsrc of download cannot be zsrc % points to a different remote machinezdst of download cannot be )
isinstancer
   	TypeErrorr   remote	_downloadr   r   srcdstr   r   r   downloadZ  s   

zParamikoMachine.downloadc                 C     |  r | s| jt| |D ]}| |||j  qd S |  r4| jt|t||j  d S | jt|t| d S r   )is_direxistsr   mkdirr   r   r   getr   r   r   fnr   r   r   r   f      zParamikoMachine._downloadc                 C  s   t |trtd|t |trtd|t |tr*|j| kr*td|d| t |tr3|nt|t |tr>|S | |S )Nzsrc of upload cannot be zdst of upload cannot be zdst r   )r   r   r   r
   r   _uploadr   r   r   r   r   uploadq  s   

zParamikoMachine.uploadc                 C  r   r   )r   r   r   r   r   r   r   putr   r   r   r   r   }  r   zParamikoMachine._upload	localhostc                 C  sL   |r|dkrd}|rdnd}| j  }|| j |d||f|}t|S )a  Returns a Paramiko ``Channel``, connected to dhost:dport on the remote machine.
        The ``Channel`` behaves like a regular socket; you can ``send`` and ``recv`` on it
        and the data will pass encrypted over SSH. Usage::

            mach = ParamikoMachine("myhost")
            sock = mach.connect_sock(12345)
            data = sock.recv(100)
            sock.send("foobar")
            sock.close()
        r   ::1)r   r   r   r   )z	127.0.0.1r   zdirect-tcpip)rz   r   r   r   open_channelSocketCompatibleChannel)r   dportdhostipv6srcaddrr   r   r   r   r   connect_sock  s   
zParamikoMachine.connect_sockc                 C  s   | j t|S r   )r   listdirr   )r   r   r   r   r   _path_listdir  s   zParamikoMachine._path_listdirc                 C  s&   | j t|d}| }|  |S )Nr   )r   r~   r   readr1   )r   r   r   datar   r   r   
_path_read  s   zParamikoMachine._path_readc                 C  sD   | j rt|tr|| j }| jt|d}|| |  d S )Nr   )r$   r   r   rM   r   r~   rH   r1   )r   r   r   r   r   r   r   _path_write  s
   
zParamikoMachine._path_writec                 C  s   z
| j t|}W n ty$ } z|jtjkrW Y d }~d S  d }~ww t|jddd|j|j	|j
|j|jdf
}t|jrBd|_t|jrKd|_|S )Nr   	directoryzregular file)r   statr   r4   errnoENOENTr   st_modest_uidst_gidst_sizest_atimest_mtimeS_ISDIR	text_modeS_ISREG)r   r   steresr   r   r   
_path_stat  s4   zParamikoMachine._path_stat/c                 C  r   )Nz+This is not implemented on ParamikoMachine!r6   )r   commandr   r"   r#   rK   r   r   r   daemonic_popen  r   zParamikoMachine.daemonic_popen)NNNNTNrj   NNr   FNNNFF)Fr   r   r   )NNNFNN)r   F)r   NNT)r   r   r   __doc__r   ri   r+   r   r1   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r]      s`    5
>

"
r]   c                   @  s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
r   c                 C  s
   || _ d S r   )_chan)r   r   r   r   r   r+     s   
z SocketCompatibleChannel.__init__c                 C  s   t | j|S r   )getattrr   r   r   r   r   r     r   z#SocketCompatibleChannel.__getattr__c                 C      | j jr
ttjd| j |S NzBad file descriptor)r   closedr4   r   EBADFsend)r   rA   r   r   r   r       zSocketCompatibleChannel.sendc                 C  r   r  )r   r  r4   r   r  recv)r   countr   r   r   r    r  zSocketCompatibleChannel.recvN)r   r   r   r+   r   r  r  r   r   r   r   r     s
    r   c                 #  s    ddl mm   fdd}| D ](}jj r&dj|fV  jj r5dj|fV  	 d ur= nqjD ]}d|fV  qAjD ]}d|fV  qLd S )Nr   )
EVENT_READDefaultSelectorc                  3  s^      } |  jj 	 | }|s$r$tdtdd tdd |D ]\}}d V  q&q)NTzpopen line timeout expiredr   machine)registerr"   r    selectr   r   )selready_key_maskr	  r  line_timeoutr   r   r   selector  s   


z_iter_lines.<locals>.selectorr<   )
	selectorsr  r	  r"   r    
recv_readyrD   recv_stderr_readyr#   r.   )r   decodelinesizer  r  rb   rQ   r   r  r   rW     s    


rW   r   )
__future__r   r   r   loggingr   r   plumbum.commands.baser   plumbum.commands.processesr   r   plumbum.machines.baser   plumbum.machines.remoter   plumbum.machines.sessionr	   plumbum.path.localr
   plumbum.path.remoter   r   r   r   	getLoggerrF   r   r]   r   rW   r   r   r   r   <module>   s6    

g  K