diff --git a/src/main.cpp b/src/main.cpp index ea7bd2c..90f42e3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,14 +20,10 @@ void print_help() { std::cout << std::endl; std::cout << "A tool for managing server configurations" << std::endl; std::cout << std::endl; + std::cout << "dropshell ..." << std::endl; std::cout << " help Show this help message" << std::endl; - std::cout << " version Show version information" << std::endl; - std::cout << " init DIR Add a local dropshell config directory (you can add several)" << std::endl; - std::cout << std::endl; - std::cout << std::endl; - std::cout << "Server commands:" << std::endl; - std::cout << " servers Summary of all configured servers" << std::endl; - std::cout << " servers NAME Show details for specific server" << std::endl; + std::cout << " init DIR Add DIR as a local configuration directory for dropshell (can add several)" << std::endl; + std::cout << " server NAME Show details for specific server" << std::endl; std::cout << " templates List all available templates" << std::endl; std::cout << std::endl; std::cout << std::endl; @@ -35,8 +31,9 @@ void print_help() { std::cout << " install SERVER [SERVICE] Install/reinstall/update service(s). Non-destructive." << std::endl; std::cout << " COMMAND SERVER [SERVICE] Run a command on service(s)." << std::endl; std::cout << std::endl; - std::cout << "Standard commands: install, backup, uninstall, start, stop" << std::endl; + std::cout << "Standard commands: install, uninstall, backup, restore, start, stop" << std::endl; std::cout << std::endl; + std::cout << " ssh SERVER [SERVICE] Launch an interactive shell on a server or service" << std::endl; std::cout << std::endl; std::cout << "Creation commands: (apply to the first local config directory)"<is_config_set()) commands.merge(std::set{ - "servers","templates","create-service","create-template","create-server" + "server","templates","create-service","create-template","create-server","ssh" }); for (const auto& command : commands) { @@ -183,7 +180,7 @@ int main(int argc, char* argv[]) { return 0; } - if (cmd == "servers") { + if (cmd == "server") { if (argc > 2) { // Show details for specific server dropshell::show_server_details(argv[2]); @@ -226,6 +223,16 @@ int main(int argc, char* argv[]) { return 0; } + if (cmd == "ssh" && argc < 4) { + if (argc < 3) + { + std::cerr << "Error: ssh requires a server name and optionally service name" << std::endl; + return 1; + } + dropshell::interactive_ssh(argv[2], ""); + return 0; + } + // handle running a command. for (const auto& command : commands) { if (cmd == command) { diff --git a/src/servers.hpp b/src/servers.hpp index 9f02ff4..4e7eda3 100644 --- a/src/servers.hpp +++ b/src/servers.hpp @@ -8,20 +8,20 @@ namespace dropshell { -// Server information structure -struct ServerInfo { - std::string name; - std::string ssh_host; - std::string ssh_user; - std::string ssh_port; -}; + // Server information structure + struct ServerInfo { + std::string name; + std::string ssh_host; + std::string ssh_user; + std::string ssh_port; + }; -std::vector get_configured_servers(); -void list_servers(); -void show_server_details(const std::string& server_name); - -void create_server(const std::string& server_name); + std::vector get_configured_servers(); + void list_servers(); + void show_server_details(const std::string& server_name); + void create_server(const std::string& server_name); + } // namespace dropshell #endif // SERVERS_HPP diff --git a/src/service_runner.cpp b/src/service_runner.cpp index 901dfa2..9880c00 100644 --- a/src/service_runner.cpp +++ b/src/service_runner.cpp @@ -270,6 +270,10 @@ bool service_runner::run_command(const std::string& command) { return uninstall(); if (command == "backup") return backup(); + if (command == "ssh") { + interactive_ssh_service(); + return true; + } // Run the generic command std::string run_cmd = construct_standard_command_run_cmd(command); @@ -480,4 +484,48 @@ std::string service_runner::healthmark() return HealthStatus2String(status); } +void interactive_ssh(const std::string & server_name, const std::string & command) { + std::string serverpath = get_local_server_path(server_name); + if (serverpath.empty()) { + std::cerr << "Error: Server not found: " << server_name << std::endl; + return; + } + + server_env env(server_name); + if (!env.is_valid()) { + std::cerr << "Error: Invalid server environment file: " << server_name << std::endl; + return; + } + + std::string ssh_address = env.get_SSH_HOST(); + std::string ssh_user = env.get_SSH_USER(); + std::string ssh_port = env.get_SSH_PORT(); + + std::string login = ssh_user + "@" + ssh_address; + + // Execute ssh with server_name and command + if (command.empty()) + execlp("ssh", "ssh", login.c_str(), "-p", ssh_port.c_str(), nullptr); + else + execlp("ssh", "ssh", login.c_str(), "-p", ssh_port.c_str(), command.c_str(), nullptr); + + // If exec returns, it means there was an error + perror("ssh execution failed"); + exit(EXIT_FAILURE); +} + +void service_runner::interactive_ssh_service() +{ + std::set used_commands = get_used_commands(m_server_name, m_service_info.service_name); + if (used_commands.find("ssh") == used_commands.end()) { + std::cerr << "Error: "<< m_service_info.service_name <<" does not support ssh" << std::endl; + return; + } + + std::string command = construct_standard_command_run_cmd("ssh"); + interactive_ssh(m_server_name, command); +} + + + } // namespace dropshell \ No newline at end of file diff --git a/src/service_runner.hpp b/src/service_runner.hpp index 7c0b9d9..7f6e8ca 100644 --- a/src/service_runner.hpp +++ b/src/service_runner.hpp @@ -80,7 +80,9 @@ class service_runner { // 4. copy it to the local user_dir/backups folder bool backup(); - + // launch an interactive ssh session on a server or service + // replaces the current dropshell process with the ssh process + void interactive_ssh_service(); private: std::string m_server_name; @@ -106,6 +108,7 @@ class service_runner { static bool execute_local_command_and_capture_output(const std::string& command, std::string & output); }; + void interactive_ssh(const std::string & server_name, const std::string & command); } // namespace dropshell diff --git a/src/services.cpp b/src/services.cpp index a98d659..63cdb06 100644 --- a/src/services.cpp +++ b/src/services.cpp @@ -4,6 +4,7 @@ #include "templates.hpp" #include "config.hpp" #include "utils/utils.hpp" +#include "server_env.hpp" #include #include diff --git a/src/services.hpp b/src/services.hpp index 1c50d85..befede7 100644 --- a/src/services.hpp +++ b/src/services.hpp @@ -20,6 +20,8 @@ namespace dropshell { bool create_service(const std::string& server_name, const std::string& service_name); + void interactive_ssh(const std::string & server_name, const std::string & service_name, const std::string & command); + } // namespace dropshell