Skip to content

Commit

Permalink
Reverted last 7 commits
Browse files Browse the repository at this point in the history
This reverts commit fbd3ac2bce2204972383f96b5147093502e099e6.
  • Loading branch information
eranif committed Feb 16, 2023
1 parent f7b1026 commit a9e2998
Show file tree
Hide file tree
Showing 39 changed files with 666 additions and 810 deletions.
1 change: 1 addition & 0 deletions CodeFormatter/GenericFormatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "Platform.hpp"
#include "StringUtils.h"
#include "asyncprocess.h"
#include "clCodeLiteRemoteProcess.hpp"
#include "clDirChanger.hpp"
#include "clTempFile.hpp"
#include "clWorkspaceManager.h"
Expand Down
1 change: 1 addition & 0 deletions CodeFormatter/GenericFormatter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define GENERICFORMATTER_HPP

#include "SourceFormatterBase.hpp"
#include "clCodeLiteRemoteProcess.hpp"
#include "procutils.h"
#include "ssh/cl_remote_executor.hpp"

Expand Down
259 changes: 97 additions & 162 deletions CodeLite/ssh/clRemoteHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,104 +14,36 @@ INITIALISE_SSH_LOG(LOG, "Remote-Host");
namespace
{
clRemoteHost* ms_instance{ nullptr };

class clSSHChannelProcessAdapter : public IProcess
{
clSSHChannel::Ptr_t m_channel = nullptr;

public:
clSSHChannelProcessAdapter(wxEvtHandler* parent, clSSHChannel::Ptr_t channel)
: IProcess(parent)
, m_channel(channel)
{
}
// Stop notifying the parent window about input/output from the process
// this is useful when we wish to terminate the process onExit but we don't want
// to know about its termination
void Detach() override {}

/// Read from process stdout - return immediately if no data is available
/// we return both converted buffer as string and the raw buffer (unconverted)
bool Read(wxString& buff, wxString& buffErr, std::string& raw_buff, std::string& raw_buffErr) override
{
wxUnusedVar(buff);
wxUnusedVar(buffErr);
wxUnusedVar(raw_buff);
wxUnusedVar(raw_buffErr);
return false;
}

// Write to the process stdin
// This version add LF to the buffer
bool Write(const wxString& buff) override
{
wxUnusedVar(buff);
return false;
}

// ANSI version
// This version add LF to the buffer
bool Write(const std::string& buff) override
{
wxUnusedVar(buff);
return false;
}

// Write to the process stdin
bool WriteRaw(const wxString& buff) override
{
wxUnusedVar(buff);
return false;
}

// ANSI version
bool WriteRaw(const std::string& buff) override
{
wxUnusedVar(buff);
return false;
}

/**
* @brief this method is mostly needed on MSW where writing a password
* is done directly on the console buffer rather than its stdin
*/
bool WriteToConsole(const wxString& buff) override
{
wxUnusedVar(buff);
return false;
}

// Return true if the process is still alive
bool IsAlive() override { return m_channel && m_channel->IsOpen(); }

// Clean the process resources and kill the process if it is
// still alive
void Cleanup() override {}

// Terminate the process. It is recommended to use this method
// so it will invoke the 'Cleaup' procedure and the process
// termination event will be sent out
void Terminate() override {}

void Signal(wxSignal sig) override
{
if(m_channel) {
m_channel->SendSignal(sig);
}
}
};
} // namespace
}

clRemoteHost::clRemoteHost()
{
m_executor.Bind(wxEVT_ASYNC_PROCESS_OUTPUT, &clRemoteHost::OnCommandStdout, this);
m_executor.Bind(wxEVT_ASYNC_PROCESS_STDERR, &clRemoteHost::OnCommandStderr, this);
m_executor.Bind(wxEVT_ASYNC_PROCESS_TERMINATED, &clRemoteHost::OnCommandCompleted, this);
Bind(wxEVT_WORKSPACE_LOADED, &clRemoteHost::OnWorkspaceOpened, this);
Bind(wxEVT_WORKSPACE_CLOSED, &clRemoteHost::OnWorkspaceClosed, this);
}

