X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2Fssh.py;h=fad00482ed895c1d77f9172b7106b69a1bd3af90;hb=bd15bb418bf618ff3055fb25c339778d12c1eaef;hp=5359a6e5fb6303a430a0a6fc083ee0ab8089cbdb;hpb=d68951ac245150eeefa6e0f4156e4c1b5c9e9325;p=csit.git diff --git a/resources/libraries/python/ssh.py b/resources/libraries/python/ssh.py index 5359a6e5fb..fad00482ed 100644 --- a/resources/libraries/python/ssh.py +++ b/resources/libraries/python/ssh.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019 Cisco and/or its affiliates. +# Copyright (c) 2021 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -302,10 +302,11 @@ class SSH: buf = u"" while not buf.endswith((u":~# ", u":~$ ", u"~]$ ", u"~]# ")): try: - chunk = chan.recv(self.__MAX_RECV_BUF) - if not chunk: + s_out = chan.recv(self.__MAX_RECV_BUF) + if not s_out: break - buf += chunk + buf += s_out.decode(encoding=u'utf-8', errors=u'ignore') \ + if isinstance(s_out, bytes) else s_out if chan.exit_status_ready(): logger.error(u"Channel exit status ready") break @@ -321,7 +322,7 @@ class SSH: :param chan: SSH channel with opened terminal. :param cmd: Command to be executed. :param prompt: Command prompt, sequence of characters used to - indicate readiness to accept commands. + indicate readiness to accept commands. :returns: Command output. .. warning:: Interruptingcow is used here, and it uses @@ -335,10 +336,11 @@ class SSH: buf = u"" while not buf.endswith(prompt): try: - chunk = chan.recv(self.__MAX_RECV_BUF) - if not chunk: + s_out = chan.recv(self.__MAX_RECV_BUF) + if not s_out: break - buf += chunk + buf += s_out.decode(encoding=u'utf-8', errors=u'ignore') \ + if isinstance(s_out, bytes) else s_out if chan.exit_status_ready(): logger.error(u"Channel exit status ready") break @@ -368,9 +370,9 @@ class SSH: connect() method has to be called first! :param local_path: Path to local file that should be uploaded; or - path where to save remote file. + path where to save remote file. :param remote_path: Remote path where to place uploaded file; or - path to remote file which should be downloaded. + path to remote file which should be downloaded. :param get: scp operation to perform. Default is put. :param timeout: Timeout value in seconds. :param wildcard: If path has wildcard characters. Default is false. @@ -408,7 +410,9 @@ class SSH: logger.trace(f"SCP took {end-start} seconds") -def exec_cmd(node, cmd, timeout=600, sudo=False, disconnect=False): +def exec_cmd( + node, cmd, timeout=600, sudo=False, disconnect=False, + log_stdout_err=True): """Convenience function to ssh/exec/return rc, out & err. Returns (rc, stdout, stderr). @@ -418,11 +422,15 @@ def exec_cmd(node, cmd, timeout=600, sudo=False, disconnect=False): :param timeout: Timeout value in seconds. Default: 600. :param sudo: Sudo privilege execution flag. Default: False. :param disconnect: Close the opened SSH connection if True. + :param log_stdout_err: If True, stdout and stderr are logged. stdout + and stderr are logged also if the return code is not zero + independently of the value of log_stdout_err. :type node: dict :type cmd: str or OptionString :type timeout: int :type sudo: bool :type disconnect: bool + :type log_stdout_err: bool :returns: RC, Stdout, Stderr. :rtype: tuple(int, str, str) """ @@ -443,10 +451,12 @@ def exec_cmd(node, cmd, timeout=600, sudo=False, disconnect=False): try: if not sudo: - ret_code, stdout, stderr = ssh.exec_command(cmd, timeout=timeout) + ret_code, stdout, stderr = ssh.exec_command( + cmd, timeout=timeout, log_stdout_err=log_stdout_err + ) else: ret_code, stdout, stderr = ssh.exec_command_sudo( - cmd, timeout=timeout + cmd, timeout=timeout, log_stdout_err=log_stdout_err ) except SSHException as err: logger.error(repr(err)) @@ -460,7 +470,7 @@ def exec_cmd(node, cmd, timeout=600, sudo=False, disconnect=False): def exec_cmd_no_error( node, cmd, timeout=600, sudo=False, message=None, disconnect=False, - retries=0, include_reason=False): + retries=0, include_reason=False, log_stdout_err=True): """Convenience function to ssh/exec/return out & err. Verifies that return code is zero. @@ -476,6 +486,9 @@ def exec_cmd_no_error( :param disconnect: Close the opened SSH connection if True. :param retries: How many times to retry on failure. :param include_reason: Whether default info should be appended to message. + :param log_stdout_err: If True, stdout and stderr are logged. stdout + and stderr are logged also if the return code is not zero + independently of the value of log_stdout_err. :type node: dict :type cmd: str or OptionString :type timeout: int @@ -484,13 +497,15 @@ def exec_cmd_no_error( :type disconnect: bool :type retries: int :type include_reason: bool + :type log_stdout_err: bool :returns: Stdout, Stderr. :rtype: tuple(str, str) :raises RuntimeError: If bash return code is not 0. """ for _ in range(retries + 1): ret_code, stdout, stderr = exec_cmd( - node, cmd, timeout=timeout, sudo=sudo, disconnect=disconnect + node, cmd, timeout=timeout, sudo=sudo, disconnect=disconnect, + log_stdout_err=log_stdout_err ) if ret_code == 0: break