Execution of the TREX server process requires an SSH session rework to support asynchronous process management. Allowing access to asynchronous functionality allows developers to execute processes without hijacking the SSH session being used. In doing so, both timeout and runtime errors may be avoided. This functionality leverages Fabric's Promise class, which provides a join method to terminate the process when the process is done being used, providing more secure process control.
Bugzilla ID: 1697 Signed-off-by: Nicholas Pratte <npra...@iol.unh.edu> --- dts/framework/remote_session/ssh_session.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dts/framework/remote_session/ssh_session.py b/dts/framework/remote_session/ssh_session.py index e6e4704bc2..185905f701 100644 --- a/dts/framework/remote_session/ssh_session.py +++ b/dts/framework/remote_session/ssh_session.py @@ -13,6 +13,7 @@ ThreadException, UnexpectedExit, ) +from invoke.runners import Promise from paramiko.ssh_exception import ( AuthenticationException, BadHostKeyException, @@ -99,6 +100,22 @@ def _send_command(self, command: str, timeout: float, env: dict | None) -> Comma return CommandResult(self.name, command, output.stdout, output.stderr, output.return_code) + def _send_async_command(self, command: str, timeout: float, env: dict | None) -> Promise: + try: + promise = self.session.run( + command, env=env, warn=True, hide=True, timeout=timeout, asynchronous=True + ) + + except (UnexpectedExit, ThreadException) as e: + self._logger.exception(e) + raise SSHSessionDeadError(self.hostname) from e + + except CommandTimedOut as e: + self._logger.exception(e) + raise SSHTimeoutError(command) from e + + return promise + def is_alive(self) -> bool: """Overrides :meth:`~.remote_session.RemoteSession.is_alive`.""" return self.session.is_connected -- 2.47.1