clRemoteHost::~clRemoteHost()
{
Unbind(wxEVT_WORKSPACE_CLOSED, &clRemoteHost::OnWorkspaceClosed, this);
Unbind(wxEVT_WORKSPACE_LOADED, &clRemoteHost::OnWorkspaceOpened, this);
m_executor.Unbind(wxEVT_ASYNC_PROCESS_OUTPUT, &clRemoteHost::OnCommandStdout, this);
m_executor.Unbind(wxEVT_ASYNC_PROCESS_STDERR, &clRemoteHost::OnCommandStderr, this);
m_executor.Unbind(wxEVT_ASYNC_PROCESS_TERMINATED, &clRemoteHost::OnCommandCompleted, this);

EventNotifier::Get()->Unbind(wxEVT_WORKSPACE_CLOSED, &clRemoteHost::OnWorkspaceClosed, this);
EventNotifier::Get()->Unbind(wxEVT_WORKSPACE_LOADED, &clRemoteHost::OnWorkspaceOpened, this);
DrainPendingCommands();
}

void clRemoteHost::DrainPendingCommands()
{
while(!m_callbacks.empty()) {
// terminate any pending commands
m_callbacks.back().second->Close();
delete m_callbacks.back().second;
m_callbacks.pop_back();
}
}

clRemoteHost* clRemoteHost::Instance()
Expand All @@ -131,80 +63,76 @@ void clRemoteHost::Release()
void clRemoteHost::OnWorkspaceOpened(clWorkspaceEvent& event)
{
event.Skip();
m_executor.shutdown();
m_activeAccount.clear();
if(event.IsRemote()) {
/// Initialise the remote host executor
m_activeAccount = event.GetRemoteAccount();
m_executor.startup(event.GetRemoteAccount());
}
}

void clRemoteHost::OnWorkspaceClosed(clWorkspaceEvent& event)
{
event.Skip();
DrainPendingCommands();
for(auto proc : m_interactiveProcesses) {
// terminate the bg thread + close the channel
proc->Terminate();
}
/// terminate all currently running commands
m_executor.shutdown();
m_interactiveProcesses.clear();
m_executor.shutdown();
m_sessions.clear();
m_activeAccount.clear();
}

void clRemoteHost::AddSshSession(clSSH::Ptr_t ssh_session) { m_sessions.push_back(ssh_session); }

clSSH::Ptr_t clRemoteHost::CreateSshSession()
{
clSSH::Ptr_t ssh_session;
wxBusyCursor bc;
LOG_DEBUG(LOG) << "Creating new ssh session" << endl;
// create new session
auto account = SSHAccountInfo::LoadAccount(m_activeAccount);
if(account.GetHost().empty()) {
LOG_WARNING(LOG) << "could not find account:" << m_activeAccount << endl;
return nullptr;
}

/// open channel
try {
ssh_session.reset(
new clSSH(account.GetHost(), account.GetUsername(), account.GetPassword(), account.GetPort()));
wxString message;

ssh_session->Open();
if(!ssh_session->AuthenticateServer(message)) {
ssh_session->AcceptServerAuthentication();
}
ssh_session->Login();
} catch(clException& e) {
LOG_ERROR(LOG) << "Failed to open ssh channel to account:" << account.GetAccountName() << "." << e.What()
<< endl;
return nullptr;
}
LOG_DEBUG(LOG) << "Initializing for account:" << m_activeAccount << "completed successfully" << endl;
return ssh_session;
}

clSSH::Ptr_t clRemoteHost::GetSshSession()
{
clSSH::Ptr_t ssh_session;
clSSH::Ptr_t ssh_sssion;
if(m_sessions.empty()) {
wxBusyCursor bc;
LOG_DEBUG(LOG) << "No ssh session in cache, will create new one" << endl;
ssh_session = CreateSshSession();
// create new session
auto account = SSHAccountInfo::LoadAccount(m_activeAccount);
if(account.GetHost().empty()) {
LOG_WARNING(LOG) << "could not find account:" << m_activeAccount << endl;
return nullptr;
}

/// open channel
try {
ssh_sssion.reset(
new clSSH(account.GetHost(), account.GetUsername(), account.GetPassword(), account.GetPort()));
wxString message;

ssh_sssion->Open();
if(!ssh_sssion->AuthenticateServer(message)) {
ssh_sssion->AcceptServerAuthentication();
}
ssh_sssion->Login();
} catch(clException& e) {
LOG_ERROR(LOG) << "Failed to open ssh channel to account:" << account.GetAccountName() << "." << e.What()
<< endl;
return nullptr;
}
LOG_DEBUG(LOG) << "Initializing for account:" << m_activeAccount << "completed successfully" << endl;
} else {
LOG_DEBUG(LOG) << "Re-using ssh session from the cache" << endl;
ssh_session = m_sessions.back();
ssh_sssion = m_sessions.back();
m_sessions.pop_back();
}
return ssh_session;
return ssh_sssion;
}

