U
    k&p[7.                     @   st   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 Zdd Z	dd Z
dd	 Zd
d Zdd ZdS )    Nc                 O   s   d}i }|D ]*\}}|||< ||kr|| ||< ||= qt | f||\}}}	|dkrdd| ||	f }
|d r|d rt|
 n|d rt|
 t|
|S )aX  Run external command or pipeline.

    Example: ``runcmd(['grep', 'foo'], ['wc', '-l'],
                      feed_stdin='foo
bar
')``

    Return the standard output of the command.

    Raise ``cliapp.AppException`` if external command returns
    non-zero exit code. ``*args`` and ``**kwargs`` are passed
    onto ``subprocess.Popen``.

    ))ignore_failF)	log_errorTr   zCommand failed: %s
%s
%s r   r   )runcmd_uncheckedjoinlogginginfoerrorcliappZAppException)argvargskwargsZour_optionsZoptsnamedefaultZ	exit_codeouterrmsg r   //usr/lib/python3/dist-packages/cliapp/runcmd.pyruncmd   s"    

r   c              
      s   | gt | }td|  fdd}dd }|dd}|dtj}|d	tj}|d
tj}|d|}	|d|}
|dd}|dd}z*t|||| }t||||||	|
||	W S  tk
r } z,|jtj	kr|j
dkr| d |_
|n W 5 d}~X Y nX dS )zRun external command or pipeline.

    Return the exit code, and contents of standard output and error
    of the command.

    See also ``runcmd``.

    zrun external command: %rc                    s"   |  kr |  } | = |S |S d S Nr   )r   r   valuer   r   r   	pop_kwargQ   s
    z#runcmd_unchecked.<locals>.pop_kwargc                 S   s   d S r   r   )_r   r   r   noopY   s    zruncmd_unchecked.<locals>.noop
feed_stdin stdinstdoutstderrstdout_callbackstderr_callbackoutput_timeoutNtimeout_callbackr   )listr   debug
subprocessPIPE_build_pipeline_run_pipelineOSErrorerrnoZENOENTfilename)r   argvsr   r   r   r   
pipe_stdinpipe_stdoutpipe_stderrr!   r"   r#   r$   Zpipelineer   r   r   r   D   s@    





   
r   c                 C   s   g }|t jkr t \}}|}n|}t| D ]\}	}
|	dkrV|	t| d krV|}|}nD|	dkrj|}t j}n0|	t| d kr|d j}|}n|d j}t j}t j|
f|||dd|}|	dkr|  |	| q,|t jkrt| t
|d|d _|S )Nr      T)r   r   r    Z	close_fdsrb)r'   r(   ospipe	enumeratelenr   Popencloseappendfdopenr    )r.   r/   r0   r1   r   procsZrpipeZwpiper    ir   r   r   pr   r   r   r)   w   s<    


 

r)   c	              
      s  ddg }	g }
d}d}t   }d}d}dd }|rP|tjkrP|d j  tjkrl|d j   tjkr|d j   fdd}|s| rg }s̈tjkr|d j s tjkr|d j g }|tjkr|t|k r|d j |s$|rzt		||g |\}}}W nD t	j
k
r } z"|jd tjkrpW Y 
qڂ W 5 d }~X Y nX nqt   }|| }|d k	o||k}d j|kr|t|k r||||  }d j| |t|7 }|t|krd j  d j|krbd j|}|rZ||}|d krN|}|	| nd	d}d j|krd j|}|r||}|d kr|}|
| nd	d}|r|r| }|rd	}q|rd	}q|s| rD ]}|jd kr|  qqd
d D p dg}d jd k	r@d j  d jd k	r^d j  d jd k	r|d j  |d d|	d|
fS )NFr   i   c                 S   s.   t  | t jd}|tjB }t  | t j| d S )Nr   )fcntlZF_GETFLr6   
O_NONBLOCKZF_SETFL)fdflagsr   r   r   set_nonblocking   s    
z&_run_pipeline.<locals>.set_nonblockingr4   c                     sT   D ]} |    qD ]} | jd kr dS qtjkr>s>dS  tjkrPsPdS dS )NTF)Zpoll
returncoder'   r(   )r@   r1   r0   r>   Z
stderr_eofZ
stdout_eofr   r   still_running   s    

z$_run_pipeline.<locals>.still_runningTc                 S   s   g | ]}|j d kr|j qS )r   )rF   ).0r@   r   r   r   
<listcomp>  s     
 z!_run_pipeline.<locals>.<listcomp>    )timer'   r(   r   filenor   r    r<   r9   selectr	   r   r,   ZEINTRwriter;   readrF   waitr   )r>   r   r/   r0   r1   r!   r"   r#   r$   r   r   posZio_sizeZlatest_outputZtimeout_quitZtimeoutrE   rH   ZrlistZwlistrwr   r2   ZnowZtime_since_outputdataZdata_newresultr@   Z
errorcodesr   rG   r   r*      s    





r*   c                 C   sr   d}d}d}d}t || | | }g }| D ]:}||krD|| q,|dkrX|d q,|d|  q,d|S )	z#Return a shell-quoted version of s.ZabcdefghijklmnopqrstuvwxyzZABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789z-_/=.,:'z"'"z'%c'r   )setr<   r   )sZlower_asciiZupper_asciiZdigitsZpunctuationZsafeZquotedcr   r   r   shell_quote  s    r\   c              
   K   s   dg}| dd}|r"|d n|dkr4|d | dg }|ttt| ||  |d | d	d}|r|tttd
ddd|g |ttt| }t|f|S )aD  Run command in argv on remote host target.

    This is similar to runcmd, but the command is run on the remote
    machine. The command is given as an argv array; elements in the
    array are automatically quoted so they get passed to the other
    side correctly.

    An optional ``tty=`` parameter can be passed to ``ssh_runcmd`` in
    order to force or disable pseudo-tty allocation. This is often
    required to run ``sudo`` on another machine and might be useful
    in other situations as well. Supported values are ``tty=True`` for
    forcing tty allocation, ``tty=False`` for disabling it and
    ``tty=None`` for not passing anything tty related to ssh.

    With the ``tty`` option,
    ``cliapp.runcmd(['ssh', '-tt', 'user@host', '--', 'sudo', 'ls'])``
    can be written as
    ``cliapp.ssh_runcmd('user@host', ['sudo', 'ls'], tty=True)``
    which is more intuitive.

    Arbitrary command line options to the ssh command can be given
    with the ``ssh_options`` argument. For example:
    ``cliapp.ssh_runcmd(
    'user@host', ['sudo', 'ls'], ssh_options=['-oStrictHostChecking=no'])``

    The remote command is run in the user's home directory, by
    default. The directory can be changed with the keyword argument
    ``remote_cwd``.

    The target is given as-is to ssh, and may use any syntax ssh
    accepts.

    Environment variables may or may not be passed to the remote
    machine: this is dependent on the ssh and sshd configurations.
    Invoke env(1) explicitly to pass in the variables you need to
    exist on the other end.

    Pipelines are not supported.

    ZsshttyNz-ttFz-TZssh_optionsz--
remote_cwdZshz-czcd "$1" && shift && exec "$@"-)popr<   extendr%   mapr\   r   )targetr   r   Zssh_argvr]   Zmore_optionsr^   Z
local_argvr   r   r   
ssh_runcmd0  s*    *



  
rd   )r,   rA   r   r6   rN   r'   rL   r
   r   r   r)   r*   r\   rd   r   r   r   r   <module>   s   &3/u