def exec_command_on_vm(self, command, user, password, vm): """Execute the specified command on the instance. Note that this method is reading whole command outputs to memory, thus shouldn't be used for large outputs. :returns: data read from standard output of the command. :raises: SSHExecCommandFailed if command returns nonzero status. The exception contains command status stderr content. """ ssh = self._get_ssh_connection() _intermediate_transport = ssh.get_transport() _intermediate_channel = \ _intermediate_transport.open_channel('direct-tcpip', (vm, 22), (self.host, 0)) transport = paramiko.Transport(_intermediate_channel) transport.start_client() transport.auth_password(user, password) channel = transport.open_session() channel.exec_command(command) exit_status = channel.recv_exit_status() channel.shutdown_write() out_data = [] err_data = [] LOG.debug("Run cmd {0} on vm {1}".format(command, vm)) select_params = [channel], [], [], self.channel_timeout while True: ready = select.select(*select_params) if not any(ready): raise exceptions.TimeoutException( "Command: '{0}' executed on host '{1}'.".format( command, self.host)) if not ready[0]: # If there is nothing to read. continue out_chunk = err_chunk = None if channel.recv_ready(): out_chunk = channel.recv(self.buf_size) out_data += out_chunk, if channel.recv_stderr_ready(): err_chunk = channel.recv_stderr(self.buf_size) err_data += err_chunk, if channel.closed and not err_chunk and not out_chunk: break if 0 != exit_status: LOG.warning( 'Command {0} finishes with non-zero exit code {1}'.format( command, exit_status)) raise exceptions.SSHExecCommandFailed( command=command, exit_status=exit_status, strerror=''.join(err_data).join(out_data)) LOG.debug('Current result {0} {1} {2}'.format(command, err_data, out_data)) return ''.join(out_data)
def exec_command(self, cmd): """ Execute the specified command on the server. Note that this method is reading whole command outputs to memory, thus shouldn't be used for large outputs. :returns: data read from standard output of the command. :raises: SSHExecCommandFailed if command returns nonzero status. The exception contains command status stderr content. """ ssh = self._get_ssh_connection() transport = ssh.get_transport() channel = transport.open_session() channel.get_pty() channel.fileno() # Register event pipe channel.exec_command(cmd) channel.shutdown_write() out_data = [] err_data = [] select_params = [channel], [], [], self.channel_timeout while True: ready = select.select(*select_params) if not any(ready): raise exceptions.TimeoutException( "Command: '{0}' executed on host '{1}'.".format( cmd, self.host)) if not ready[0]: # If there is nothing to read. continue out_chunk = err_chunk = None if channel.recv_ready(): out_chunk = channel.recv(self.buf_size) out_data += out_chunk, if channel.recv_stderr_ready(): err_chunk = channel.recv_stderr(self.buf_size) err_data += err_chunk, if channel.closed and not err_chunk and not out_chunk: break exit_status = channel.recv_exit_status() if 0 != exit_status: raise exceptions.SSHExecCommandFailed( command=cmd, exit_status=exit_status, strerror=''.join(err_data).join(out_data)) return ''.join(out_data)