From dd7860d477ae0015ae5c5b3f24435d553f09737a Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Tue, 10 Aug 2021 20:57:38 +0100 Subject: [PATCH] ssh: Move legacy scp out of SshConnectionBase Move methods related to the scp command into TelnetConnection, since SshConnection do not use it at all anymore (it has been replaced by the "scp" python package, piggy backing on paramiko). --- devlib/utils/ssh.py | 117 ++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 59 deletions(-) diff --git a/devlib/utils/ssh.py b/devlib/utils/ssh.py index ea4e222..5856354 100644 --- a/devlib/utils/ssh.py +++ b/devlib/utils/ssh.py @@ -303,65 +303,8 @@ class SshConnectionBase(ConnectionBase): self.sudo_cmd = sanitize_cmd_template(sudo_cmd) self.platform = platform self.strict_host_check = strict_host_check - self.options = {} logger.debug('Logging in {}@{}'.format(username, host)) - def fmt_remote_path(self, path): - return '{}@{}:{}'.format(self.username, self.host, path) - - def push(self, sources, dest, timeout=30): - # Quote the destination as SCP would apply globbing too - dest = self.fmt_remote_path(quote(dest)) - paths = sources + [dest] - return self._scp(paths, timeout) - - def pull(self, sources, dest, timeout=30): - # First level of escaping for the remote shell - sources = ' '.join(map(quote, sources)) - # All the sources are merged into one scp parameter - sources = self.fmt_remote_path(sources) - paths = [sources, dest] - self._scp(paths, timeout) - - def _scp(self, paths, timeout=30): - # NOTE: the version of scp in Ubuntu 12.04 occasionally (and bizarrely) - # fails to connect to a device if port is explicitly specified using -P - # option, even if it is the default port, 22. To minimize this problem, - # only specify -P for scp if the port is *not* the default. - port_string = '-P {}'.format(quote(str(self.port))) if (self.port and self.port != 22) else '' - keyfile_string = '-i {}'.format(quote(self.keyfile)) if self.keyfile else '' - options = " ".join(["-o {}={}".format(key, val) - for key, val in self.options.items()]) - paths = ' '.join(map(quote, paths)) - command = '{} {} -r {} {} {}'.format(scp, - options, - keyfile_string, - port_string, - paths) - command_redacted = command - logger.debug(command) - if self.password: - command, command_redacted = _give_password(self.password, command) - try: - check_output(command, timeout=timeout, shell=True) - except subprocess.CalledProcessError as e: - raise_from(HostError("Failed to copy file with '{}'. Output:\n{}".format( - command_redacted, e.output)), None) - except TimeoutError as e: - raise TimeoutError(command_redacted, e.output) - - def _get_default_options(self): - if self.strict_host_check: - options = { - 'StrictHostKeyChecking': 'yes', - } - else: - options = { - 'StrictHostKeyChecking': 'no', - 'UserKnownHostsFile': '/dev/null', - } - return options - class SshConnection(SshConnectionBase): # pylint: disable=unused-argument,super-init-not-called @@ -405,8 +348,6 @@ class SshConnection(SshConnectionBase): if self.use_scp: logger.debug('Using SCP for file transfer') - _check_env() - self.options = self._get_default_options() else: logger.debug('Using SFTP for file transfer') @@ -860,6 +801,7 @@ class TelnetConnection(SshConnectionBase): strict_host_check=strict_host_check, ) + _check_env() self.options = self._get_default_options() self.lock = threading.Lock() @@ -870,6 +812,63 @@ class TelnetConnection(SshConnectionBase): self.conn = telnet_get_shell(host, username, password, port, timeout, original_prompt) atexit.register(self.close) + def fmt_remote_path(self, path): + return '{}@{}:{}'.format(self.username, self.host, path) + + def _get_default_options(self): + if self.strict_host_check: + options = { + 'StrictHostKeyChecking': 'yes', + } + else: + options = { + 'StrictHostKeyChecking': 'no', + 'UserKnownHostsFile': '/dev/null', + } + return options + + def push(self, sources, dest, timeout=30): + # Quote the destination as SCP would apply globbing too + dest = self.fmt_remote_path(quote(dest)) + paths = sources + [dest] + return self._scp(paths, timeout) + + def pull(self, sources, dest, timeout=30): + # First level of escaping for the remote shell + sources = ' '.join(map(quote, sources)) + # All the sources are merged into one scp parameter + sources = self.fmt_remote_path(sources) + paths = [sources, dest] + self._scp(paths, timeout) + + def _scp(self, paths, timeout=30): + # NOTE: the version of scp in Ubuntu 12.04 occasionally (and bizarrely) + # fails to connect to a device if port is explicitly specified using -P + # option, even if it is the default port, 22. To minimize this problem, + # only specify -P for scp if the port is *not* the default. + port_string = '-P {}'.format(quote(str(self.port))) if (self.port and self.port != 22) else '' + keyfile_string = '-i {}'.format(quote(self.keyfile)) if self.keyfile else '' + options = " ".join(["-o {}={}".format(key, val) + for key, val in self.options.items()]) + paths = ' '.join(map(quote, paths)) + command = '{} {} -r {} {} {}'.format(scp, + options, + keyfile_string, + port_string, + paths) + command_redacted = command + logger.debug(command) + if self.password: + command, command_redacted = _give_password(self.password, command) + try: + check_output(command, timeout=timeout, shell=True) + except subprocess.CalledProcessError as e: + raise_from(HostError("Failed to copy file with '{}'. Output:\n{}".format( + command_redacted, e.output)), None) + except TimeoutError as e: + raise TimeoutError(command_redacted, e.output) + + def execute(self, command, timeout=None, check_exit_code=True, as_root=False, strip_colors=True, will_succeed=False): #pylint: disable=unused-argument if command == '':