mirror of
https://github.com/ARM-software/devlib.git
synced 2025-01-31 02:00:45 +00:00
utils/ssh: Implement work around for issue in pexpect
As detailed in https://github.com/pexpect/pexpect/issues/552 when sending a command with exactly the length of the prompt less than the window width, an extra prompt is introduced into the returned data causing the matching to fail and only return part of the commands output. To workaround this check the length of the command to be submitted and if of the specific length add an additional whitespace character to the end of the command to prevent this behaviour.
This commit is contained in:
parent
cc0679e40f
commit
911a9f2ef4
@ -41,7 +41,8 @@ from pexpect import EOF, TIMEOUT, spawn
|
|||||||
# pylint: disable=redefined-builtin,wrong-import-position
|
# pylint: disable=redefined-builtin,wrong-import-position
|
||||||
from devlib.exception import (HostError, TargetStableError, TargetNotRespondingError,
|
from devlib.exception import (HostError, TargetStableError, TargetNotRespondingError,
|
||||||
TimeoutError, TargetTransientError)
|
TimeoutError, TargetTransientError)
|
||||||
from devlib.utils.misc import which, strip_bash_colors, check_output, sanitize_cmd_template
|
from devlib.utils.misc import (which, strip_bash_colors, check_output,
|
||||||
|
sanitize_cmd_template, memoized)
|
||||||
from devlib.utils.types import boolean
|
from devlib.utils.types import boolean
|
||||||
|
|
||||||
|
|
||||||
@ -253,7 +254,7 @@ class SshConnection(object):
|
|||||||
# simulate impatiently hitting ^C until command prompt appears
|
# simulate impatiently hitting ^C until command prompt appears
|
||||||
logger.debug('Sending ^C')
|
logger.debug('Sending ^C')
|
||||||
for _ in range(self.max_cancel_attempts):
|
for _ in range(self.max_cancel_attempts):
|
||||||
self.conn.sendline(chr(3))
|
self._sendline(chr(3))
|
||||||
if self.conn.prompt(0.1):
|
if self.conn.prompt(0.1):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
@ -267,15 +268,15 @@ class SshConnection(object):
|
|||||||
command = self.sudo_cmd.format(quote(command))
|
command = self.sudo_cmd.format(quote(command))
|
||||||
if log:
|
if log:
|
||||||
logger.debug(command)
|
logger.debug(command)
|
||||||
self.conn.sendline(command)
|
self._sendline(command)
|
||||||
if self.password:
|
if self.password:
|
||||||
index = self.conn.expect_exact([self.password_prompt, TIMEOUT], timeout=0.5)
|
index = self.conn.expect_exact([self.password_prompt, TIMEOUT], timeout=0.5)
|
||||||
if index == 0:
|
if index == 0:
|
||||||
self.conn.sendline(self.password)
|
self._sendline(self.password)
|
||||||
else: # not as_root
|
else: # not as_root
|
||||||
if log:
|
if log:
|
||||||
logger.debug(command)
|
logger.debug(command)
|
||||||
self.conn.sendline(command)
|
self._sendline(command)
|
||||||
timed_out = self._wait_for_prompt(timeout)
|
timed_out = self._wait_for_prompt(timeout)
|
||||||
# the regex removes line breaks potential introduced when writing
|
# the regex removes line breaks potential introduced when writing
|
||||||
# command to shell.
|
# command to shell.
|
||||||
@ -321,6 +322,21 @@ class SshConnection(object):
|
|||||||
except TimeoutError as e:
|
except TimeoutError as e:
|
||||||
raise TimeoutError(command_redacted, e.output)
|
raise TimeoutError(command_redacted, e.output)
|
||||||
|
|
||||||
|
def _sendline(self, command):
|
||||||
|
# Workaround for https://github.com/pexpect/pexpect/issues/552
|
||||||
|
if len(command) == self._get_window_size()[1] - self._get_prompt_length():
|
||||||
|
command += ' '
|
||||||
|
self.conn.sendline(command)
|
||||||
|
|
||||||
|
@memoized
|
||||||
|
def _get_prompt_length(self):
|
||||||
|
self.conn.sendline()
|
||||||
|
self.conn.prompt()
|
||||||
|
return len(self.conn.after)
|
||||||
|
|
||||||
|
@memoized
|
||||||
|
def _get_window_size(self):
|
||||||
|
return self.conn.getwinsize()
|
||||||
|
|
||||||
class TelnetConnection(SshConnection):
|
class TelnetConnection(SshConnection):
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user