diff --git a/src/autocomplete.cpp b/src/autocomplete.cpp index 8ee773f..98d881c 100644 --- a/src/autocomplete.cpp +++ b/src/autocomplete.cpp @@ -52,7 +52,7 @@ void dropshell::autocomplete(const std::vector &args) std::vector templates; get_templates(templates); for (const auto& t : templates) - std::cout << t.name << std::endl; + std::cout << t.template_name << std::endl; return; } diff --git a/src/main.cpp b/src/main.cpp index 512da45..69a0e05 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -210,12 +210,12 @@ int main(int argc, char* argv[]) { } for (const auto& service_info : servicelist) { - dropshell::service_runner service; - if (!service.init(server_name, service_info.service_name)) { + dropshell::service_runner runner(server_name, service_info.service_name); + if (!runner.isValid) { std::cerr << "Error: Failed to initialize service" << std::endl; return 1; } - if (!service.run_command(command)) { + if (!runner.run_command(command)) { std::cerr << command +" failed." << std::endl; return 1; } diff --git a/src/main_commands.cpp b/src/main_commands.cpp index ab4e287..de4a310 100644 --- a/src/main_commands.cpp +++ b/src/main_commands.cpp @@ -6,6 +6,8 @@ #include "service_runner.hpp" #include "config.hpp" #include "templates.hpp" +#include "server_env.hpp" + #include #include #include @@ -59,9 +61,8 @@ int restore(const std::vector &args) std::string service_name = args[3]; std::string backup_file = args[4]; - ServiceInfo service_info = get_service_info(server_name, service_name); - if (service_info.path.empty()) { + if (service_info.local_service_path.empty()) { std::cerr << "Error: Service not found" << std::endl; return 1; } @@ -113,10 +114,9 @@ int backup(const std::vector & args) { std::string server_name = args[2]; std::string service_name = args[3]; - service_runner runner; - if (!runner.init(server_name, service_name)) - { - std::cerr << "Error: Failed to initialise service runner" << std::endl; + ServiceInfo service_info = get_service_info(server_name, service_name); + if (service_info.local_service_path.empty()) { + std::cerr << "Error: Service not found" << std::endl; return 1; } @@ -125,17 +125,23 @@ int backup(const std::vector & args) { std::cerr << "Error: Invalid server environment" << std::endl; return 1; } - + std::string command = "backup"; - std::string script_path = runner.sr_get_local_service_template_path() + "/" + command + ".sh"; - if (!template_command_exists(runner.sr_get_service_template_name(), command)) { - std::cout << "No backup script for " << runner.sr_get_service_template_name() << std::endl; + if (!template_command_exists(service_info.template_name, command)) { + std::cout << "No backup script for " << service_info.template_name << std::endl; return true; // nothing to back up. } // Check if basic installed stuff is in place. - if (!runner.check_remote_items_exist({runner.sr_get_remote_service_path(),script_path,runner.sr_get_remote_service_env_file()})) + std::string remote_service_template_path = get_remote_service_template_path(server_name, service_name); + std::string remote_script_path = remote_service_template_path + "/" + command + ".sh"; + std::string remote_service_env_file = get_remote_service_env_file(server_name, service_name); + if (!env.check_remote_items_exist({ + get_remote_service_path(server_name, service_name), + remote_script_path, + remote_service_env_file}) + ) { std::cerr << "Error: Required service directories not found on remote server" << std::endl; std::cerr << "Is the service installed?" << std::endl; @@ -146,7 +152,7 @@ int backup(const std::vector & args) { std::string remote_backups_dir = get_remote_backups_path(server_name); std::cout << "Remote backups directory on "<< server_name <<": " << remote_backups_dir << std::endl; std::string mkdir_cmd = "'mkdir -p " + quote(remote_backups_dir) + "'"; - if (!runner.execute_ssh_command(mkdir_cmd, "Failed to create backups directory on server")) { + if (!env.execute_ssh_command(mkdir_cmd, "Failed to create backups directory on server")) { return false; } @@ -167,10 +173,10 @@ int backup(const std::vector & args) { if (name_breaks_backups(server_name)) {std::cerr << "Error: Server name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;} if (name_breaks_backups(service_name)) {std::cerr << "Error: Service name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;} - if (name_breaks_backups(runner.sr_get_service_template_name())) {std::cerr << "Error: Service template name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;} + if (name_breaks_backups(service_info.template_name)) {std::cerr << "Error: Service template name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;} // Construct backup filename - std::string backup_filename = server_name + "-_-" + runner.sr_get_service_template_name() + "-_-" + service_name + "-_-" + datetime.str() + ".tgz"; + std::string backup_filename = server_name + "-_-" + service_info.template_name + "-_-" + service_name + "-_-" + datetime.str() + ".tgz"; std::string remote_backup_file_path = remote_backups_dir + "/" + backup_filename; std::string local_backup_file_path = (std::filesystem::path(local_backups_dir) / backup_filename).string(); @@ -178,20 +184,21 @@ int backup(const std::vector & args) { ASSERT(3 == count_substring("-_-", local_backup_file_path)); // Run backup script - std::string backup_cmd = "'cd " + quote(runner.sr_get_remote_service_template_path()) + - " && /bin/bash "+quote(script_path)+" "+quote(runner.sr_get_remote_service_config_path())+" "+ + std::string backup_cmd = "'cd " + quote(remote_service_template_path) + + " && /bin/bash "+quote(remote_script_path)+" "+quote(remote_service_env_file)+" "+ quote(remote_backup_file_path)+"'"; - if (!runner.execute_ssh_command(backup_cmd, "Backup script failed")) { + if (!env.execute_ssh_command(backup_cmd, "Backup script failed")) { std::cerr << "Backup script failed: " << backup_cmd << std::endl; return false; - } + } std::cout << "Remote backups directory on "<< server_name <<": " << get_remote_backups_path(server_name) << std::endl; + // Copy backup file from server to local - std::string scp_cmd = "scp -P " + runner.sr_get_server_env().get_SSH_PORT() + " " + - runner.sr_get_server_env().get_SSH_USER() + "@" + runner.sr_get_server_env().get_SSH_HOST() + ":" + + std::string scp_cmd = "scp -P " + env.get_SSH_PORT() + " " + + env.get_SSH_USER() + "@" + env.get_SSH_HOST() + ":" + quote(remote_backup_file_path) + " " + quote(local_backup_file_path); - if (!runner.execute_local_command(scp_cmd, "Failed to copy backup file from server")) { + if (!env.execute_local_command(scp_cmd, "Failed to copy backup file from server")) { return false; } diff --git a/src/server_env.cpp b/src/server_env.cpp index 40ca9a2..af59c6e 100644 --- a/src/server_env.cpp +++ b/src/server_env.cpp @@ -1,6 +1,9 @@ #include "server_env.hpp" #include "utils/envmanager.hpp" #include "utils/directories.hpp" +#include "utils/utils.hpp" +#include "services.hpp" + #include #include #include @@ -10,7 +13,7 @@ bool server_env::is_valid() const { return mValid; } -server_env::server_env(const std::string& server_name) : mValid(false) { +server_env::server_env(const std::string& server_name) : mValid(false), mServer_name(server_name) { if (server_name.empty()) { std::cerr << "Warning: Server name is empty, passed to server_env constructor." << std::endl; @@ -22,7 +25,8 @@ server_env::server_env(const std::string& server_name) : mValid(false) { // Check if file exists if (!std::filesystem::exists(env_path)) { - throw std::runtime_error("Server environment file not found: " + env_path); + std::cerr << "Server environment file not found: " + env_path << std::endl; + return; } try { @@ -47,8 +51,8 @@ server_env::server_env(const std::string& server_name) : mValid(false) { mValid = true; } catch (const std::exception& e) { - throw std::runtime_error("Failed to parse server environment file: " + std::string(e.what())); - } + std::cerr << "Failed to parse server environment file: " + std::string(e.what()) << std::endl; + } } std::string server_env::get_variable(const std::string& name) const { @@ -79,4 +83,90 @@ std::string server_env::get_DROPSHELL_DIR() const { return get_variable("DROPSHELL_DIR"); } +// Helper method implementations +std::string server_env::construct_ssh_cmd() const { + std::stringstream ssh_cmd; + ssh_cmd << "ssh -p " << get_SSH_PORT() << " " + << get_SSH_USER() << "@" << get_SSH_HOST() << " "; + return ssh_cmd.str(); +} + +std::string server_env::construct_standard_command_run_cmd(const std::string &service_name, const std::string &command) const +{ + std::string remote_service_template_path = get_remote_service_template_path(mServer_name,service_name); + std::string remote_service_config_path = get_remote_service_config_path(mServer_name,service_name); + + std::string script_path = remote_service_template_path + "/" + command + ".sh"; + std::string run_cmd = "'cd " + quote(remote_service_template_path) + + " && /bin/bash "+quote(script_path)+" "+quote(remote_service_config_path)+"'"; + return run_cmd; +} + +bool server_env::check_remote_dir_exists(const std::string &dir_path) const +{ + std::string check_dir_cmd = construct_ssh_cmd() + "'test -d " + quote(dir_path) + "'"; + if (system(check_dir_cmd.c_str()) != 0) { + std::cerr << "Error: Directory not found on remote server:" << std::filesystem::path(dir_path).filename().string() << std::endl; + return false; + } + return true; +} + +bool server_env::check_remote_file_exists(const std::string& file_path) const { + std::string check_cmd = construct_ssh_cmd() + "'test -f " + quote(file_path) + "'"; + if (system(check_cmd.c_str()) != 0) { + std::cerr << "Error: File not found on remote server: " << std::filesystem::path(file_path).filename().string() << std::endl; + return false; + } + return true; +} + +bool server_env::check_remote_items_exist(const std::vector &file_paths) const +{ + // convert file_paths to a single string, separated by spaces + std::string file_paths_str; + std::string file_names_str; + for (const auto& file_path : file_paths) { + file_paths_str += quote(file_path) + " "; + file_names_str += std::filesystem::path(file_path).filename().string() + " "; + } + // check if all items in the vector exist on the remote server, in a single command. + std::string check_cmd = construct_ssh_cmd() + "'for item in " + file_paths_str + "; do test -f $item; done'"; + if (system(check_cmd.c_str()) != 0) { + std::cerr << "Error: Required items not found on remote server: " << file_names_str << std::endl; + return false; + } + return true; +} + +bool server_env::execute_ssh_command(const std::string& command, const std::string& error_msg) const { + std::string full_cmd = construct_ssh_cmd() + command; + return execute_local_command(full_cmd, error_msg); +} + +bool server_env::execute_local_command(const std::string& command, const std::string& error_msg) { + bool okay = (system(command.c_str()) == 0); + + if (!okay && !error_msg.empty()) + std::cerr << "Error: " << error_msg << std::endl; + return okay; +} + +bool server_env::execute_local_command_and_capture_output(const std::string &command, std::string &output) +{ + std::string full_cmd = command + " 2>&1"; + FILE *pipe = popen(full_cmd.c_str(), "r"); + if (!pipe) { + std::cerr << "Error: Failed to execute command: " << command << std::endl; + return false; + } + char buffer[128]; + while (fgets(buffer, sizeof(buffer), pipe) != nullptr) { + output += buffer; + } + pclose(pipe); + return true; +} + + } // namespace dropshell \ No newline at end of file diff --git a/src/server_env.hpp b/src/server_env.hpp index e16a8bd..93ba3ff 100644 --- a/src/server_env.hpp +++ b/src/server_env.hpp @@ -32,7 +32,21 @@ class server_env { bool is_valid() const; +// helper functions + public: + std::string construct_ssh_cmd() const; + std::string construct_standard_command_run_cmd(const std::string& service_name, const std::string& command) const; + bool check_remote_items_exist(const std::vector& file_paths) const; + bool execute_ssh_command(const std::string& command, const std::string& error_msg) const; + + static bool execute_local_command(const std::string& command, const std::string& error_msg); + static bool execute_local_command_and_capture_output(const std::string& command, std::string & output); + + bool check_remote_dir_exists(const std::string &dir_path) const; + bool check_remote_file_exists(const std::string& file_path) const; + private: + std::string mServer_name; std::map variables; bool mValid; std::unique_ptr m_env_manager; diff --git a/src/service_runner.cpp b/src/service_runner.cpp index 191b5b1..71071c3 100644 --- a/src/service_runner.cpp +++ b/src/service_runner.cpp @@ -19,26 +19,16 @@ namespace fs = std::filesystem; namespace dropshell { -service_runner::service_runner() : m_server_name(""), m_server_env(nullptr) {} - -bool service_runner::init(const std::string& server_name, const std::string& service_name) { +service_runner::service_runner(const std::string& server_name, const std::string& service_name) : + m_server_env(server_name), m_server_name(server_name), mValid(false) +{ if (server_name.empty() || service_name.empty()) - return false; + return; // Initialize server environment - try { - m_server_env = std::make_unique(server_name); - if (!m_server_env->is_valid()) { - std::cerr << "Error: Invalid server environment" << std::endl; - m_server_env.reset(); - return false; - } - } catch (const std::exception& e) { - std::cerr << "Error: Failed to initialize server environment: " << e.what() << std::endl; - return false; - } + if (!m_server_env.is_valid()) + return; - m_server_name = server_name; m_service_info = get_service_info(server_name, service_name); mRemote_service_path = get_remote_service_path(m_server_name, m_service_info.service_name); @@ -46,101 +36,13 @@ bool service_runner::init(const std::string& server_name, const std::string& ser mRemote_service_template_path = get_remote_service_template_path(m_server_name, m_service_info.service_name); mRemote_service_env_file = get_remote_service_env_file(m_server_name, m_service_info.service_name); - return !m_service_info.path.empty(); -} - -// Helper method implementations -std::string service_runner::construct_ssh_cmd(const server_env &env) { - std::stringstream ssh_cmd; - ssh_cmd << "ssh -p " << env.get_SSH_PORT() << " " - << env.get_SSH_USER() << "@" << env.get_SSH_HOST() << " "; - return ssh_cmd.str(); -} - -std::string service_runner::construct_ssh_cmd() const -{ - if (!m_server_env) - return std::string(); - return construct_ssh_cmd(*m_server_env); -} - -std::string service_runner::construct_standard_command_run_cmd(const std::string &command) const -{ - std::string script_path = mRemote_service_template_path + "/" + command + ".sh"; - std::string run_cmd = "'cd " + quote(mRemote_service_template_path) + - " && /bin/bash "+quote(script_path)+" "+quote(mRemote_service_config_path)+"'"; - return run_cmd; -} - -bool service_runner::check_remote_dir_exists(const std::string &dir_path) const -{ - std::string check_dir_cmd = construct_ssh_cmd() + "'test -d " + quote(dir_path) + "'"; - if (system(check_dir_cmd.c_str()) != 0) { - std::cerr << "Error: Directory not found on remote server:" << fs::path(dir_path).filename().string() << std::endl; - return false; - } - return true; -} - -bool service_runner::check_remote_file_exists(const std::string& file_path) const { - std::string check_cmd = construct_ssh_cmd() + "'test -f " + quote(file_path) + "'"; - if (system(check_cmd.c_str()) != 0) { - std::cerr << "Error: File not found on remote server: " << fs::path(file_path).filename().string() << std::endl; - return false; - } - return true; -} - -bool service_runner::check_remote_items_exist(const std::vector &file_paths) const -{ - // convert file_paths to a single string, separated by spaces - std::string file_paths_str; - std::string file_names_str; - for (const auto& file_path : file_paths) { - file_paths_str += quote(file_path) + " "; - file_names_str += fs::path(file_path).filename().string() + " "; - } - // check if all items in the vector exist on the remote server, in a single command. - std::string check_cmd = construct_ssh_cmd() + "'for item in " + file_paths_str + "; do test -f $item; done'"; - if (system(check_cmd.c_str()) != 0) { - std::cerr << "Error: Required items not found on remote server: " << file_names_str << std::endl; - return false; - } - return true; -} - -bool service_runner::execute_ssh_command(const std::string& command, const std::string& error_msg) const { - std::string full_cmd = construct_ssh_cmd() + command; - return execute_local_command(full_cmd, error_msg); -} -bool service_runner::execute_local_command(const std::string& command, const std::string& error_msg) const { - bool okay = (system(command.c_str()) == 0); - - if (!okay && !error_msg.empty()) - std::cerr << "Error: " << error_msg << std::endl; - return okay; -} - -bool service_runner::execute_local_command_and_capture_output(const std::string &command, std::string &output) -{ - std::string full_cmd = command + " 2>&1"; - FILE *pipe = popen(full_cmd.c_str(), "r"); - if (!pipe) { - std::cerr << "Error: Failed to execute command: " << command << std::endl; - return false; - } - char buffer[128]; - while (fgets(buffer, sizeof(buffer), pipe) != nullptr) { - output += buffer; - } - pclose(pipe); - return true; + mValid = !m_service_info.local_template_path.empty(); } bool service_runner::install() { maketitle("Installing " + m_service_info.service_name + " (" + m_service_info.template_name + ") on " + m_server_name); - if (!m_server_env) return false; // should never hit this. + if (!m_server_env.is_valid()) return false; // should never hit this. // Check if template exists template_info tinfo; @@ -149,23 +51,23 @@ bool service_runner::install() { // Create service directory std::string mkdir_cmd = "'mkdir -p " + quote(mRemote_service_path) + "'"; - if (!execute_ssh_command(mkdir_cmd, "Failed to create service directory")) + if (!m_server_env.execute_ssh_command(mkdir_cmd, "Failed to create service directory")) return false; // Check if rsync is installed on remote host std::string check_rsync_cmd = "'which rsync > /dev/null 2>&1'"; - if (!execute_ssh_command(check_rsync_cmd, "rsync is not installed on the remote host")) + if (!m_server_env.execute_ssh_command(check_rsync_cmd, "rsync is not installed on the remote host")) return false; // Copy template files { - std::cout << "Copying template files from [LOCAL] " << tinfo.path << std::endl << std::string(24,' ')<<"to [REMOTE] " << mRemote_service_template_path << "/" << std::endl; - std::string rsync_cmd = "rsync --delete -zrpc -e 'ssh -p " + m_server_env->get_SSH_PORT() + "' " + - quote(tinfo.path + "/") + " "+ - m_server_env->get_SSH_USER() + "@" + m_server_env->get_SSH_HOST() + ":" + + std::cout << "Copying template files from [LOCAL] " << tinfo.local_template_path << std::endl << std::string(24,' ')<<"to [REMOTE] " << mRemote_service_template_path << "/" << std::endl; + std::string rsync_cmd = "rsync --delete -zrpc -e 'ssh -p " + m_server_env.get_SSH_PORT() + "' " + + quote(tinfo.local_template_path + "/") + " "+ + m_server_env.get_SSH_USER() + "@" + m_server_env.get_SSH_HOST() + ":" + quote(mRemote_service_template_path+"/"); //std::cout << std::endl << rsync_cmd << std::endl << std::endl; - execute_local_command(rsync_cmd,"Failed to copy template files"); + m_server_env.execute_local_command(rsync_cmd,"Failed to copy template files"); } // Copy service files (including service.env) @@ -176,17 +78,17 @@ bool service_runner::install() { return false; } std::cout << "Copying service files from [LOCAL] " << local_service_path << std::endl <get_SSH_PORT() + "' " + + std::string rsync_cmd = "rsync --delete -zrpc -e 'ssh -p " + m_server_env.get_SSH_PORT() + "' " + quote(local_service_path + "/") + " "+ - m_server_env->get_SSH_USER() + "@" + m_server_env->get_SSH_HOST() + ":" + + m_server_env.get_SSH_USER() + "@" + m_server_env.get_SSH_HOST() + ":" + quote(mRemote_service_config_path + "/"); - execute_local_command(rsync_cmd,"Failed to copy service files"); + m_server_env.execute_local_command(rsync_cmd,"Failed to copy service files"); } // Run install script { - std::string install_cmd = construct_standard_command_run_cmd("install"); - bool ok= execute_ssh_command(install_cmd, "Failed to run install script"); + std::string install_cmd = m_server_env.construct_standard_command_run_cmd(m_service_info.service_name, "install"); + bool ok= m_server_env.execute_ssh_command(install_cmd, "Failed to run install script"); if (!ok) return false; } @@ -199,21 +101,21 @@ bool service_runner::install() { bool service_runner::uninstall() { maketitle("Uninstalling " + m_service_info.service_name + " (" + m_service_info.template_name + ") on " + m_server_name); - if (!m_server_env) return false; // should never hit this. + if (!m_server_env.is_valid()) return false; // should never hit this. // 2. Check if service directory exists on server - if (!check_remote_dir_exists(mRemote_service_path)) { + if (!m_server_env.check_remote_dir_exists(mRemote_service_path)) { std::cerr << "Service is not installed: " << m_service_info.service_name << std::endl; return true; // Nothing to uninstall } // 3. Run uninstall script if it exists std::string uninstall_script = mRemote_service_template_path + "/_uninstall.sh"; - bool script_exists = check_remote_file_exists(uninstall_script); + bool script_exists = m_server_env.check_remote_file_exists(uninstall_script); if (script_exists) { - std::string uninstall_cmd = construct_standard_command_run_cmd("uninstall"); - if (!execute_ssh_command(uninstall_cmd, "Failed to run uninstall script")) { + std::string uninstall_cmd = m_server_env.construct_standard_command_run_cmd(m_service_info.service_name, "uninstall"); + if (!m_server_env.execute_ssh_command(uninstall_cmd, "Failed to run uninstall script")) { std::cerr << "Warning: Uninstall script failed, but continuing with directory removal" << std::endl; } } else { @@ -223,7 +125,7 @@ bool service_runner::uninstall() { // 4. Remove the service directory from the server std::string rm_cmd = "'rm -rf " + quote(mRemote_service_path) + "'"; - if (!execute_ssh_command(rm_cmd, "Failed to remove service directory")) { + if (!m_server_env.execute_ssh_command(rm_cmd, "Failed to remove service directory")) { return false; } @@ -236,7 +138,7 @@ bool service_runner::uninstall() { // Run a command on the service. // ------------------------------------------------------------------------------------------------ bool service_runner::run_command(const std::string& command) { - if (!m_server_env) { + if (!m_server_env.is_valid()) { std::cerr << "Error: Server service not initialized" << std::endl; return false; } @@ -264,17 +166,17 @@ bool service_runner::run_command(const std::string& command) { std::string script_path = mRemote_service_template_path + "/" + command + ".sh"; // Check if service directory exists - if (!check_remote_dir_exists(mRemote_service_path)) { + if (!m_server_env.check_remote_dir_exists(mRemote_service_path)) { return false; } // Check if command script exists - if (!check_remote_file_exists(script_path)) { + if (!m_server_env.check_remote_file_exists(script_path)) { return false; } // Check if env file exists - if (!check_remote_file_exists(mRemote_service_env_file)) { + if (!m_server_env.check_remote_file_exists(mRemote_service_env_file)) { return false; } @@ -286,8 +188,8 @@ bool service_runner::run_command(const std::string& command) { } // Run the generic command - std::string run_cmd = construct_standard_command_run_cmd(command); - return execute_ssh_command(run_cmd, "Command returned error code: " + script_path); + std::string run_cmd = m_server_env.construct_standard_command_run_cmd(m_service_info.service_name, command); + return m_server_env.execute_ssh_command(run_cmd, "Command returned error code: " + script_path); } @@ -316,11 +218,11 @@ std::map service_runner::get_all_services_status(std } std::string script_path = remote_service_template_path + "/" + command + ".sh"; - std::string ssh_cmd = construct_ssh_cmd(env) + "'cd " + quote(remote_service_template_path) + + std::string ssh_cmd = env.construct_ssh_cmd() + "'cd " + quote(remote_service_template_path) + " && /bin/bash "+quote(script_path)+" "+quote(remote_service_config_path)+"'"; std::string output; - if (!execute_local_command_and_capture_output(ssh_cmd, output)) + if (!env.execute_local_command_and_capture_output(ssh_cmd, output)) return status; std::stringstream ss(output); @@ -359,7 +261,7 @@ std::map service_runner::get_all_services_status(std HealthStatus service_runner::is_healthy() { - if (!m_server_env) { + if (!m_server_env.is_valid()) { std::cerr << "Error: Server service not initialized" << std::endl; return HealthStatus::ERROR; } @@ -372,14 +274,14 @@ HealthStatus service_runner::is_healthy() } std::string script_path = mRemote_service_template_path + "/" + command + ".sh"; - if (!check_remote_file_exists(script_path)) { + if (!m_server_env.check_remote_file_exists(script_path)) { std::cerr << "Service is not installed: " << m_service_info.service_name << std::endl; return HealthStatus::NOTINSTALLED; } // Run status script, does not display output. - std::string run_cmd = construct_standard_command_run_cmd("status"); - bool ok = execute_ssh_command(run_cmd, ""); + std::string run_cmd = m_server_env.construct_standard_command_run_cmd(m_service_info.service_name, "status"); + bool ok = m_server_env.execute_ssh_command(run_cmd, ""); if (!ok) return HealthStatus::UNHEALTHY; @@ -506,7 +408,7 @@ void service_runner::interactive_ssh_service() return; } - std::string command = construct_standard_command_run_cmd("ssh"); + std::string command = m_server_env.construct_standard_command_run_cmd(m_service_info.service_name, "ssh"); interactive_ssh(m_server_name, "/bin/bash -c '"+command+"'"); } diff --git a/src/service_runner.hpp b/src/service_runner.hpp index 48d13a3..22dd988 100644 --- a/src/service_runner.hpp +++ b/src/service_runner.hpp @@ -31,8 +31,8 @@ typedef struct ServiceStatus { class service_runner { public: - service_runner(); - bool init(const std::string& server_name, const std::string& service_name); + service_runner(const std::string& server_name, const std::string& service_name); + bool isValid; // run a command over ssh, using the credentials from server.env (via server_env.hpp) // first check that the command corresponds to a valid .sh file in the service directory @@ -89,42 +89,17 @@ class service_runner { private: std::string m_server_name; + server_env m_server_env; ServiceInfo m_service_info; - std::unique_ptr m_server_env; + bool mValid; std::string mRemote_service_path; std::string mRemote_service_config_path; std::string mRemote_service_template_path; std::string mRemote_service_env_file; - public: - std::string sr_get_server_name() const { return m_server_name; } - std::string sr_get_service_name() const { return m_service_info.service_name; } - std::string sr_get_service_path() const { return m_service_info.path; } - std::string sr_get_service_template_name() const { return m_service_info.template_name; } - std::string sr_get_local_service_template_path() const { return m_service_info.template_local_path; } - - ServiceInfo sr_get_service_info() const { return m_service_info; } - const server_env& sr_get_server_env() const { ASSERT(m_server_env); return *m_server_env; } - - const std::string& sr_get_remote_service_path() const { return mRemote_service_path; } - const std::string& sr_get_remote_service_config_path() const { return mRemote_service_config_path; } - const std::string& sr_get_remote_service_template_path() const { return mRemote_service_template_path; } - const std::string& sr_get_remote_service_env_file() const { return mRemote_service_env_file; } - // Helper methods public: - static std::string construct_ssh_cmd(const server_env &env); - - std::string construct_ssh_cmd() const; - std::string construct_standard_command_run_cmd(const std::string& command) const; - - bool check_remote_dir_exists(const std::string& dir_path) const; - bool check_remote_file_exists(const std::string& file_path) const; - bool check_remote_items_exist(const std::vector& file_paths) const; - bool execute_ssh_command(const std::string& command, const std::string& error_msg) const; - bool execute_local_command(const std::string& command, const std::string& error_msg) const; - static bool execute_local_command_and_capture_output(const std::string& command, std::string & output); }; diff --git a/src/services.cpp b/src/services.cpp index 3be6085..da2f261 100644 --- a/src/services.cpp +++ b/src/services.cpp @@ -51,16 +51,17 @@ std::vector get_server_services_info(const std::string& server_name ServiceInfo get_service_info(const std::string &server_name, const std::string &service_name) { + ServiceInfo service; + if (server_name.empty() || service_name.empty()) return ServiceInfo(); - std::string service_dir = get_local_service_path(server_name, service_name); - if (service_dir.empty()) + service.service_name = service_name; + + service.local_service_path = get_local_service_path(server_name, service_name); + if (service.local_service_path.empty()) return ServiceInfo(); - ServiceInfo service; - service.path = service_dir; - service.service_name = service_name; // now set the template name and path. std::string local_service_env_path = get_local_service_env_path(server_name, service_name); @@ -83,7 +84,7 @@ ServiceInfo get_service_info(const std::string &server_name, const std::string & } // find the template path - service.template_local_path = tinfo.path; + service.local_template_path = tinfo.local_template_path; return service; } @@ -95,16 +96,15 @@ std::set get_used_commands(const std::string &server_name, const st if (server_name.empty() || service_name.empty()) return commands; - ServiceInfo service = get_service_info(server_name, service_name); - if (service.template_local_path.empty()) { + ServiceInfo service_info = get_service_info(server_name, service_name); + if (service_info.local_template_path.empty()) { std::cerr << "Error: Service not found: " << service_name << std::endl; return commands; } // iterate over all files in the template path, and add the command name to the set. // commands are .sh files that don't begin with _ - fs::path template_path = fs::path(service.template_local_path); - for (const auto& entry : fs::directory_iterator(template_path)) { + for (const auto& entry : fs::directory_iterator(service_info.local_template_path)) { if (fs::is_regular_file(entry) && entry.path().extension() == ".sh" && (entry.path().filename().string().rfind("_", 0) != 0)) commands.insert(entry.path().stem().string()); } @@ -171,7 +171,7 @@ bool create_service(const std::string &server_name, const std::string &template_ fs::create_directory(service_dir); // copy the template example files to the service directory - recursive_copy(tinfo.path+"/example", service_dir); + recursive_copy(tinfo.local_template_path+"/example", service_dir); std::cout << "Service " << service_name <<" created successfully"< get_server_services_info(const std::string& server_name); diff --git a/src/templates.cpp b/src/templates.cpp index 41c0144..a5fb0ce 100644 --- a/src/templates.cpp +++ b/src/templates.cpp @@ -25,17 +25,17 @@ bool get_templates(std::vector& templates) { for (const auto& entry : std::filesystem::directory_iterator(dir_path)) { if (entry.is_directory()) { template_info info; - info.name = entry.path().filename().string(); - info.path = entry.path().string(); + info.template_name = entry.path().filename().string(); + info.local_template_path = entry.path().string(); // Check if template with same name already exists - bool found = false; + bool duplicate = false; auto it = std::find_if(templates.begin(), templates.end(), - [&info](const template_info& t) { return t.name == info.name; }); - found = (it!=templates.end()); - found |= info.name=="example"; // don't include the example template! + [&info](const template_info& t) { return t.template_name == info.template_name; }); + duplicate = (it!=templates.end()); + duplicate |= (info.template_name=="example"); // don't include the example template! - if (!found) { + if (!duplicate) { templates.push_back(info); } } @@ -58,14 +58,14 @@ bool get_templates(std::vector& templates) { return true; } -bool get_template_info(const std::string& name, template_info& info) { +bool get_template_info(const std::string& template_name, template_info& info) { std::vector templates; if (!get_templates(templates)) { return false; } auto it = std::find_if(templates.begin(), templates.end(), - [&name](const template_info& t) { return t.name == name; }); + [&template_name](const template_info& t) { return t.template_name == template_name; }); if (it != templates.end()) { info = *it; @@ -82,7 +82,7 @@ bool template_command_exists(const std::string &template_name, const std::string return false; } - std::string path = info.path + "/" + command + ".sh"; + std::string path = info.local_template_path + "/" + command + ".sh"; return (std::filesystem::exists(path)); } @@ -104,7 +104,7 @@ void list_templates() { std::cout << std::string(60, '-') << std::endl; for (const auto& t : templates) { - std::cout << std::left << std::setw(20) << t.name << t.path << std::endl; + std::cout << std::left << std::setw(20) << t.template_name << t.local_template_path << std::endl; } } @@ -120,7 +120,7 @@ void create_template(const std::string& template_name) { template_info info; if (get_template_info(template_name, info)) { - std::cerr << "Error: Template '" << template_name << "' already exists at " << info.path << std::endl; + std::cerr << "Error: Template '" << template_name << "' already exists at " << info.local_template_path << std::endl; return; } diff --git a/src/templates.hpp b/src/templates.hpp index 3e5d895..6544b36 100644 --- a/src/templates.hpp +++ b/src/templates.hpp @@ -6,8 +6,8 @@ namespace dropshell { class template_info { public: - std::string name; - std::string path; + std::string template_name; + std::string local_template_path; }; // templates are stored in two locations: @@ -20,7 +20,7 @@ class template_info { bool get_templates(std::vector& templates); -bool get_template_info(const std::string& name, template_info& info); +bool get_template_info(const std::string& template_name, template_info& info); bool template_command_exists(const std::string& template_name,const std::string& command); void list_templates();