diff --git a/src/config.cpp b/src/config.cpp index 81a113f..aeef1c1 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -10,9 +10,9 @@ namespace dropshell { -config *get_global_config() { - static config *gConfig = new config(); - return gConfig; +config & gConfig() { + static config *globalConfig = new config(); + return *globalConfig; } @@ -22,7 +22,7 @@ config::~config() { } bool config::load_config() { - std::string config_path = get_local_dropshell_config_file(); + std::string config_path = localfile::dropshell_conf(); if (config_path.empty() || !std::filesystem::exists(config_path)) return false; @@ -56,10 +56,10 @@ void config::save_config() return; } - std::string parent_path = get_local_dropshell_config_parent_path(); + std::string parent_path = dropshell::get_parent(localfile::dropshell_conf()); std::filesystem::create_directories(parent_path); - std::string config_path = get_local_dropshell_config_file(); + std::string config_path = localfile::dropshell_conf(); envmanager config_env(config_path); config_env.set_variable("local.config.directories", multi2string(mLocalConfigPaths)); diff --git a/src/config.hpp b/src/config.hpp index 32852b7..d4aedf5 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -25,6 +25,6 @@ class config { }; -config *get_global_config(); +config & gConfig(); } // namespace dropshell \ No newline at end of file diff --git a/src/server_env.cpp b/src/server_env_manager.cpp similarity index 74% rename from src/server_env.cpp rename to src/server_env_manager.cpp index 3e9097f..88183df 100644 --- a/src/server_env.cpp +++ b/src/server_env_manager.cpp @@ -1,4 +1,4 @@ -#include "server_env.hpp" +#include "server_env_manager.hpp" #include "utils/envmanager.hpp" #include "utils/directories.hpp" #include "utils/utils.hpp" @@ -12,15 +12,12 @@ namespace dropshell { -server_env::server_env(const std::string& server_name) : mValid(false), mServer_name(server_name) { +server_env_manager::server_env_manager(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; return; - } // Construct the full path to server.env - std::string env_path = get_local_server_env_path(server_name); + std::string env_path = localfile::server_env(server_name); // Check if file exists if (!std::filesystem::exists(env_path)) { @@ -54,7 +51,7 @@ server_env::server_env(const std::string& server_name) : mValid(false), mServer_ } } -std::string server_env::get_variable(const std::string& name) const { +std::string server_env_manager::get_variable(const std::string& name) const { if (!m_env_manager) { return ""; } @@ -62,17 +59,17 @@ std::string server_env::get_variable(const std::string& name) const { } // Helper method implementations -std::string server_env::construct_ssh_cmd() const { +std::string server_env_manager::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, std::vector args, bool silent) const +std::string server_env_manager::construct_standard_command_run_cmd(const std::string &service_name, const std::string &command, std::vector args, bool silent) 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 remote_service_template_path = remotepath::service_template(mServer_name,service_name); + std::string remote_service_config_path = remotepath::service_config(mServer_name,service_name); std::string script_path = remote_service_template_path + "/" + command + ".sh"; @@ -89,19 +86,19 @@ std::string server_env::construct_standard_command_run_cmd(const std::string &se return run_cmd; } -void server_env::get_all_service_env_vars(const std::string &service_name, std::map & all_env_vars) const +void server_env_manager::get_all_service_env_vars(const std::string &service_name, std::map & all_env_vars) const { all_env_vars.clear(); // add in some handy variables. - all_env_vars["CONFIG_PATH"] = get_remote_service_config_path(mServer_name,service_name); + all_env_vars["CONFIG_PATH"] = remotepath::service_config(mServer_name,service_name); all_env_vars["SERVER"] = mServer_name; all_env_vars["SERVICE"] = service_name; { // load service.env from the service on this machine. std::map env_vars; - envmanager env_manager(get_local_service_env_path(mServer_name,service_name)); + envmanager env_manager(localfile::service_env(mServer_name,service_name)); env_manager.load(); env_manager.get_all_variables(env_vars); all_env_vars.merge(env_vars); @@ -123,18 +120,18 @@ void server_env::get_all_service_env_vars(const std::string &service_name, std:: } -bool server_env::check_remote_dir_exists(const std::string &dir_path) const +bool server_env_manager::check_remote_dir_exists(const std::string &dir_path) const { sCommand scommand("test -d " + quote(dir_path)); return execute_ssh_command(scommand); } -bool server_env::check_remote_file_exists(const std::string& file_path) const { +bool server_env_manager::check_remote_file_exists(const std::string& file_path) const { sCommand scommand("test -f " + quote(file_path)); return execute_ssh_command(scommand); } -bool server_env::check_remote_items_exist(const std::vector &file_paths) const +bool server_env_manager::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; @@ -154,34 +151,34 @@ bool server_env::check_remote_items_exist(const std::vector &file_p return true; } -bool server_env::execute_ssh_command(const sCommand& command) const { +bool server_env_manager::execute_ssh_command(const sCommand& command) const { std::string full_cmd = construct_ssh_cmd() + " " + quote(command.construct_safecmd()); return execute_local_command(full_cmd); } -bool server_env::execute_ssh_command_and_capture_output(const sCommand& command, std::string &output) const +bool server_env_manager::execute_ssh_command_and_capture_output(const sCommand& command, std::string &output) const { std::string full_cmd = construct_ssh_cmd() + " " + quote(command.construct_safecmd()); return execute_local_command_and_capture_output(full_cmd, output); } -bool server_env::run_remote_template_command(const std::string &service_name, const std::string &command, std::vector args, bool silent) const +bool server_env_manager::run_remote_template_command(const std::string &service_name, const std::string &command, std::vector args, bool silent) const { std::string full_cmd = construct_standard_command_run_cmd(service_name, command, args, silent); return execute_ssh_command(full_cmd); } -bool server_env::run_remote_template_command_and_capture_output(const std::string &service_name, const std::string &command, std::vector args, std::string &output, bool silent) const +bool server_env_manager::run_remote_template_command_and_capture_output(const std::string &service_name, const std::string &command, std::vector args, std::string &output, bool silent) const { std::string full_cmd = construct_standard_command_run_cmd(service_name, command, args, silent); return execute_ssh_command_and_capture_output(full_cmd, output); } -bool server_env::execute_local_command(const sCommand& command) { +bool server_env_manager::execute_local_command(const sCommand& command) { return (system(command.construct_safecmd().c_str()) == 0); } -bool server_env::execute_local_command_and_capture_output(const sCommand& command, std::string &output) +bool server_env_manager::execute_local_command_and_capture_output(const sCommand& command, std::string &output) { std::string full_cmd = command.construct_safecmd() + " 2>&1"; FILE *pipe = popen(full_cmd.c_str(), "r"); diff --git a/src/server_env.hpp b/src/server_env_manager.hpp similarity index 96% rename from src/server_env.hpp rename to src/server_env_manager.hpp index 18177fd..a0a3a97 100644 --- a/src/server_env.hpp +++ b/src/server_env_manager.hpp @@ -11,6 +11,7 @@ #include "utils/envmanager.hpp" namespace dropshell { +// class to hold a command to run on the remote server. class sCommand { public: sCommand(std::string directory_to_run_in, std::string command_to_run, const std::map & env_vars) : @@ -41,9 +42,9 @@ class sCommand { // SSH_PORT // the following replacements are made in the values: // ${USER} -> the username of the user running dropshell -class server_env { +class server_env_manager { public: - server_env(const std::string& server_name); + server_env_manager(const std::string& server_name); std::string get_variable(const std::string& name) const; // trivial getters. diff --git a/src/servers.cpp b/src/servers.cpp index 0991680..f690ea5 100644 --- a/src/servers.cpp +++ b/src/servers.cpp @@ -1,5 +1,5 @@ #include "servers.hpp" -#include "server_env.hpp" +#include "server_env_manager.hpp" #include "service_runner.hpp" #include "utils/tableprint.hpp" #include "utils/envmanager.hpp" @@ -18,19 +18,19 @@ namespace dropshell { std::vector get_configured_servers() { std::vector servers; - std::vector local_config_directories = get_global_config()->get_local_config_directories(); + std::vector local_config_directories = gConfig().get_local_config_directories(); if (local_config_directories.empty()) return servers; for (int i = 0; i < local_config_directories.size(); i++) { - std::string servers_dir = get_local_config_servers_path(i); + std::string servers_dir = localpath::config_servers(i); if (!servers_dir.empty() && std::filesystem::exists(servers_dir)) { for (const auto& entry : std::filesystem::directory_iterator(servers_dir)) { if (std::filesystem::is_directory(entry)) { std::string server_name = entry.path().filename().string(); - server_env env(server_name); + server_env_manager env(server_name); if (!env.is_valid()) { std::cerr << "Error: Invalid server environment file: " << entry.path().string() << std::endl; continue; @@ -75,7 +75,7 @@ void list_servers() { } void show_server_details(const std::string& server_name) { - server_env env(server_name); + server_env_manager env(server_name); if (!env.is_valid()) { std::cerr << "Error: Invalid server environment file: " << server_name << std::endl; return; @@ -146,7 +146,7 @@ void show_server_details(const std::string& server_name) { void create_server(const std::string &server_name) { // 1. check if server name already exists - std::string server_existing_dir = get_local_server_path(server_name); + std::string server_existing_dir = localpath::server(server_name); if (!server_existing_dir.empty()) { std::cerr << "Error: Server name already exists: " << server_name << std::endl; std::cerr << "Current server path: " << server_existing_dir << std::endl; @@ -154,7 +154,7 @@ void create_server(const std::string &server_name) } // 2. create a new directory in the user config directory - std::string config_servers_dir = get_local_config_servers_path(0); + std::string config_servers_dir = localpath::config_servers(); std::string server_dir = config_servers_dir + "/" + server_name; std::filesystem::create_directory(server_dir); diff --git a/src/service_runner.hpp b/src/service_runner.hpp index efb6a7d..8dfd0d0 100644 --- a/src/service_runner.hpp +++ b/src/service_runner.hpp @@ -9,7 +9,7 @@ #include #include #include -#include "server_env.hpp" +#include "server_env_manager.hpp" #include "services.hpp" #include "utils/utils.hpp" #include "utils/assert.hpp" @@ -93,7 +93,7 @@ class service_runner { private: std::string m_server_name; - server_env m_server_env; + server_env_manager m_server_env; ServiceInfo m_service_info; bool mValid; diff --git a/src/utils/directories.cpp b/src/utils/directories.cpp index ac6cce5..ea37d88 100644 --- a/src/utils/directories.cpp +++ b/src/utils/directories.cpp @@ -1,6 +1,6 @@ #include "directories.hpp" #include "config.hpp" -#include "server_env.hpp" +#include "server_env_manager.hpp" #include #include #include @@ -10,135 +10,88 @@ namespace fs = std::filesystem; namespace dropshell { - -std::string get_local_dropshell_config_parent_path() -{ +namespace localfile { + std::string dropshell_conf() { // Try ~/.config/dropshell/dropshell.conf const char* home = std::getenv("HOME"); if (home) { - fs::path user_path = fs::path(home) / ".config" / "dropshell"; + fs::path user_path = fs::path(home) / ".config" / "dropshell" / "dropshell.conf"; return user_path.string(); } std::cerr << "Warning: Couldn't determine user directory" << std::endl; return std::string(); -} - -std::string get_local_dropshell_config_file() -{ - std::string parent_path = get_local_dropshell_config_parent_path(); - if (parent_path.empty()) - return std::string(); - return parent_path + "/dropshell.conf"; -} - -std::string get_local_system_templates_path() -{ - return "/opt/dropshell/templates"; -} - -std::string get_local_backup_path() -{ - config *cfg = get_global_config(); - if (!cfg) - return std::string(); - return cfg->get_local_backup_path(); -} - -int getNumConfigDirectories() -{ - config *cfg = get_global_config(); - std::vector local_config_directories = cfg->get_local_config_directories(); - return local_config_directories.size(); -} - -std::string get_primary_local_config_path() -{ - return get_local_config_path(0); -} - -std::string get_local_config_path(int index) -{ - config *cfg = get_global_config(); - if (!cfg) - return std::string(); - - std::vector local_config_directories = cfg->get_local_config_directories(); - if (index < 0 || index >= local_config_directories.size()) - return std::string(); - return local_config_directories[index]; -} - -std::string get_local_config_templates_path(int index) -{ - std::string config_path = get_local_config_path(index); - if (config_path.empty()) - return std::string(); - return config_path + "/templates"; -} - -std::string get_local_config_servers_path(int index) -{ - std::string config_path = get_local_config_path(index); - if (config_path.empty()) - return std::string(); - return config_path + "/servers"; -} - -std::string get_local_server_path(const std::string &server_name) -{ - config *cfg = get_global_config(); - std::vector local_config_directories = cfg->get_local_config_directories(); - for (auto &dir : local_config_directories) { - std::string server_path = dir + "/servers/" + server_name; - if (fs::exists(server_path)) { - return server_path; - } } - return std::string(); -} -std::string get_local_server_env_path(const std::string &server_name) -{ - if (server_name.empty()) - return std::string(); - std::string serverpath = get_local_server_path(server_name); - if (serverpath.empty()) - return std::string(); - return (fs::path(serverpath) / "server.env").string(); -} + std::string server_env(const std::string &server_name) { + if (server_name.empty()) + return std::string(); + std::string serverpath = localpath::server(server_name); + if (serverpath.empty()) + return std::string(); + return (fs::path(serverpath) / "server.env").string(); + } -std::string get_local_service_path(const std::string &server_name, const std::string &service_name) -{ - if (server_name.empty() || service_name.empty()) - return std::string(); + std::string service_env(const std::string &server_name, const std::string &service_name) { + if (server_name.empty() || service_name.empty()) + return std::string(); + std::string servicepath = localpath::service(server_name, service_name); + if (servicepath.empty()) + return std::string(); + return (fs::path(servicepath) / "service.env").string(); + } - std::string serverpath = get_local_server_path(server_name); - if (serverpath.empty()) - return std::string(); - return (fs::path(serverpath) / service_name).string(); -} + std::string service_hash(const std::string &server_name, const std::string &service_name) { + std::string config_path = localpath::config(); + if (server_name.empty() || service_name.empty() || config_path.empty()) + return std::string(); + return (fs::path(config_path) / ".remote_versions" / server_name / (service_name + ".hash.env")).string(); + } -std::string get_local_service_env_path(const std::string &server_name, const std::string &service_name) -{ - if (server_name.empty() || service_name.empty()) - return std::string(); - std::string servicepath = get_local_service_path(server_name, service_name); - if (servicepath.empty()) - return std::string(); - return (fs::path(servicepath) / "service.env").string(); -} +} // namespace localfile -std::string get_local_service_hash_path(const std::string &server_name, const std::string &service_name) -{ - if (server_name.empty() || service_name.empty()) - return std::string(); - std::string config_path = get_primary_local_config_path(); - if (config_path.empty()) - return std::string(); +// ------------------------------------------------------------------------------------------ + +namespace localpath { + // /opt/dropshell/templates + std::string system_templates() { + return "/opt/dropshell/templates"; + } + + // configured by user - defaults to first config_path/backups. + std::string backups_path() { + return gConfig().get_local_backup_path(); + } + + int num_config_directories() { + return gConfig().get_local_config_directories().size(); + } + + std::string config(int index) { + return (num_config_directories()>index) ? gConfig().get_local_config_directories()[index] : ""; + } + + std::string config_templates(int index) { + return (num_config_directories()>index) ? (gConfig().get_local_config_directories()[index]+"/templates") : ""; + } + + std::string config_servers(int index) { + return (num_config_directories()>index) ? (gConfig().get_local_config_directories()[index]+"/servers") : ""; + } + + std::string server(const std::string &server_name) { + for (auto &dir : gConfig().get_local_config_directories()) + if (fs::exists(dir + "/servers/" + server_name)) + return dir + "/servers/" + server_name; + return ""; + } + + std::string service(const std::string &server_name, const std::string &service_name) { + std::string serverpath = localpath::server(server_name); + return (serverpath.empty() ? "" : (serverpath+"/"+service_name)); + } +} // namespace localpath - return (fs::path(config_path) / ".remote_versions" / server_name / (service_name + ".hash.env")).string(); -} // ------------------------------------------------------------------------------------------ @@ -152,74 +105,53 @@ std::string get_local_service_hash_path(const std::string &server_name, const st // |-- (script files) // |-- backups - std::string get_remote_DROPSHELL_path(const std::string &server_name) - { - if (server_name.empty()) - return std::string(); - server_env env(server_name); - if (!env.is_valid()) - return std::string(); - return env.get_DROPSHELL_DIR(); +namespace remotepath { + std::string DROPSHELL_DIR(const std::string &server_name) + { + return server_env_manager(server_name).get_DROPSHELL_DIR(); } - std::string get_remote_services_path(const std::string &server_name) + std::string services(const std::string &server_name) { - if (server_name.empty()) - return std::string(); - std::string dropshell_path = get_remote_DROPSHELL_path(server_name); - if (dropshell_path.empty()) - return std::string(); - return (fs::path(dropshell_path) / "services").string(); + std::string dsp = DROPSHELL_DIR(server_name); + return (dsp.empty() ? "" : (dsp + "/services")); } - std::string get_remote_service_path(const std::string &server_name, const std::string &service_name) + std::string service(const std::string &server_name, const std::string &service_name) { - if (server_name.empty() || service_name.empty()) - return std::string(); - std::string services_path = get_remote_services_path(server_name); - if (services_path.empty()) - return std::string(); - return (fs::path(services_path) / service_name).string(); + std::string services_path = services(server_name); + return (services_path.empty() ? "" : (services_path + "/" + service_name)); } - std::string get_remote_service_config_path(const std::string &server_name, const std::string &service_name) + std::string service_config(const std::string &server_name, const std::string &service_name) { - if (server_name.empty() || service_name.empty()) - return std::string(); - std::string service_path = get_remote_service_path(server_name, service_name); - if (service_path.empty()) - return std::string(); - return (fs::path(service_path) / "config").string(); + std::string service_path = service(server_name, service_name); + return (service_path.empty() ? "" : (service_path + "/config")); } - std::string get_remote_service_template_path(const std::string &server_name, const std::string &service_name) + std::string service_template(const std::string &server_name, const std::string &service_name) { - if (server_name.empty() || service_name.empty()) - return std::string(); - std::string service_path = get_remote_service_path(server_name, service_name); - if (service_path.empty()) - return std::string(); - return (fs::path(service_path) / "template").string(); + std::string service_path = service(server_name, service_name); + return (service_path.empty() ? "" : (service_path + "/template")); } - std::string get_remote_backups_path(const std::string &server_name) + std::string backups(const std::string &server_name) { - if (server_name.empty()) - return std::string(); - std::string dropshell_path = get_remote_DROPSHELL_path(server_name); - if (dropshell_path.empty()) - return std::string(); - return (fs::path(dropshell_path) / "backups").string(); + std::string dsp = DROPSHELL_DIR(server_name); + return (dsp.empty() ? "" : (dsp + "/backups")); } - std::string get_remote_service_env_file(const std::string &server_name, const std::string &service_name) + std::string service_env(const std::string &server_name, const std::string &service_name) { - if (server_name.empty() || service_name.empty()) - return std::string(); - std::string service_path = get_remote_service_config_path(server_name, service_name); - if (service_path.empty()) - return std::string(); - return (fs::path(service_path) / "service.env").string(); + std::string service_path = service_config(server_name, service_name); + return (service_path.empty() ? "" : (service_path + "/service.env")); } +} // namespace remotepath +std::string get_parent(std::string path) +{ + if (path.empty()) + return std::string(); + return fs::path(path).parent_path().string(); +} } // namespace dropshell \ No newline at end of file diff --git a/src/utils/directories.hpp b/src/utils/directories.hpp index ec172c2..19ca053 100644 --- a/src/utils/directories.hpp +++ b/src/utils/directories.hpp @@ -5,13 +5,9 @@ namespace dropshell { - // local paths - return empty string on failure - std::string get_local_dropshell_config_parent_path(); - std::string get_local_dropshell_config_file(); - std::string get_local_system_templates_path(); - std::string get_local_backup_path(); - + // all functions return empty string on failure + //------------------------------------------------------------------------------------------------ // local user config directories // config_path // |-- servers @@ -30,23 +26,32 @@ namespace dropshell { // |-- .remote_versions // | |-- server_name // | |-- service_name.hash.env + namespace localfile { + // ~/.config/dropshell/dropshell.conf + std::string dropshell_conf(); + std::string server_env(const std::string &server_name); + std::string service_env(const std::string &server_name, const std::string &service_name); + std::string service_hash(const std::string &server_name, const std::string &service_name); + } // namespace localfile - std::string get_primary_local_config_path(); + namespace localpath { + // /opt/dropshell/templates + std::string system_templates(); + + // configured by user - defaults to first config_path/backups. + std::string backups_path(); + + int num_config_directories(); + std::string config(int index=0); + std::string config_templates(int index=0); + std::string config_servers(int index=0); + + std::string server(const std::string &server_name); + std::string service(const std::string &server_name, const std::string &service_name); + } // namespace local - int getNumConfigDirectories(); - std::string get_local_config_path(int index); - std::string get_local_config_templates_path(int index); - std::string get_local_config_servers_path(int index); - - std::string get_local_server_path(const std::string &server_name); - std::string get_local_server_env_path(const std::string &server_name); - - std::string get_local_service_path(const std::string &server_name, const std::string &service_name); - std::string get_local_service_env_path(const std::string &server_name, const std::string &service_name); - - std::string get_local_service_hash_path(const std::string &server_name, const std::string &service_name); - + //------------------------------------------------------------------------------------------------ // remote paths // DROPSHELL_DIR // |-- backups @@ -59,14 +64,23 @@ namespace dropshell { // |-- example // |-- service.env // |-- (other config files for specific server&service) - std::string get_remote_DROPSHELL_path(const std::string &server_name); - std::string get_remote_services_path(const std::string &server_name); - std::string get_remote_service_path(const std::string &server_name, const std::string &service_name); - std::string get_remote_service_config_path(const std::string &server_name, const std::string &service_name); - std::string get_remote_service_template_path(const std::string &server_name, const std::string &service_name); - std::string get_remote_backups_path(const std::string &server_name); + namespace remotefile { + std::string service_env(const std::string &server_name, const std::string &service_name); + } // namespace remotefile + + namespace remotepath { + std::string DROPSHELL_DIR(const std::string &server_name); + std::string services(const std::string &server_name); + std::string service(const std::string &server_name, const std::string &service_name); + std::string service_config(const std::string &server_name, const std::string &service_name); + std::string service_template(const std::string &server_name, const std::string &service_name); + std::string backups(const std::string &server_name); + } // namespace remotepath + + //------------------------------------------------------------------------------------------------ + // utility functions + std::string get_parent(std::string path); - std::string get_remote_service_env_file(const std::string &server_name, const std::string &service_name); } // namespace dropshell #endif