示例#1
0
def _ssh_execute(ssh, cmd, ssh_params):
    # NOTE(yuriyz): this ugly code is work-around against paramiko with
    # eventlet issues
    LOG.debug('Running cmd (SSH): %s', cmd)
    stdin_stream, stdout_stream, stderr_stream = ssh.exec_command(cmd)
    paramiko_channel = stdout_stream.channel
    paramiko_channel.setblocking(0)
    stdout_io = six.moves.StringIO()
    stderr_io = six.moves.StringIO()

    def _wait_execution(mutable, channel):
        try:
            stdout_data = channel.recv(1048576)
        except Exception:
            LOG.debug('No data from SSH stdout.')
        else:
            LOG.debug('Got %d from SSH stdout.', len(stdout_data))
            stdout_io.write(stdout_data)

        try:
            stderr_data = channel.recv_stderr(1048576)
        except Exception:
            LOG.debug('No data from SSH stderr.')
        else:
            LOG.debug('Got %d from SSH stderr.', len(stderr_data))
            stderr_io.write(stderr_data)

        if channel.exit_status_ready():
            raise loopingcall.LoopingCallDone()

        try:
            ssh = utils.ssh_connect(ssh_params)
        except exception.SSHConnectFailed:
            mutable['error'] = True
            raise loopingcall.LoopingCallDone()
        else:
            ssh.close()

    error = {'error': False}
    timer = loopingcall.FixedIntervalLoopingCall(_wait_execution, error,
                                                 paramiko_channel)
    timer.start(interval=60).wait()
    stdout = stdout_io.getvalue()
    stderr = stderr_io.getvalue()
    LOG.debug('SSH stdout is: "%s"', stdout)
    LOG.debug('SSH stderr is: "%s"', stderr)

    if error['error']:
        message = _('connection to the node lost')
        raise exception.SSHCommandFailed(cmd=message)

    exit_status = paramiko_channel.recv_exit_status()
    if exit_status != 0:
        message = _('wrong exit status %d') % exit_status
        raise exception.SSHCommandFailed(cmd=message)

    return stdout, stderr
示例#2
0
def _ssh_execute(ssh_obj, cmd_to_exec):
    """Executes a command via ssh.

    Executes a command via ssh and returns a list of the lines of the
    output from the command.

    :param ssh_obj: paramiko.SSHClient, an active ssh connection.
    :param cmd_to_exec: command to execute.
    :returns: list of the lines of output from the command.
    :raises: SSHCommandFailed on an error from ssh.

    """
    LOG.debug(_translators.log_error("Executing SSH cmd: %r"), cmd_to_exec)
    try:
        output_list = processutils.ssh_execute(ssh_obj,
                                               cmd_to_exec)[0].split('\n')
    except Exception as e:
        LOG.error(
            _translators.log_error(
                "Cannot execute SSH cmd %(cmd)s. Reason: %(err)s."), {
                    'cmd': cmd_to_exec,
                    'err': e
                })
        raise exception.SSHCommandFailed(cmd=cmd_to_exec)

    return output_list