void clRemoteHost::run_command_with_callback(const std::vector<wxString>& command, const wxString& wd,
const clEnvList_t& env, execute_callback&& cb)
{
m_executor.execute_with_callback(clRemoteExecutor::Cmd::from(command, wd, env), m_activeAccount, std::move(cb));
clSSHChannel* channel = m_executor.try_execute(clRemoteExecutor::Cmd::from(command, wd, env));
if(channel) {
m_callbacks.emplace_back(std::make_pair(std::move(cb), channel));
}
}

void clRemoteHost::run_command_with_callback(const wxString& command, const wxString& wd, const clEnvList_t& env,
Expand All @@ -215,12 +143,50 @@ void clRemoteHost::run_command_with_callback(const wxString& command, const wxSt
run_command_with_callback(argv, wd, env, std::move(cb));
}

void clRemoteHost::OnCommandStderr(clProcessEvent& event)
{
const std::string& output = event.GetStringRaw();
if(m_callbacks.empty()) {
LOG_WARNING(LOG) << "no callback found for command output" << endl;
return;
}
LOG_DEBUG(LOG) << "stderr:" << event.GetStringRaw().size() << "bytes" << endl;
// call the callback
m_callbacks.front().first(output, clRemoteCommandStatus::STDERR);
}

void clRemoteHost::OnCommandStdout(clProcessEvent& event)
{
const std::string& output = event.GetStringRaw();
if(m_callbacks.empty()) {
LOG_WARNING(LOG) << "no callback found for command output" << endl;
return;
}
LOG_DEBUG(LOG) << "stdout:" << event.GetStringRaw().size() << "bytes" << endl;
// call the callback
m_callbacks.front().first(output, clRemoteCommandStatus::STDOUT);
}

void clRemoteHost::OnCommandCompleted(clProcessEvent& event)
{
if(m_callbacks.empty()) {
LOG_WARNING(LOG) << "no callback found for command output" << endl;
return;
}

// call the callback and consume it from the queue
LOG_DEBUG(LOG) << "command completed. exit status:" << event.GetInt() << endl;
m_callbacks.front().first("", event.GetInt() == 0 ? clRemoteCommandStatus::DONE
: clRemoteCommandStatus::DONE_WITH_ERROR);
delete m_callbacks.front().second;
m_callbacks.erase(m_callbacks.begin());
}

IProcess::Ptr_t clRemoteHost::run_interactive_process(wxEvtHandler* parent, const wxArrayString& command, size_t flags,
const wxString& wd, const clEnvList_t& env)
{
// interactive commands are running using their own ssh session
auto ssh_session = CreateSshSession();

// create new ssh session (or re-use one)
auto ssh_session = GetSshSession();
if(!ssh_session) {
LOG_ERROR(LOG) << "no ssh session available" << endl;
return IProcess::Ptr_t{};
Expand All @@ -244,35 +210,4 @@ IProcess::Ptr_t clRemoteHost::run_interactive_process(wxEvtHandler* parent, cons
return run_interactive_process(parent, wxargv, flags, wd, env);
}

void clRemoteHost::StopRunningCommands() { m_executor.shutdown(); }

bool clRemoteHost::run_command_sync(const std::vector<wxString>& command, const wxString& wd, const clEnvList_t& env,
std::string* output)
{
return m_executor.execute_command(clRemoteExecutor::Cmd::from(command, wd, env), m_activeAccount, output);
}

bool clRemoteHost::run_command_sync(const wxString& command, const wxString& wd, const clEnvList_t& env,
std::string* output)
{
auto wxargv = StringUtils::BuildArgv(command);
return run_command_sync(wxargv, wd, env, output);
}

IProcess::Ptr_t clRemoteHost::run_process(wxEvtHandler* parent, const wxString& command, const wxString& wd,
const clEnvList_t& env)
{
auto wxargv = StringUtils::BuildArgv(command);
return run_process(parent, wxargv, wd, env);
}

IProcess::Ptr_t clRemoteHost::run_process(wxEvtHandler* parent, const std::vector<wxString>& command,
const wxString& wd, const clEnvList_t& env)
{
clSSHChannel::Ptr_t channel{ m_executor.execute(clRemoteExecutor::Cmd::from(command, wd, env), m_activeAccount,
parent) };
IProcess::Ptr_t adpter{ new clSSHChannelProcessAdapter{ parent, channel } };
return adpter;
}

#endif // USE_SFTP
Loading

0 comments on commit a9e2998

Please sign in to comment.