From 764ea2b03c0ff369cf4f572b9e7fef78b37a40eb Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 29 Aug 2025 19:54:53 +1200 Subject: [PATCH] feat: Update 2 files --- source/src/commands/list.cpp | 92 +++++++++++++++++++++++++----------- source/src/utils/execute.cpp | 6 ++- 2 files changed, 70 insertions(+), 28 deletions(-) diff --git a/source/src/commands/list.cpp b/source/src/commands/list.cpp index 3ab1839..639a80d 100644 --- a/source/src/commands/list.cpp +++ b/source/src/commands/list.cpp @@ -2,6 +2,7 @@ #include "config.hpp" #include "utils/utils.hpp" #include "utils/directories.hpp" +#include "utils/execute.hpp" #include "shared_commands.hpp" #include "servers.hpp" #include "tableprint.hpp" @@ -100,6 +101,10 @@ void list_servers() { int checked = 0; + // First, check which servers are online (with caching per server, not per user) + std::map server_online_status; + std::mutex online_status_mutex; + transwarp::parallel exec{server_user_pairs.size()}; auto task = transwarp::for_each(exec, server_user_pairs.begin(), server_user_pairs.end(), [&](const server_user_pair& sup) { @@ -114,19 +119,45 @@ void list_servers() { std::string ports_used_str = ""; std::set ports_used; - std::map status = shared_commands::get_all_services_status(sup.server.get_server_name(),sup.user.user); - - for (const auto& [service_name, service_status] : status) { - ports_used.insert(service_status.ports.begin(), service_status.ports.end()); - serviceticks += shared_commands::HealthStatus2String(service_status.health) + " "; + // Check if server is online (with caching to avoid redundant checks for multiple users) + bool is_online = false; + { + std::lock_guard lock(online_status_mutex); + auto it = server_online_status.find(sup.server.get_server_name()); + if (it != server_online_status.end()) { + is_online = it->second; + } else { + // Quick connectivity check with short timeout (already set to 3s in execute.cpp) + sSSHInfo sshinfo = server_env.get_SSH_INFO(sup.user.user); + std::string test_cmd = "true"; + is_online = execute_ssh_command(sshinfo, sCommand("", test_cmd, {}), cMode::Silent); + server_online_status[sup.server.get_server_name()] = is_online; + } } - for (const auto& port : ports_used) - ports_used_str += std::to_string(port) + " "; + // Only check service status if server is online + if (is_online) { + std::map status = shared_commands::get_all_services_status(sup.server.get_server_name(),sup.user.user); + + for (const auto& [service_name, service_status] : status) { + ports_used.insert(service_status.ports.begin(), service_status.ports.end()); + serviceticks += shared_commands::HealthStatus2String(service_status.health) + " "; + } + + for (const auto& port : ports_used) + ports_used_str += std::to_string(port) + " "; + } + + // Add red cross to address if server is offline + std::string address_display = sup.server.get_SSH_HOST(); + if (!is_online) { + address_display += " :cross:"; + } + // critical section { std::lock_guard lock(tp_mutex); - tp.add_row({sup.server.get_server_name(), sup.server.get_SSH_HOST(), sup.user.user, serviceticks, ports_used_str}); + tp.add_row({sup.server.get_server_name(), address_display, sup.user.user, serviceticks, ports_used_str}); ++checked; // print out a tick character for each server checked. @@ -160,10 +191,9 @@ void show_server_details(const std::string& server_name) { info << std::endl << "Server Status:" << std::endl; info << std::string(40, '-') << std::endl; - // Try to connect to the server - std::string cmd = "ssh -o ConnectTimeout=5 " + sshinfo.get_user() + "@" + sshinfo.get_host() + " -p " + sshinfo.get_port() + " 'true' 2>/dev/null"; - int result = system(cmd.c_str()); - if (result == 0) { + // Try to connect to the server (using our improved timeout) + bool is_online = execute_ssh_command(sshinfo, sCommand("", "true", {}), cMode::Silent); + if (is_online) { info << "Status: Online" << std::endl; } else { warning << "Status: Offline" << std::endl; @@ -199,23 +229,31 @@ void show_server_details(const std::string& server_name) { tableprint tp("Services: " + server_name, false); tp.add_row({"Status", "Service", "Template","Ports"}); - std::map status = shared_commands::get_all_services_status(server_name); + if (is_online) { + std::map status = shared_commands::get_all_services_status(server_name); - std::set ports_used; - std::string serviceticks = ""; - for (const auto& [service_name, service_status] : status) { - std::string healthy = shared_commands::HealthStatus2String(service_status.health); + std::set ports_used; + std::string serviceticks = ""; + for (const auto& [service_name, service_status] : status) { + std::string healthy = shared_commands::HealthStatus2String(service_status.health); + + std::string ports_str = ""; + for (const auto& port : service_status.ports) + ports_str += std::to_string(port) + " "; + + std::string template_name = get_service_info(server_name,service_name).template_name; + if (template_name.empty()) + template_name = "Unknown"; - std::string ports_str = ""; - for (const auto& port : service_status.ports) - ports_str += std::to_string(port) + " "; - - std::string template_name = get_service_info(server_name,service_name).template_name; - if (template_name.empty()) - template_name = "Unknown"; - - tp.add_row({healthy, service_name, template_name, ports_str}); - } // end of for (const auto& service : services) + tp.add_row({healthy, service_name, template_name, ports_str}); + } // end of for (const auto& service : services) + } else { + // Server is offline, just list services without checking their status + std::vector services = get_server_services_info(server_name); + for (const auto& service : services) { + tp.add_row({":cross:", service.service_name, service.template_name, "-"}); + } + } tp.print(); } // end of list services } // end of show_server_details diff --git a/source/src/utils/execute.cpp b/source/src/utils/execute.cpp index 2843cf3..bae8e43 100644 --- a/source/src/utils/execute.cpp +++ b/source/src/utils/execute.cpp @@ -165,7 +165,11 @@ namespace dropshell return false; std::stringstream ssh_cmd; - ssh_cmd << "ssh -p " << ssh_info.get_port() << " " << (hasFlag(mode, cMode::Interactive) ? "-tt " : "") + // Add ConnectTimeout to prevent long waits on unreachable servers + // Use shorter timeout (3s) for non-interactive, longer (10s) for interactive + int timeout = hasFlag(mode, cMode::Interactive) ? 10 : 3; + ssh_cmd << "ssh -o ConnectTimeout=" << timeout << " -p " << ssh_info.get_port() << " " + << (hasFlag(mode, cMode::Interactive) ? "-tt " : "") << ssh_info.get_user() << "@" << ssh_info.get_host(); std::string remote_bb64_path;