Skip to content

Commit

Permalink
Merge pull request #1281 from ejoerns/explicit-scp
Browse files Browse the repository at this point in the history
sshdriver: support selecting scp mode explicitly
  • Loading branch information
jluebbe authored Oct 13, 2023
2 parents 6a11213 + fbd0c8b commit 0657977
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
4 changes: 3 additions & 1 deletion doc/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1615,8 +1615,10 @@ Arguments:
stdout, and an empty list as second element.
- connection_timeout (float, default=30.0): timeout when trying to establish connection to
target.
- explicit_sftp_mode (bool, default=False): if set to True, `put()` and `get()` will
- explicit_sftp_mode (bool, default=False): if set to True, `put()`, `get()`, and `scp()` will
explicitly use the SFTP protocol for file transfers instead of scp's default protocol
- explicit_scp_mode (bool, default=False): if set to True, `put()`, `get()`, and `scp()` will
explicitly use the SCP protocol for file transfers instead of scp's default protocol

UBootDriver
~~~~~~~~~~~
Expand Down
24 changes: 22 additions & 2 deletions labgrid/driver/sshdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import subprocess
import tempfile
import time
from functools import cached_property

import attr

Expand All @@ -34,6 +35,7 @@ class SSHDriver(CommandMixin, Driver, CommandProtocol, FileTransferProtocol):
stderr_merge = attr.ib(default=False, validator=attr.validators.instance_of(bool))
connection_timeout = attr.ib(default=float(get_ssh_connect_timeout()), validator=attr.validators.instance_of(float))
explicit_sftp_mode = attr.ib(default=False, validator=attr.validators.instance_of(bool))
explicit_scp_mode = attr.ib(default=False, validator=attr.validators.instance_of(bool))

def __attrs_post_init__(self):
super().__attrs_post_init__()
Expand Down Expand Up @@ -360,6 +362,8 @@ def scp(self, *, src, dst):

if self.explicit_sftp_mode and self._scp_supports_explicit_sftp_mode():
complete_cmd.insert(1, "-s")
if self.explicit_scp_mode and self._scp_supports_explicit_scp_mode():
complete_cmd.insert(1, "-O")

self.logger.info("Running command: %s", complete_cmd)
sub = subprocess.Popen(
Expand Down Expand Up @@ -432,10 +436,14 @@ def get_status(self):
"""The SSHDriver is always connected, return 1"""
return 1

def _scp_supports_explicit_sftp_mode(self):
@cached_property
def _ssh_version(self):
version = subprocess.run(["ssh", "-V"], capture_output=True, text=True)
version = re.match(r"^OpenSSH_(\d+)\.(\d+)", version.stderr)
major, minor = map(int, version.groups())
return map(int, version.groups())

def _scp_supports_explicit_sftp_mode(self):
major, minor = self._ssh_version

# OpenSSH >= 8.6 supports explicitly using the SFTP protocol via -s
if major == 8 and minor >= 6:
Expand All @@ -445,6 +453,14 @@ def _scp_supports_explicit_sftp_mode(self):
return False
raise Exception(f"OpenSSH version {major}.{minor} does not support explicit SFTP mode")

def _scp_supports_explicit_scp_mode(self):
major, minor = self._ssh_version

# OpenSSH >= 9.0 default to the SFTP protocol
if major >= 9:
return True
raise Exception(f"OpenSSH version {major}.{minor} does not support explicit SCP mode")

@Driver.check_active
@step(args=['filename', 'remotepath'])
def put(self, filename, remotepath=''):
Expand All @@ -459,6 +475,8 @@ def put(self, filename, remotepath=''):

if self.explicit_sftp_mode and self._scp_supports_explicit_sftp_mode():
transfer_cmd.insert(1, "-s")
if self.explicit_scp_mode and self._scp_supports_explicit_scp_mode():
transfer_cmd.insert(1, "-O")

try:
sub = subprocess.call(
Expand Down Expand Up @@ -487,6 +505,8 @@ def get(self, filename, destination="."):

if self.explicit_sftp_mode and self._scp_supports_explicit_sftp_mode():
transfer_cmd.insert(1, "-s")
if self.explicit_scp_mode and self._scp_supports_explicit_scp_mode():
transfer_cmd.insert(1, "-O")

try:
sub = subprocess.call(
Expand Down

0 comments on commit 0657977

Please sign in to comment.