<s> import time <EOL> import random <EOL> import logging <EOL> import threading <EOL> from plumbum . commands import BaseCommand , run_proc <EOL> from plumbum . lib import six <EOL> from plumbum . machines . base import PopenAddons <EOL> class ShellSessionError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class SSHCommsError ( EOFError ) : <EOL> """<STR_LIT>""" <EOL> class SSHCommsChannel2Error ( SSHCommsError ) : <EOL> """<STR_LIT>""" <EOL> class IncorrectLogin ( SSHCommsError ) : <EOL> """<STR_LIT>""" <EOL> class HostPublicKeyUnknown ( SSHCommsError ) : <EOL> """<STR_LIT>""" <EOL> shell_logger = logging . getLogger ( "<STR_LIT>" ) <EOL> class MarkedPipe ( object ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ] <EOL> def __init__ ( self , pipe , marker ) : <EOL> self . pipe = pipe <EOL> self . marker = marker <EOL> if six . PY3 : <EOL> self . marker = six . bytes ( self . marker , "<STR_LIT:ascii>" ) <EOL> def close ( self ) : <EOL> """<STR_LIT>""" "<STR_LIT>" <EOL> while self . readline ( ) : <EOL> pass <EOL> self . pipe = None <EOL> def readline ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . pipe is None : <EOL> return six . b ( "<STR_LIT>" ) <EOL> line = self . pipe . readline ( ) <EOL> if not line : <EOL> raise EOFError ( ) <EOL> if line . strip ( ) == self . marker : <EOL> self . pipe = None <EOL> line = six . b ( "<STR_LIT>" ) <EOL> return line <EOL> class SessionPopen ( PopenAddons ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , proc , argv , isatty , stdin , stdout , stderr , encoding ) : <EOL> self . proc = proc <EOL> self . argv = argv <EOL> self . isatty = isatty <EOL> self . stdin = stdin <EOL> self . stdout = stdout <EOL> self . stderr = stderr <EOL> self . encoding = encoding <EOL> self . returncode = None <EOL> self . _done = False <EOL> def poll ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _done : <EOL> return self . returncode <EOL> else : <EOL> return None <EOL> def wait ( self ) : <EOL> """<STR_LIT>""" <EOL> self . communicate ( ) <EOL> return self . returncode <EOL> def communicate ( self , input = None ) : <EOL> """<STR_LIT>""" <EOL> stdout = [ ] <EOL> stderr = [ ] <EOL> sources = [ ( "<STR_LIT:1>" , stdout , self . stdout ) ] <EOL> if not self . isatty : <EOL> sources . append ( ( "<STR_LIT:2>" , stderr , self . stderr ) ) <EOL> i = <NUM_LIT:0> <EOL> while sources : <EOL> if input : <EOL> chunk = input [ : <NUM_LIT:1000> ] <EOL> self . stdin . write ( chunk ) <EOL> self . stdin . flush ( ) <EOL> input = input [ <NUM_LIT:1000> : ] <EOL> i = ( i + <NUM_LIT:1> ) % len ( sources ) <EOL> name , coll , pipe = sources [ i ] <EOL> try : <EOL> line = pipe . readline ( ) <EOL> shell_logger . debug ( "<STR_LIT>" , name , line ) <EOL> except EOFError : <EOL> shell_logger . debug ( "<STR_LIT>" , name ) <EOL> self . proc . poll ( ) <EOL> returncode = self . proc . returncode <EOL> if returncode == <NUM_LIT:5> : <EOL> raise IncorrectLogin ( "<STR_LIT>" ) <EOL> elif returncode == <NUM_LIT:6> : <EOL> raise HostPublicKeyUnknown ( "<STR_LIT>" ) <EOL> msg = "<STR_LIT>" <EOL> msgerr = "<STR_LIT>" <EOL> raise SSHCommsChannel2Error ( msgerr ) if name == "<STR_LIT:2>" else SSHCommsError ( msg ) <EOL> if not line : <EOL> del sources [ i ] <EOL> else : <EOL> coll . append ( line ) <EOL> if self . isatty : <EOL> stdout . pop ( <NUM_LIT:0> ) <EOL> try : <EOL> self . returncode = int ( stdout . pop ( - <NUM_LIT:1> ) ) <EOL> except ( IndexError , ValueError ) : <EOL> self . returncode = "<STR_LIT>" <EOL> self . _done = True <EOL> stdout = six . b ( "<STR_LIT>" ) . join ( stdout ) <EOL> stderr = six . b ( "<STR_LIT>" ) . join ( stderr ) <EOL> return stdout , stderr <EOL> class ShellSession ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , proc , encoding = "<STR_LIT>" , isatty = False , connect_timeout = <NUM_LIT:5> ) : <EOL> self . proc = proc <EOL> self . encoding = proc . encoding if encoding == "<STR_LIT>" else encoding <EOL> self . isatty = isatty <EOL> self . _current = None <EOL> if connect_timeout : <EOL> def closer ( ) : <EOL> shell_logger . error ( "<STR_LIT>" , proc , connect_timeout ) <EOL> self . close ( ) <EOL> timer = threading . Timer ( connect_timeout , self . close ) <EOL> timer . start ( ) <EOL> self . run ( "<STR_LIT>" ) <EOL> if connect_timeout : <EOL> timer . cancel ( ) <EOL> def __enter__ ( self ) : <EOL> return self <EOL> def __exit__ ( self , t , v , tb ) : <EOL> self . close ( ) <EOL> def __del__ ( self ) : <EOL> try : <EOL> self . close ( ) <EOL> except Exception : <EOL> pass <EOL> def alive ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . proc and self . proc . poll ( ) is None <EOL> def close ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . alive ( ) : <EOL> return <EOL> try : <EOL> self . proc . stdin . write ( six . b ( "<STR_LIT>" ) ) <EOL> self . proc . stdin . flush ( ) <EOL> time . sleep ( <NUM_LIT> ) <EOL> except ( ValueError , EnvironmentError ) : <EOL> pass <EOL> for p in [ self . proc . stdin , self . proc . stdout , self . proc . stderr ] : <EOL> try : <EOL> p . close ( ) <EOL> except Exception : <EOL> pass <EOL> try : <EOL> self . proc . kill ( ) <EOL> except EnvironmentError : <EOL> pass <EOL> self . proc = None <EOL> def popen ( self , cmd ) : <EOL> """<STR_LIT>""" <EOL> if self . proc is None : <EOL> raise ShellSessionError ( "<STR_LIT>" ) <EOL> if self . _current and not self . _current . _done : <EOL> raise ShellSessionError ( "<STR_LIT>" ) <EOL> if isinstance ( cmd , BaseCommand ) : <EOL> full_cmd = cmd . formulate ( <NUM_LIT:1> ) <EOL> else : <EOL> full_cmd = cmd <EOL> marker = "<STR_LIT>" % ( time . time ( ) * random . random ( ) , ) <EOL> if full_cmd . strip ( ) : <EOL> full_cmd += "<STR_LIT>" <EOL> else : <EOL> full_cmd = "<STR_LIT>" <EOL> full_cmd += "<STR_LIT>" % ( marker , ) <EOL> if not self . isatty : <EOL> full_cmd += "<STR_LIT>" % ( marker , ) <EOL> if self . encoding : <EOL> full_cmd = full_cmd . encode ( self . encoding ) <EOL> shell_logger . debug ( "<STR_LIT>" , full_cmd ) <EOL> self . proc . stdin . write ( full_cmd + six . b ( "<STR_LIT:\n>" ) ) <EOL> self . proc . stdin . flush ( ) <EOL> self . _current = SessionPopen ( self . proc , full_cmd , self . isatty , self . proc . stdin , <EOL> MarkedPipe ( self . proc . stdout , marker ) , MarkedPipe ( self . proc . stderr , marker ) , <EOL> self . encoding ) <EOL> return self . _current <EOL> def run ( self , cmd , retcode = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> return run_proc ( self . popen ( cmd ) , retcode ) </s>
