+ self.remote_ip = None
+ self.local_ip = None
+
+ def run_command(self, command, keep_session=False):
+ """Run a command passed as a str on a localhost or at remote machine.
+ :param command: text with the command to execute.
+ :param keep_session: if True it returns a <stdin> for sending input with '<stdin>.write("text\n")'.
+ A command with keep_session=True MUST be followed by a command with keep_session=False in order to
+ close the session and get the output
+ :return: the output of the command if 'keep_session=False' or the <stdin> object if 'keep_session=True'
+ :raises: RunCommandException if command fails
+ """
+ if self.run_command_session and keep_session:
+ raise RunCommandException("Internal error. A command with keep_session=True must be followed by another "
+ "command with keep_session=False to close session")
+ try:
+ if self.localhost:
+ if self.run_command_session:
+ p = self.run_command_session
+ self.run_command_session = None
+ (output, outerror) = p.communicate()
+ returncode = p.returncode
+ p.stdin.close()
+ elif keep_session:
+ p = subprocess.Popen(('bash', "-c", command), stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ self.run_command_session = p
+ return p.stdin
+ else:
+ output = subprocess.check_output(('bash', "-c", command))
+ returncode = 0
+ else:
+ if self.run_command_session:
+ (i, o, e) = self.run_command_session
+ self.run_command_session = None
+ i.channel.shutdown_write()
+ else:
+ if not self.ssh_conn:
+ self.ssh_connect()
+ (i, o, e) = self.ssh_conn.exec_command(command, timeout=10)
+ if keep_session:
+ self.run_command_session = (i, o, e)
+ return i
+ returncode = o.channel.recv_exit_status()
+ output = o.read()
+ outerror = e.read()
+ if returncode != 0:
+ text = "run_command='{}' Error='{}'".format(command, outerror)
+ self.logger.error(text)
+ raise RunCommandException(text)
+
+ self.logger.debug("run_command='{}' result='{}'".format(command, output))
+ return output
+
+ except RunCommandException:
+ raise
+ except subprocess.CalledProcessError as e:
+ text = "run_command Exception '{}' '{}'".format(str(e), e.output)
+ except (paramiko.ssh_exception.SSHException, Exception) as e:
+ text = "run_command='{}' Exception='{}'".format(command, str(e))
+ self.ssh_conn = None
+ self.run_command_session = None
+ raise RunCommandException(text)