Ejemplo n.º 1
0
    def execute(self, cmd, quiet=False):
        """Execute a command on a remote SSH server.

        :param cmd: Command for execution.
        :type cmd: str
        :param quiet: if quiet is True don't print error messages
        :return: Handlers of stdin, stdout and stderr
        :rtype: tuple
        :raise SshDestinationError: if any error

        """
        try:
            with self._shell() as shell:
                LOG.debug('Executing %s', cmd)
                stdin_, stdout_, stderr_ = shell.exec_command(cmd)
                # while not stdout_.channel.exit_status_ready():
                #     LOG.debug('%s: waiting', cmd)
                #     time.sleep(1)
                exit_code = stdout_.channel.recv_exit_status()
                if exit_code != 0:
                    if not quiet:
                        LOG.error("Failed while execute command %s", cmd)
                        LOG.error(stderr_.read())
                    raise SshClientException('%s exited with code %d'
                                             % (cmd, exit_code))
                return stdin_, stdout_, stderr_

        except (SSHException, IOError) as err:
            if not quiet:
                LOG.error('Failed to execute %s: %s', cmd, err)
            raise SshClientException('Failed to execute %s: %s'
                                     % (cmd, err))
Ejemplo n.º 2
0
    def execute(self, cmd, quiet=False, background=False):
        """Execute a command on a remote SSH server.

        :param cmd: Command for execution.
        :type cmd: str
        :param quiet: if quiet is True don't print error messages
        :param background: Don't wait until the command exits.
        :type background: bool
        :return: Strings with stdout and stderr. If command is executed
            in background the method will return None.
        :rtype: tuple
        :raise SshClientException: if any error or non-zero exit code

        """
        max_chunk_size = 1024 * 1024
        try:
            with self._shell() as shell:
                if not background:
                    LOG.debug('Executing command: %s', cmd)
                    stdin_, stdout_, _ = shell.exec_command(cmd)
                    channel = stdout_.channel
                    stdin_.close()
                    channel.shutdown_write()
                    stdout_chunks = []
                    stderr_chunks = []
                    while not channel.closed \
                            or channel.recv_ready() \
                            or channel.recv_stderr_ready():
                        if channel.recv_ready():
                            stdout_chunks.append(
                                channel.recv(max_chunk_size).decode("utf-8"))
                        if channel.recv_stderr_ready():
                            stderr_chunks.append(
                                channel.recv_stderr(max_chunk_size).decode(
                                    "utf-8"))

                    exit_code = channel.recv_exit_status()
                    if exit_code != 0:
                        if not quiet:
                            LOG.error("Failed to execute command %s", cmd)
                            LOG.error(''.join(stderr_chunks))
                        raise SshClientException('%s exited with code %d' %
                                                 (cmd, exit_code))
                    return ''.join(stdout_chunks), ''.join(stderr_chunks)
                else:
                    LOG.debug('Executing in background: %s', cmd)
                    transport = shell.get_transport()
                    channel = transport.open_session()
                    channel.exec_command(cmd)
                    LOG.debug('Ran %s in background', cmd)

        except (SSHException, IOError) as err:
            if not quiet:
                LOG.error('Failed to execute %s: %s', cmd, err)
            raise SshClientException('Failed to execute %s: %s' % (cmd, err))
Ejemplo n.º 3
0
    def _shell(self):
        """
        Create SSHClient instance and connect to the destination host.

        :return: Connected to the remote destination host shell.
        :rtype: generator(SSHClient)
        :raise SshDestinationError: if the ssh client fails to connect.
        """
        shell = SSHClient()
        shell.set_missing_host_key_policy(AutoAddPolicy())
        try:
            LOG.debug("Connecting to %s:%d as %s with key %s", self._host,
                      self._port, self._user, self._key)
            shell.connect(hostname=self._host,
                          key_filename=self._key,
                          port=self._port,
                          username=self._user)
            yield shell
        except FileNotFoundError:
            raise
        except (AuthenticationException, SSHException, socket.error) as err:
            # print(type(err))
            raise SshClientException(err)
        finally:
            shell.close()
Ejemplo n.º 4
0
    def get_remote_handlers(self, cmd):
        """Get remote stdin, stdout and stderr handler

        :param cmd: Command for execution
        :type cmd: str
        :return: Remote stdin, stdout and stderr handler
        :rtype: tuple(generator, generator, generator)
        :raise SshDestinationError: if any error
        """
        try:
            with self._shell() as shell:
                stdin_, stdout_, stderr_ = shell.exec_command(cmd)
                yield stdin_, stdout_, stderr_

        except SSHException as err:
            LOG.error('Failed to execute %s', cmd)
            raise SshClientException(err)
Ejemplo n.º 5
0
    def _shell(self):
        """
        Create SSHClient instance and connect to the destination host.

        :return: Connected to the remote destination host shell.
        :rtype: generator(SSHClient)
        :raise SshDestinationError: if the ssh client fails to connect.
        """
        shell = SSHClient()
        shell.set_missing_host_key_policy(AutoAddPolicy())
        try:
            shell.connect(hostname=self.ssh_connect_info.host,
                          key_filename=self.ssh_connect_info.key,
                          port=self.ssh_connect_info.port,
                          username=self.ssh_connect_info.user)
            yield shell
        except (AuthenticationException, SSHException, socket.error) as err:
            raise SshClientException(err)
        finally:
            shell.close()