|
|
@@ -187,17 +187,10 @@ def run_helper(client, cmd, env=None, in_buff=None, sudo=False):
|
|
|
Helper function to run `cmd` command on remote host
|
|
|
'''
|
|
|
chan = client.get_transport().open_session()
|
|
|
+ chan.get_pty()
|
|
|
if env:
|
|
|
chan.update_environment(env)
|
|
|
|
|
|
- stdin = chan.makefile('wb')
|
|
|
- stdout = chan.makefile('r')
|
|
|
- stderr = chan.makefile_stderr('r')
|
|
|
- out_buff = io.StringIO()
|
|
|
- err_buff = io.StringIO()
|
|
|
- out_thread = log_stream(stdout, out_buff)
|
|
|
- err_thread = log_stream(stderr, err_buff)
|
|
|
-
|
|
|
if sudo:
|
|
|
assert not in_buff, 'in_buff and sudo can not be combined'
|
|
|
if isinstance(sudo, str):
|
|
|
@@ -205,12 +198,36 @@ def run_helper(client, cmd, env=None, in_buff=None, sudo=False):
|
|
|
else:
|
|
|
sudo_cmd = 'sudo -s'
|
|
|
chan.exec_command(sudo_cmd)
|
|
|
+ msg = chan.recv(1024)
|
|
|
+ while msg and b'[sudo] password for' in msg:
|
|
|
+ pw = getpass(msg.decode())
|
|
|
+ chan.send(pw + '\n')
|
|
|
+ msg = chan.recv(1024)
|
|
|
+ msg += chan.recv(1024)
|
|
|
+ if b'root@' in msg:
|
|
|
+ break
|
|
|
+ else:
|
|
|
+ if b'sudo: 3 incorrect password attempts' in msg:
|
|
|
+ raise RemoteException(msg)
|
|
|
+ if b'Sorry' in msg: # Failure message in in two parts in bash on Debian anyway.
|
|
|
+ msg += chan.recv(1024)
|
|
|
+
|
|
|
in_buff = cmd
|
|
|
- else:
|
|
|
+
|
|
|
+ stdin = chan.makefile('wb')
|
|
|
+ stdout = chan.makefile('r')
|
|
|
+ stderr = chan.makefile_stderr('r')
|
|
|
+ out_buff = io.StringIO()
|
|
|
+ err_buff = io.StringIO()
|
|
|
+ out_thread = log_stream(stdout, out_buff)
|
|
|
+ err_thread = log_stream(stderr, err_buff)
|
|
|
+
|
|
|
+ if not sudo:
|
|
|
chan.exec_command(cmd)
|
|
|
+
|
|
|
if in_buff:
|
|
|
# XXX use a real buff (not a simple str) ?
|
|
|
- stdin.write(in_buff)
|
|
|
+ stdin.write(in_buff.replace('\n', '') + ' && exit $?\n')
|
|
|
stdin.flush()
|
|
|
stdin.close()
|
|
|
chan.shutdown_write()
|