1
0
mirror of https://github.com/ARM-software/devlib.git synced 2025-01-31 02:00:45 +00:00

utils/ssh: Add paramiko based scp transfers

Using scp over paramiko allows scp transfers to be treated similarly to
sftp transfers, instead of requiring subprocesses, and provides
the ability to monitor an scp transfer using a callback as can be done
using sftp.
This commit is contained in:
Jonathan Paynter 2020-09-10 13:45:20 +01:00 committed by Marc Bonnici
parent 1d1ba7811d
commit ebf1c1a2e1
2 changed files with 22 additions and 12 deletions

View File

@ -36,6 +36,7 @@ from future.utils import raise_from
from paramiko.client import SSHClient, AutoAddPolicy, RejectPolicy from paramiko.client import SSHClient, AutoAddPolicy, RejectPolicy
import paramiko.ssh_exception import paramiko.ssh_exception
from scp import SCPClient
# By default paramiko is very verbose, including at the INFO level # By default paramiko is very verbose, including at the INFO level
logging.getLogger("paramiko").setLevel(logging.WARNING) logging.getLogger("paramiko").setLevel(logging.WARNING)
@ -446,6 +447,10 @@ class SshConnection(SshConnectionBase):
sftp.get_channel().settimeout(timeout) sftp.get_channel().settimeout(timeout)
return sftp return sftp
def _get_scp(self, timeout):
return SCPClient(self.client.get_transport(), socket_timeout=timeout)
@classmethod @classmethod
def _push_file(cls, sftp, src, dst): def _push_file(cls, sftp, src, dst):
try: try:
@ -560,21 +565,25 @@ class SshConnection(SshConnectionBase):
def push(self, sources, dest, timeout=30): def push(self, sources, dest, timeout=30):
# If using scp, use implementation from base class # If using scp, use implementation from base class
if self.use_scp: with _handle_paramiko_exceptions():
super().push(sources, dest, timeout) if self.use_scp:
else: scp = self._get_scp(timeout)
with _handle_paramiko_exceptions(), self._get_sftp(timeout) as sftp: scp.put(sources, dest, recursive=True)
for source in sources: else:
self._push_path(sftp, source, dest) with self._get_sftp(timeout) as sftp:
for source in sources:
self._push_path(sftp, source, dest)
def pull(self, sources, dest, timeout=30): def pull(self, sources, dest, timeout=30):
# If using scp, use implementation from base class # If using scp, use implementation from base class
if self.use_scp: with _handle_paramiko_exceptions():
super().pull(sources, dest, timeout) if self.use_scp:
else: scp = self._get_scp(timeout)
with _handle_paramiko_exceptions(), self._get_sftp(timeout) as sftp: scp.get(sources, dest, recursive=True)
for source in sources: else:
self._pull_path(sftp, source, dest) with self._get_sftp(timeout) as sftp:
for source in sources:
self._pull_path(sftp, source, dest)
def execute(self, command, timeout=None, check_exit_code=True, def execute(self, command, timeout=None, check_exit_code=True,
as_root=False, strip_colors=True, will_succeed=False): #pylint: disable=unused-argument as_root=False, strip_colors=True, will_succeed=False): #pylint: disable=unused-argument

View File

@ -83,6 +83,7 @@ params = dict(
'pexpect>=3.3', # Send/recieve to/from device 'pexpect>=3.3', # Send/recieve to/from device
'pyserial', # Serial port interface 'pyserial', # Serial port interface
'paramiko', # SSH connection 'paramiko', # SSH connection
'scp', # SSH connection file transfers
'wrapt', # Basic for construction of decorator functions 'wrapt', # Basic for construction of decorator functions
'future', # Python 2-3 compatibility 'future', # Python 2-3 compatibility
'enum34;python_version<"3.4"', # Enums for Python < 3.4 'enum34;python_version<"3.4"', # Enums for Python < 3.4