<s> '''<STR_LIT>''' <EOL> from __future__ import absolute_import <EOL> import re <EOL> import os <EOL> import json <EOL> import time <EOL> import logging <EOL> import subprocess <EOL> import salt . defaults . exitcodes <EOL> import salt . utils <EOL> import salt . utils . nb_popen <EOL> import salt . utils . vt <EOL> log = logging . getLogger ( __name__ ) <EOL> SSH_PASSWORD_PROMPT_RE = re . compile ( r'<STR_LIT>' , re . M ) <EOL> KEY_VALID_RE = re . compile ( r'<STR_LIT>' ) <EOL> class NoPasswdError ( Exception ) : <EOL> pass <EOL> class KeyAcceptError ( Exception ) : <EOL> pass <EOL> def gen_key ( path ) : <EOL> '''<STR_LIT>''' <EOL> cmd = '<STR_LIT>' . format ( path ) <EOL> if not os . path . isdir ( os . path . dirname ( path ) ) : <EOL> os . makedirs ( os . path . dirname ( path ) ) <EOL> subprocess . call ( cmd , shell = True ) <EOL> class Shell ( object ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( <EOL> self , <EOL> opts , <EOL> host , <EOL> user = None , <EOL> port = None , <EOL> passwd = None , <EOL> priv = None , <EOL> timeout = None , <EOL> sudo = False , <EOL> tty = False , <EOL> mods = None , <EOL> identities_only = False ) : <EOL> self . opts = opts <EOL> self . host = host <EOL> self . user = user <EOL> self . port = port <EOL> self . passwd = str ( passwd ) if passwd else passwd <EOL> self . priv = priv <EOL> self . timeout = timeout <EOL> self . sudo = sudo <EOL> self . tty = tty <EOL> self . mods = mods <EOL> self . identities_only = identities_only <EOL> def get_error ( self , errstr ) : <EOL> '''<STR_LIT>''' <EOL> for line in errstr . split ( '<STR_LIT:\n>' ) : <EOL> if line . startswith ( '<STR_LIT>' ) : <EOL> return line <EOL> if line . startswith ( '<STR_LIT>' ) : <EOL> continue <EOL> if '<STR_LIT>' in line : <EOL> continue <EOL> return line <EOL> return errstr <EOL> def _key_opts ( self ) : <EOL> '''<STR_LIT>''' <EOL> options = [ <EOL> '<STR_LIT>' , <EOL> ] <EOL> if self . passwd : <EOL> options . append ( '<STR_LIT>' ) <EOL> else : <EOL> options . append ( '<STR_LIT>' ) <EOL> if self . opts . get ( '<STR_LIT>' , ( <NUM_LIT:0> , ) ) > ( <NUM_LIT:4> , <NUM_LIT:9> ) : <EOL> options . append ( '<STR_LIT>' ) <EOL> options . append ( '<STR_LIT>' . format ( self . timeout ) ) <EOL> if self . opts . get ( '<STR_LIT>' ) : <EOL> options . append ( '<STR_LIT>' ) <EOL> if self . opts . get ( '<STR_LIT>' ) : <EOL> options . extend ( [ '<STR_LIT>' , <EOL> '<STR_LIT>' ] ) <EOL> known_hosts = self . opts . get ( '<STR_LIT>' ) <EOL> if known_hosts and os . path . isfile ( known_hosts ) : <EOL> options . append ( '<STR_LIT>' . format ( known_hosts ) ) <EOL> if self . port : <EOL> options . append ( '<STR_LIT>' . format ( self . port ) ) <EOL> if self . priv : <EOL> options . append ( '<STR_LIT>' . format ( self . priv ) ) <EOL> if self . user : <EOL> options . append ( '<STR_LIT>' . format ( self . user ) ) <EOL> if self . identities_only : <EOL> options . append ( '<STR_LIT>' ) <EOL> ret = [ ] <EOL> for option in options : <EOL> ret . append ( '<STR_LIT>' . format ( option ) ) <EOL> return '<STR_LIT>' . join ( ret ) <EOL> def _passwd_opts ( self ) : <EOL> '''<STR_LIT>''' <EOL> options = [ '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ] <EOL> if self . opts [ '<STR_LIT>' ] > ( <NUM_LIT:4> , <NUM_LIT:9> ) : <EOL> options . append ( '<STR_LIT>' ) <EOL> options . append ( '<STR_LIT>' . format ( self . timeout ) ) <EOL> if self . opts . get ( '<STR_LIT>' ) : <EOL> options . append ( '<STR_LIT>' ) <EOL> if self . opts . get ( '<STR_LIT>' ) : <EOL> options . extend ( [ '<STR_LIT>' , <EOL> '<STR_LIT>' ] ) <EOL> if self . passwd : <EOL> options . extend ( [ '<STR_LIT>' , <EOL> '<STR_LIT>' ] ) <EOL> else : <EOL> options . extend ( [ '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' ] ) <EOL> if self . port : <EOL> options . append ( '<STR_LIT>' . format ( self . port ) ) <EOL> if self . user : <EOL> options . append ( '<STR_LIT>' . format ( self . user ) ) <EOL> if self . identities_only : <EOL> options . append ( '<STR_LIT>' ) <EOL> ret = [ ] <EOL> for option in options : <EOL> ret . append ( '<STR_LIT>' . format ( option ) ) <EOL> return '<STR_LIT>' . join ( ret ) <EOL> def _copy_id_str_old ( self ) : <EOL> '''<STR_LIT>''' <EOL> if self . passwd : <EOL> return "<STR_LIT>" . format ( <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' . format ( self . priv ) , <EOL> self . _passwd_opts ( ) , <EOL> self . port , <EOL> self . user , <EOL> self . host ) <EOL> return None <EOL> def _copy_id_str_new ( self ) : <EOL> '''<STR_LIT>''' <EOL> if self . passwd : <EOL> return "<STR_LIT>" . format ( <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' . format ( self . priv ) , <EOL> self . _passwd_opts ( ) , <EOL> self . port , <EOL> self . user , <EOL> self . host ) <EOL> return None <EOL> def copy_id ( self ) : <EOL> '''<STR_LIT>''' <EOL> stdout , stderr , retcode = self . _run_cmd ( self . _copy_id_str_old ( ) ) <EOL> if salt . defaults . exitcodes . EX_OK != retcode and '<STR_LIT>' in stderr : <EOL> stdout , stderr , retcode = self . _run_cmd ( self . _copy_id_str_new ( ) ) <EOL> return stdout , stderr , retcode <EOL> def _cmd_str ( self , cmd , ssh = '<STR_LIT>' ) : <EOL> '''<STR_LIT>''' <EOL> opts = '<STR_LIT>' <EOL> tty = self . tty <EOL> if ssh != '<STR_LIT>' : <EOL> tty = False <EOL> if self . passwd : <EOL> opts = self . _passwd_opts ( ) <EOL> if self . priv : <EOL> opts = self . _key_opts ( ) <EOL> return "<STR_LIT>" . format ( <EOL> ssh , <EOL> '<STR_LIT>' if ssh == '<STR_LIT>' else self . host , <EOL> '<STR_LIT>' if tty else '<STR_LIT>' , <EOL> opts , <EOL> cmd ) <EOL> def _old_run_cmd ( self , cmd ) : <EOL> '''<STR_LIT>''' <EOL> try : <EOL> proc = subprocess . Popen ( <EOL> cmd , <EOL> shell = True , <EOL> stderr = subprocess . PIPE , <EOL> stdout = subprocess . PIPE , <EOL> ) <EOL> data = proc . communicate ( ) <EOL> return data [ <NUM_LIT:0> ] , data [ <NUM_LIT:1> ] , proc . returncode <EOL> except Exception : <EOL> return ( '<STR_LIT>' , '<STR_LIT>' , None ) <EOL> def _run_nb_cmd ( self , cmd ) : <EOL> '''<STR_LIT>''' <EOL> try : <EOL> proc = salt . utils . nb_popen . NonBlockingPopen ( <EOL> cmd , <EOL> shell = True , <EOL> stderr = subprocess . PIPE , <EOL> stdout = subprocess . PIPE , <EOL> ) <EOL> while True : <EOL> time . sleep ( <NUM_LIT:0.1> ) <EOL> out = proc . recv ( ) <EOL> err = proc . recv_err ( ) <EOL> rcode = proc . returncode <EOL> if out is None and err is None : <EOL> break <EOL> if err : <EOL> err = self . get_error ( err ) <EOL> yield out , err , rcode <EOL> except Exception : <EOL> yield ( '<STR_LIT>' , '<STR_LIT>' , None ) <EOL> def exec_nb_cmd ( self , cmd ) : <EOL> '''<STR_LIT>''' <EOL> r_out = [ ] <EOL> r_err = [ ] <EOL> rcode = None <EOL> cmd = self . _cmd_str ( cmd ) <EOL> logmsg = '<STR_LIT>' . format ( cmd ) <EOL> if self . passwd : <EOL> logmsg = logmsg . replace ( self . passwd , ( '<STR_LIT:*>' * <NUM_LIT:6> ) ) <EOL> log . debug ( logmsg ) <EOL> for out , err , rcode in self . _run_nb_cmd ( cmd ) : <EOL> if out is not None : <EOL> r_out . append ( out ) <EOL> if err is not None : <EOL> r_err . append ( err ) <EOL> yield None , None , None <EOL> yield '<STR_LIT>' . join ( r_out ) , '<STR_LIT>' . join ( r_err ) , rcode <EOL> def exec_cmd ( self , cmd ) : <EOL> '''<STR_LIT>''' <EOL> cmd = self . _cmd_str ( cmd ) <EOL> logmsg = '<STR_LIT>' . format ( cmd ) <EOL> if self . passwd : <EOL> logmsg = logmsg . replace ( self . passwd , ( '<STR_LIT:*>' * <NUM_LIT:6> ) ) <EOL> if '<STR_LIT>' in logmsg or '<STR_LIT>' in logmsg : <EOL> log . debug ( '<STR_LIT>' ) <EOL> log . trace ( logmsg ) <EOL> else : <EOL> log . debug ( logmsg ) <EOL> ret = self . _run_cmd ( cmd ) <EOL> return ret <EOL> def send ( self , local , remote , makedirs = False ) : <EOL> '''<STR_LIT>''' <EOL> if makedirs : <EOL> self . exec_cmd ( '<STR_LIT>' . format ( os . path . dirname ( remote ) ) ) <EOL> cmd = '<STR_LIT>' . format ( local , self . host , remote ) <EOL> cmd = self . _cmd_str ( cmd , ssh = '<STR_LIT>' ) <EOL> logmsg = '<STR_LIT>' . format ( cmd ) <EOL> if self . passwd : <EOL> logmsg = logmsg . replace ( self . passwd , ( '<STR_LIT:*>' * <NUM_LIT:6> ) ) <EOL> log . debug ( logmsg ) <EOL> return self . _run_cmd ( cmd ) <EOL> def _run_cmd ( self , cmd , key_accept = False , passwd_retries = <NUM_LIT:3> ) : <EOL> '''<STR_LIT>''' <EOL> term = salt . utils . vt . Terminal ( <EOL> cmd , <EOL> shell = True , <EOL> log_stdout = True , <EOL> log_stdout_level = '<STR_LIT>' , <EOL> log_stderr = True , <EOL> log_stderr_level = '<STR_LIT>' , <EOL> stream_stdout = False , <EOL> stream_stderr = False ) <EOL> sent_passwd = <NUM_LIT:0> <EOL> ret_stdout = '<STR_LIT>' <EOL> ret_stderr = '<STR_LIT>' <EOL> old_stdout = '<STR_LIT>' <EOL> try : <EOL> while term . has_unread_data : <EOL> stdout , stderr = term . recv ( ) <EOL> if stdout : <EOL> ret_stdout += stdout <EOL> buff = old_stdout + stdout <EOL> else : <EOL> buff = stdout <EOL> if stderr : <EOL> ret_stderr += stderr <EOL> if buff and SSH_PASSWORD_PROMPT_RE . search ( buff ) : <EOL> if not self . passwd : <EOL> return '<STR_LIT>' , '<STR_LIT>' , <NUM_LIT> <EOL> if sent_passwd < passwd_retries : <EOL> term . sendline ( self . passwd ) <EOL> sent_passwd += <NUM_LIT:1> <EOL> continue <EOL> else : <EOL> return '<STR_LIT>' , '<STR_LIT>' , <NUM_LIT> <EOL> elif buff and KEY_VALID_RE . search ( buff ) : <EOL> if key_accept : <EOL> term . sendline ( '<STR_LIT:yes>' ) <EOL> continue <EOL> else : <EOL> term . sendline ( '<STR_LIT>' ) <EOL> ret_stdout = ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) . format ( stdout ) <EOL> return ret_stdout , '<STR_LIT>' , <NUM_LIT> <EOL> elif buff and buff . endswith ( '<STR_LIT>' ) : <EOL> mods_raw = json . dumps ( self . mods , separators = ( '<STR_LIT:U+002C>' , '<STR_LIT::>' ) ) + '<STR_LIT>' <EOL> term . sendline ( mods_raw ) <EOL> if stdout : <EOL> old_stdout = stdout <EOL> time . sleep ( <NUM_LIT> ) <EOL> return ret_stdout , ret_stderr , term . exitstatus <EOL> finally : <EOL> term . close ( terminate = True , kill = True ) </s>
