diff --git a/source/src/commands/backupdata.cpp b/source/src/commands/backupdata.cpp index 189d36d..e35aeda 100644 --- a/source/src/commands/backupdata.cpp +++ b/source/src/commands/backupdata.cpp @@ -102,7 +102,7 @@ namespace dropshell } // Create backups directory locally if it doesn't exist - std::string local_backups_dir = gConfig().get_local_backup_path(); + std::string local_backups_dir = localpath::backups(); if (local_backups_dir.empty()) { error << "Error: Local backups directory not found" << std::endl; diff --git a/source/src/commands/install.cpp b/source/src/commands/install.cpp index c9fc15e..334b1cb 100644 --- a/source/src/commands/install.cpp +++ b/source/src/commands/install.cpp @@ -238,20 +238,7 @@ namespace dropshell { maketitle("Installing dropshell agent on this computer..."); - std::vector paths = { - gConfig().get_local_template_cache_path(), - gConfig().get_local_backup_path(), - gConfig().get_local_tempfiles_path(), - localpath::agent()}; - for (auto &p : gConfig().get_local_server_definition_paths()) - paths.push_back(p); - - for (auto &p : paths) - if (!std::filesystem::exists(p)) - { - info << "Creating directory: " << p << std::endl; - std::filesystem::create_directories(p); - } + localpath::create_directories(); // create the agent-local directory. recreate_agent_local::recreate_tree(localpath::agent()); diff --git a/source/src/commands/restoredata.cpp b/source/src/commands/restoredata.cpp index 8a1c7d3..2e880b6 100644 --- a/source/src/commands/restoredata.cpp +++ b/source/src/commands/restoredata.cpp @@ -57,7 +57,7 @@ namespace dropshell std::vector get_backup_files(const std::string &server, const std::string &match_service = "", const std::string &match_template_name = "") { - std::string local_backups_dir = gConfig().get_local_backup_path(); + std::string local_backups_dir = localpath::backups(); if (local_backups_dir.empty() || !std::filesystem::exists(local_backups_dir)) { error << "Error: Local backups directory not found: " << local_backups_dir << std::endl; @@ -137,7 +137,7 @@ namespace dropshell debug << " Server: " << server << std::endl; debug << " Service: " << service << std::endl; - std::string local_backups_dir = gConfig().get_local_backup_path(); + std::string local_backups_dir = localpath::backups(); if (local_backups_dir.empty() || !std::filesystem::exists(local_backups_dir)) { error << "Error: Local backups directory not found: " << local_backups_dir << std::endl; diff --git a/source/src/config.cpp b/source/src/config.cpp index 3612b42..aaf8bc5 100644 --- a/source/src/config.cpp +++ b/source/src/config.cpp @@ -46,6 +46,15 @@ bool config::load_config() { // load json config file. return true; } +void _append(std::vector & a, const std::vector & b) { + if (b.empty()) + return; + if (a.empty()) + a = b; + else + a.insert(std::end(a), std::begin(b), std::end(b)); +} + bool config::save_config(bool create_aux_directories) { std::string config_path = localfile::dropshell_json(); @@ -61,37 +70,27 @@ bool config::save_config(bool create_aux_directories) if (!mIsConfigSet) { std::string homedir = localpath::current_user_home(); - std::string dropshell_base = homedir + "/.dropshell"; - mConfig["tempfiles"] = dropshell_base + "/tmp"; - mConfig["backups"] = dropshell_base + "/backups"; + std::string dropshell_base = homedir + "/.local/dropshell_files"; - mConfig["template_cache"] = dropshell_base + "/template_cache"; - mConfig["template_registry_URLs"] = { - "https://templates.dropshell.app" + mConfig["server_definition_paths"] = { + dropshell_base + "/servers" }; mConfig["template_local_paths"] = { dropshell_base + "/local_templates" }; - - mConfig["server_definition_paths"] = { - dropshell_base + "/servers" - }; - mConfig["template_upload_registry_url"] = "https://templates.dropshell.app"; - mConfig["template_upload_registry_token"] = "SECRETTOKEN"; + mConfig["template_registry_URLs"] = { + "https://templates.dropshell.app" + }; + mConfig["template_upload_token"] = "SECRETTOKEN"; } config_file << mConfig.dump(4); config_file.close(); if (create_aux_directories) { - std::vector paths = { - get_local_template_cache_path(), - get_local_backup_path(), - get_local_tempfiles_path() - }; - for (auto & p : get_local_server_definition_paths()) - paths.push_back(p); - + std::vector paths; + _append(paths, get_local_template_paths()); + _append(paths, get_local_server_definition_paths()); for (auto & p : paths) if (!std::filesystem::exists(p)) { @@ -99,6 +98,11 @@ bool config::save_config(bool create_aux_directories) std::filesystem::create_directories(p); } } + + debug << "Config paths: " << std::endl; + for (auto [key,value] : mConfig.items()) { + debug << " " << key << ": " << value << std::endl; + } return true; } @@ -113,28 +117,17 @@ bool config::is_agent_installed() return std::filesystem::exists(localpath::agent() + "/bb64"); } -std::string config::get_local_tempfiles_path() { - return mConfig["tempfiles"]; -} - -std::string config::get_local_backup_path() { - return mConfig["backups"]; -} - -std::string config::get_local_template_cache_path() { - return mConfig["template_cache"]; -} - std::vector config::get_template_registry_urls() { nlohmann::json template_registry_urls = mConfig["template_registry_URLs"]; std::vector urls; for (auto &url : template_registry_urls) { - urls.push_back(url); + if (url.is_string() && !url.empty()) + urls.push_back(url); } return urls; } -std::vector config::get_template_local_paths() +std::vector config::get_local_template_paths() { nlohmann::json template_local_paths = mConfig["template_local_paths"]; std::vector paths; @@ -147,23 +140,40 @@ std::vector config::get_template_local_paths() std::vector config::get_local_server_definition_paths() { nlohmann::json server_definition_paths = mConfig["server_definition_paths"]; - std::vector paths; for (auto &path : server_definition_paths) { if (path.is_string() && !path.empty()) paths.push_back(path); - else - warning << "Invalid server definition path: " << path << std::endl; } return paths; } -std::string config::get_template_upload_registry_url() { - return mConfig["template_upload_registry_url"]; +std::string config::get_server_create_path() +{ + std::vector paths = get_local_server_definition_paths(); + if (paths.empty()) + return ""; + return paths[0]; } -std::string config::get_template_upload_registry_token() { - return mConfig["template_upload_registry_token"]; +std::string config::get_template_create_path() +{ + std::vector paths = get_local_template_paths(); + if (paths.empty()) + return ""; + return paths[0]; +} + +std::string config::get_template_upload_url() +{ + std::vector urls = get_template_registry_urls(); + if (urls.empty()) + return ""; + return urls[0]; +} + +std::string config::get_template_upload_token() { + return mConfig["template_upload_token"]; } } // namespace dropshell \ No newline at end of file diff --git a/source/src/config.hpp b/source/src/config.hpp index 3da4d03..7081f22 100644 --- a/source/src/config.hpp +++ b/source/src/config.hpp @@ -17,15 +17,14 @@ class config { bool is_config_set() const; static bool is_agent_installed(); - std::string get_local_tempfiles_path(); - std::string get_local_backup_path(); - std::string get_local_template_cache_path(); std::vector get_template_registry_urls(); - std::vector get_template_local_paths(); + std::vector get_local_template_paths(); std::vector get_local_server_definition_paths(); - std::string get_template_upload_registry_url(); - std::string get_template_upload_registry_token(); + std::string get_server_create_path(); + std::string get_template_create_path(); + std::string get_template_upload_url(); + std::string get_template_upload_token(); private: nlohmann::json mConfig; diff --git a/source/src/service_runner.cpp b/source/src/service_runner.cpp index 0d7f1fa..16050ad 100644 --- a/source/src/service_runner.cpp +++ b/source/src/service_runner.cpp @@ -1,529 +1,529 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "utils/assert.hpp" +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include "utils/assert.hpp" -#include "config.hpp" -#include "server_env_manager.hpp" -#include "templates.hpp" -#include "services.hpp" -#include "utils/directories.hpp" -#include "utils/utils.hpp" -#include "command_registry.hpp" -#include "shared_commands.hpp" +// #include "config.hpp" +// #include "server_env_manager.hpp" +// #include "templates.hpp" +// #include "services.hpp" +// #include "utils/directories.hpp" +// #include "utils/utils.hpp" +// #include "command_registry.hpp" +// #include "shared_commands.hpp" -namespace dropshell { +// namespace dropshell { -class service_runner { - public: - service_runner(const std::string& server_name, const std::string& service_name); - bool isValid() const { return mValid; } +// class service_runner { +// public: +// service_runner(const std::string& server_name, const std::string& service_name); +// bool isValid() const { return mValid; } - // 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 - // then run the command, passing the {service_name}.env file as an argument - // do a lot of checks, such as: - // checking that we can ssh to the server. - // checking whether the service directory exists on the server. - // checking that the command exists in the service directory. - // checking that the command is a valid .sh file. - // checking that the {service_name}.env file exists in the service directory. - bool run_command(const std::string& command, std::vector additional_args={}, std::map env_vars={}); +// // 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 +// // then run the command, passing the {service_name}.env file as an argument +// // do a lot of checks, such as: +// // checking that we can ssh to the server. +// // checking whether the service directory exists on the server. +// // checking that the command exists in the service directory. +// // checking that the command is a valid .sh file. +// // checking that the {service_name}.env file exists in the service directory. +// bool run_command(const std::string& command, std::vector additional_args={}, std::map env_vars={}); - // check health of service. Silent. - // 1. run status.sh on the server - // 2. return the output of the status.sh script +// // check health of service. Silent. +// // 1. run status.sh on the server +// // 2. return the output of the status.sh script - //HealthStatus is_healthy(); +// //HealthStatus is_healthy(); - // std::string healthtick(); - // std::string healthmark(); +// // std::string healthtick(); +// // std::string healthmark(); - public: - // backup and restore - bool backup(bool silent=false); - bool restore(std::string backup_file, bool silent=false); +// public: +// // backup and restore +// bool backup(bool silent=false); +// bool restore(std::string backup_file, bool silent=false); - // nuke the service - bool nuke(bool silent=false); // nukes all data for this service on the remote server - bool fullnuke(); // nuke all data for this service on the remote server, and then nukes all the local service definitionfiles +// // nuke the service +// bool nuke(bool silent=false); // nukes all data for this service on the remote server +// bool fullnuke(); // nuke all data for this service on the remote server, and then nukes all the local service definitionfiles - // launch an interactive ssh session on a server or service - // replaces the current dropshell process with the ssh process - bool interactive_ssh_service(); +// // launch an interactive ssh session on a server or service +// // replaces the current dropshell process with the ssh process +// bool interactive_ssh_service(); - bool scp_file_to_remote(const std::string& local_path, const std::string& remote_path, bool silent=false); - bool scp_file_from_remote(const std::string& remote_path, const std::string& local_path, bool silent=false); - public: - // utility functions - static std::string get_latest_backup_file(const std::string& server, const std::string& service); - static bool interactive_ssh(const std::string & server_name, const std::string & command); - // static std::map get_all_services_status(std::string server_name); +// bool scp_file_to_remote(const std::string& local_path, const std::string& remote_path, bool silent=false); +// bool scp_file_from_remote(const std::string& remote_path, const std::string& local_path, bool silent=false); +// public: +// // utility functions +// static std::string get_latest_backup_file(const std::string& server, const std::string& service); +// static bool interactive_ssh(const std::string & server_name, const std::string & command); +// // static std::map get_all_services_status(std::string server_name); - private: - std::string mServer; - server_env_manager mServerEnv; - LocalServiceInfo mServiceInfo; - std::string mService; - bool mValid; +// private: +// std::string mServer; +// server_env_manager mServerEnv; +// LocalServiceInfo mServiceInfo; +// std::string mService; +// bool mValid; - // Helper methods - public: -}; +// // Helper methods +// public: +// }; -} // namespace dropshell +// } // namespace dropshell -namespace fs = std::filesystem; +// namespace fs = std::filesystem; -namespace dropshell { +// namespace dropshell { -service_runner::service_runner(const std::string& server_name, const std::string& service_name) : - mServerEnv(server_name), mServer(server_name), mService(service_name), mValid(false) -{ - if (server_name.empty() || service_name.empty()) - return; +// service_runner::service_runner(const std::string& server_name, const std::string& service_name) : +// mServerEnv(server_name), mServer(server_name), mService(service_name), mValid(false) +// { +// if (server_name.empty() || service_name.empty()) +// return; - // Initialize server environment - if (!mServerEnv.is_valid()) - return; +// // Initialize server environment +// if (!mServerEnv.is_valid()) +// return; - mServiceInfo = get_service_info(server_name, service_name); - if (mServiceInfo.service_name.empty()) - return; +// mServiceInfo = get_service_info(server_name, service_name); +// if (mServiceInfo.service_name.empty()) +// return; - mService = mServiceInfo.service_name; +// mService = mServiceInfo.service_name; - mValid = !mServiceInfo.local_template_path.empty(); -} +// mValid = !mServiceInfo.local_template_path.empty(); +// } -bool service_runner::nuke(bool silent) -{ - maketitle("Nuking " + mService + " (" + mServiceInfo.template_name + ") on " + mServer); +// bool service_runner::nuke(bool silent) +// { +// maketitle("Nuking " + mService + " (" + mServiceInfo.template_name + ") on " + mServer); - if (!mServerEnv.is_valid()) return false; // should never hit this. +// if (!mServerEnv.is_valid()) return false; // should never hit this. - std::string remote_service_path = remotepath::service(mServer, mService); +// std::string remote_service_path = remotepath::service(mServer, mService); - info << "Service " << mService << " successfully nuked from " << mServer << std::endl; +// info << "Service " << mService << " successfully nuked from " << mServer << std::endl; - if (!silent) { - info << "There's nothing left on the remote server." << std::endl; - info << "You can remove the local files with:" << std::endl; - info << " rm -rf " << localpath::service(mServer,mService) << std::endl; - } - return true; -} +// if (!silent) { +// info << "There's nothing left on the remote server." << std::endl; +// info << "You can remove the local files with:" << std::endl; +// info << " rm -rf " << localpath::service(mServer,mService) << std::endl; +// } +// return true; +// } -bool service_runner::fullnuke() -{ - if (!nuke(true)) - { - warning << "Nuke script failed, aborting." << std::endl; - return false; - } +// bool service_runner::fullnuke() +// { +// if (!nuke(true)) +// { +// warning << "Nuke script failed, aborting." << std::endl; +// return false; +// } - std::string local_service_path = mServiceInfo.local_service_path; - if (local_service_path.empty() || !fs::exists(local_service_path)) { - error << "Service directory not found: " << local_service_path << std::endl; - return false; - } +// std::string local_service_path = mServiceInfo.local_service_path; +// if (local_service_path.empty() || !fs::exists(local_service_path)) { +// error << "Service directory not found: " << local_service_path << std::endl; +// return false; +// } - std::string rm_cmd = "rm -rf " + quote(local_service_path); - if (!execute_local_command("", rm_cmd, {}, nullptr, cMode::Silent)) { - error << "Failed to remove service directory" << std::endl; - return false; - } +// std::string rm_cmd = "rm -rf " + quote(local_service_path); +// if (!execute_local_command("", rm_cmd, {}, nullptr, cMode::Silent)) { +// error << "Failed to remove service directory" << std::endl; +// return false; +// } - return true; -} +// return true; +// } -// ------------------------------------------------------------------------------------------------ -// Run a command on the service. -// ------------------------------------------------------------------------------------------------ -bool service_runner::run_command(const std::string& command, std::vector additional_args, std::map env_vars) { - if (!mServerEnv.is_valid()) { - std::cerr << "Error: Server service not initialized" << std::endl; - return false; - } - template_info tinfo = gTemplateManager().get_template_info(mServiceInfo.template_name); - if (!tinfo.is_set()) { - std::cerr << "Error: Template '" << mServiceInfo.template_name << "' not found" << std::endl; - return false; - } +// // ------------------------------------------------------------------------------------------------ +// // Run a command on the service. +// // ------------------------------------------------------------------------------------------------ +// bool service_runner::run_command(const std::string& command, std::vector additional_args, std::map env_vars) { +// if (!mServerEnv.is_valid()) { +// std::cerr << "Error: Server service not initialized" << std::endl; +// return false; +// } +// template_info tinfo = gTemplateManager().get_template_info(mServiceInfo.template_name); +// if (!tinfo.is_set()) { +// std::cerr << "Error: Template '" << mServiceInfo.template_name << "' not found" << std::endl; +// return false; +// } - if (command == "fullnuke") - return fullnuke(); +// if (command == "fullnuke") +// return fullnuke(); - if (command == "nuke") - { - std::cout << "Nuking " << mService << " (" << mServiceInfo.template_name << ") on " << mServer << std::endl; - return nuke(); - } +// if (command == "nuke") +// { +// std::cout << "Nuking " << mService << " (" << mServiceInfo.template_name << ") on " << mServer << std::endl; +// return nuke(); +// } - if (!gTemplateManager().template_command_exists(mServiceInfo.template_name, command)) { - std::cout << "No command script for " << mServiceInfo.template_name << " : " << command << std::endl; - return true; // nothing to run. - } +// if (!gTemplateManager().template_command_exists(mServiceInfo.template_name, command)) { +// std::cout << "No command script for " << mServiceInfo.template_name << " : " << command << std::endl; +// return true; // nothing to run. +// } - // install doesn't require anything on the server yet. - // if (command == "install") - // return install_service(mServer, mService, false); +// // install doesn't require anything on the server yet. +// // if (command == "install") +// // return install_service(mServer, mService, false); - std::string script_path = remotepath::service_template(mServer, mService) + "/" + command + ".sh"; +// std::string script_path = remotepath::service_template(mServer, mService) + "/" + command + ".sh"; - // Check if service directory exists - if (!mServerEnv.check_remote_dir_exists(remotepath::service(mServer, mService))) { - std::cerr << "Error: Service is not installed: " << mService << std::endl; - return false; - } +// // Check if service directory exists +// if (!mServerEnv.check_remote_dir_exists(remotepath::service(mServer, mService))) { +// std::cerr << "Error: Service is not installed: " << mService << std::endl; +// return false; +// } - // Check if command script exists - if (!mServerEnv.check_remote_file_exists(script_path)) { - std::cerr << "Error: Remote command script not found: " << script_path << std::endl; - return false; - } +// // Check if command script exists +// if (!mServerEnv.check_remote_file_exists(script_path)) { +// std::cerr << "Error: Remote command script not found: " << script_path << std::endl; +// return false; +// } - // Check if env file exists - if (!mServerEnv.check_remote_file_exists(remotefile::service_env(mServer, mService))) { - std::cerr << "Error: Service config file not found: " << remotefile::service_env(mServer, mService) << std::endl; - return false; - } +// // Check if env file exists +// if (!mServerEnv.check_remote_file_exists(remotefile::service_env(mServer, mService))) { +// std::cerr << "Error: Service config file not found: " << remotefile::service_env(mServer, mService) << std::endl; +// return false; +// } - // if (command == "uninstall") - // return uninstall(); +// // if (command == "uninstall") +// // return uninstall(); - if (command == "ssh") { - interactive_ssh_service(); - return true; - } - if (command == "restore") { - if (additional_args.size() < 1) { - std::cerr << "Error: restore requires a backup file:" << std::endl; - std::cerr << "dropshell restore " << std::endl; - return false; - } - return restore(additional_args[0], false); - } - if (command == "backup") { - return backup(false); - } +// if (command == "ssh") { +// interactive_ssh_service(); +// return true; +// } +// if (command == "restore") { +// if (additional_args.size() < 1) { +// std::cerr << "Error: restore requires a backup file:" << std::endl; +// std::cerr << "dropshell restore " << std::endl; +// return false; +// } +// return restore(additional_args[0], false); +// } +// if (command == "backup") { +// return backup(false); +// } - // Run the generic command - std::vector args; // not passed through yet. - return mServerEnv.run_remote_template_command(mService, command, args, false, env_vars); -} +// // Run the generic command +// std::vector args; // not passed through yet. +// return mServerEnv.run_remote_template_command(mService, command, args, false, env_vars); +// } -bool service_runner::interactive_ssh(const std::string & server_name, const std::string & command) { - std::string serverpath = localpath::server(server_name); - if (serverpath.empty()) { - std::cerr << "Error: Server not found: " << server_name << std::endl; - return false; - } +// bool service_runner::interactive_ssh(const std::string & server_name, const std::string & command) { +// std::string serverpath = localpath::server(server_name); +// if (serverpath.empty()) { +// std::cerr << "Error: Server not found: " << server_name << std::endl; +// return false; +// } - server_env_manager env(server_name); - if (!env.is_valid()) { - std::cerr << "Error: Invalid server environment file: " << server_name << std::endl; - return false; - } - sCommand scommand("", "bash",{}); - return execute_ssh_command(env.get_SSH_INFO(), scommand, cMode::Interactive); -} +// server_env_manager env(server_name); +// if (!env.is_valid()) { +// std::cerr << "Error: Invalid server environment file: " << server_name << std::endl; +// return false; +// } +// sCommand scommand("", "bash",{}); +// return execute_ssh_command(env.get_SSH_INFO(), scommand, cMode::Interactive); +// } -bool service_runner::interactive_ssh_service() -{ - std::set used_commands = get_used_commands(mServer, mService); - if (used_commands.find("ssh") == used_commands.end()) { - std::cerr << "Error: "<< mService <<" does not support ssh" << std::endl; - return false; - } +// bool service_runner::interactive_ssh_service() +// { +// std::set used_commands = get_used_commands(mServer, mService); +// if (used_commands.find("ssh") == used_commands.end()) { +// std::cerr << "Error: "<< mService <<" does not support ssh" << std::endl; +// return false; +// } - std::vector args; // not passed through yet. - return mServerEnv.run_remote_template_command(mService, "ssh", args, false, {}); -} +// std::vector args; // not passed through yet. +// return mServerEnv.run_remote_template_command(mService, "ssh", args, false, {}); +// } -bool service_runner::scp_file_to_remote(const std::string &local_path, const std::string &remote_path, bool silent) -{ - std::string scp_cmd = "scp -P " + mServerEnv.get_SSH_PORT() + " " + quote(local_path) + " " + mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + quote(remote_path) + (silent ? " > /dev/null 2>&1" : ""); - return execute_local_command("", scp_cmd, {}, nullptr, (silent ? cMode::Silent : cMode::Defaults)); -} +// bool service_runner::scp_file_to_remote(const std::string &local_path, const std::string &remote_path, bool silent) +// { +// std::string scp_cmd = "scp -P " + mServerEnv.get_SSH_PORT() + " " + quote(local_path) + " " + mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + quote(remote_path) + (silent ? " > /dev/null 2>&1" : ""); +// return execute_local_command("", scp_cmd, {}, nullptr, (silent ? cMode::Silent : cMode::Defaults)); +// } -bool service_runner::scp_file_from_remote(const std::string &remote_path, const std::string &local_path, bool silent) -{ - std::string scp_cmd = "scp -P " + mServerEnv.get_SSH_PORT() + " " + mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + quote(remote_path) + " " + quote(local_path) + (silent ? " > /dev/null 2>&1" : ""); - return execute_local_command("", scp_cmd, {}, nullptr, (silent ? cMode::Silent : cMode::Defaults)); -} +// bool service_runner::scp_file_from_remote(const std::string &remote_path, const std::string &local_path, bool silent) +// { +// std::string scp_cmd = "scp -P " + mServerEnv.get_SSH_PORT() + " " + mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + quote(remote_path) + " " + quote(local_path) + (silent ? " > /dev/null 2>&1" : ""); +// return execute_local_command("", scp_cmd, {}, nullptr, (silent ? cMode::Silent : cMode::Defaults)); +// } -bool service_runner::restore(std::string backup_file, bool silent) -{ - if (backup_file.empty()) { - std::cerr << "Error: not enough arguments. dropshell restore " << std::endl; - return false; - } +// bool service_runner::restore(std::string backup_file, bool silent) +// { +// if (backup_file.empty()) { +// std::cerr << "Error: not enough arguments. dropshell restore " << std::endl; +// return false; +// } - std::string local_backups_dir = gConfig().get_local_backup_path(); +// std::string local_backups_dir = gConfig().get_local_backup_path(); - if (backup_file == "latest") { - // get the latest backup file from the server - backup_file = get_latest_backup_file(mServer, mService); - } +// if (backup_file == "latest") { +// // get the latest backup file from the server +// backup_file = get_latest_backup_file(mServer, mService); +// } - std::string local_backup_file_path = (std::filesystem::path(local_backups_dir) / backup_file).string(); +// std::string local_backup_file_path = (std::filesystem::path(local_backups_dir) / backup_file).string(); - if (! std::filesystem::exists(local_backup_file_path)) { - std::cerr << "Error: Backup file not found at " << local_backup_file_path << std::endl; - return false; - } +// if (! std::filesystem::exists(local_backup_file_path)) { +// std::cerr << "Error: Backup file not found at " << local_backup_file_path << std::endl; +// return false; +// } - // split the backup filename into parts based on the magic string - std::vector parts = dropshell::split(backup_file, "-_-"); - if (parts.size() != 4) { - std::cerr << "Error: Backup file format is incompatible, - in one of the names?" << std::endl; - return false; - } +// // split the backup filename into parts based on the magic string +// std::vector parts = dropshell::split(backup_file, "-_-"); +// if (parts.size() != 4) { +// std::cerr << "Error: Backup file format is incompatible, - in one of the names?" << std::endl; +// return false; +// } - std::string backup_server_name = parts[0]; - std::string backup_template_name = parts[1]; - std::string backup_service_name = parts[2]; - std::string backup_datetime = parts[3]; +// std::string backup_server_name = parts[0]; +// std::string backup_template_name = parts[1]; +// std::string backup_service_name = parts[2]; +// std::string backup_datetime = parts[3]; - if (backup_template_name != mServiceInfo.template_name) { - std::cerr << "Error: Backup template does not match service template. Can't restore." << std::endl; - return false; - } +// if (backup_template_name != mServiceInfo.template_name) { +// std::cerr << "Error: Backup template does not match service template. Can't restore." << std::endl; +// return false; +// } - std::string nicedate = std::string(backup_datetime).substr(0, 10); +// std::string nicedate = std::string(backup_datetime).substr(0, 10); - std::cout << "Restoring " << nicedate << " backup of " << backup_template_name << " taken from "< latest_datetime) { - latest_datetime = datetime; - latest_file = filename; - } - } - } +// for (const auto& entry : std::filesystem::directory_iterator(local_backups_dir)) { +// if (!entry.is_regular_file()) continue; +// std::string filename = entry.path().filename().string(); +// if (filename.rfind(prefix, 0) == 0) { // starts with prefix +// // Extract the datetime part +// size_t dt_start = prefix.size(); +// size_t dt_end = filename.find(".tgz", dt_start); +// if (dt_end == std::string::npos) continue; +// std::string datetime = filename.substr(dt_start, dt_end - dt_start); +// std::cout << "Found backup file: " << filename << " with datetime: " << datetime << std::endl; +// if (datetime > latest_datetime) { +// latest_datetime = datetime; +// latest_file = filename; +// } +// } +// } - if (latest_file.empty()) { - std::cerr << "Error: No backup files found for " << server << ", " << service << std::endl; - } +// if (latest_file.empty()) { +// std::cerr << "Error: No backup files found for " << server << ", " << service << std::endl; +// } - std::cout << "Latest backup file: " << latest_file << std::endl; - return latest_file; -} +// std::cout << "Latest backup file: " << latest_file << std::endl; +// return latest_file; +// } -} // namespace dropshell \ No newline at end of file +// } // namespace dropshell \ No newline at end of file diff --git a/source/src/services.cpp b/source/src/services.cpp index 0775d5b..b683ada 100644 --- a/source/src/services.cpp +++ b/source/src/services.cpp @@ -137,7 +137,7 @@ std::set list_backups(const std::string &server_name, const std::st return backups; } - std::string backups_dir = gConfig().get_local_backup_path(); + std::string backups_dir = localpath::backups(); if (backups_dir.empty()) return backups; diff --git a/source/src/templates.cpp b/source/src/templates.cpp index 002f1fa..4ffb122 100644 --- a/source/src/templates.cpp +++ b/source/src/templates.cpp @@ -185,7 +185,7 @@ return false; } - auto local_template_paths = gConfig().get_template_local_paths(); + auto local_template_paths = gConfig().get_local_template_paths(); if (local_template_paths.empty()) { std::cerr << "Error: No local template paths found" << std::endl; std::cerr << "Run 'dropshell edit' to add one to the DropShell config" << std::endl; @@ -252,7 +252,7 @@ ASSERT(mSources.empty(), "Template manager already loaded (sources are not empty)."); ASSERT(gConfig().is_config_set(), "Config not set."); ASSERT(!mLoaded, "Template manager already loaded."); - auto local_template_paths = gConfig().get_template_local_paths(); + auto local_template_paths = gConfig().get_local_template_paths(); if (local_template_paths.empty()) return; for (const auto& path : local_template_paths) diff --git a/source/src/utils/directories.cpp b/source/src/utils/directories.cpp index 3393ca8..593641c 100644 --- a/source/src/utils/directories.cpp +++ b/source/src/utils/directories.cpp @@ -62,7 +62,7 @@ namespace localpath { std::string remote_versions(const std::string &server_name, const std::string &service_name) { - std::string template_cache_path = gConfig().get_local_template_cache_path(); + std::string template_cache_path = localpath::template_cache(); return ((template_cache_path.empty() || service_name.empty()) ? "" : (template_cache_path+"/remote_versions/"+service_name+".json")); } @@ -84,6 +84,48 @@ namespace localpath { warning << "Couldn't determine user directory" << std::endl; return std::string(); } + + std::string dropshell_files() + { + return current_user_home() + "/.local/dropshell_files"; + return std::string(); + } + + std::string backups() + { + return dropshell_files() + "/backups"; + } + + std::string temp_files() + { + return dropshell_files() + "/temp_files"; + } + + std::string template_cache() + { + return dropshell_files() + "template_cache"; + } + + bool create_directories() + { + std::vector paths = { + dropshell_files(), + template_cache(), + backups(), + temp_files(), + agent()}; + for (auto &p : gConfig().get_local_server_definition_paths()) + paths.push_back(p); + + for (auto &p : paths) + if (!std::filesystem::exists(p)) + { + info << "Creating directory: " << p << std::endl; + std::filesystem::create_directories(p); + } + return false; + } + } // namespace localpath //------------------------------------------------------------------------------------------------ diff --git a/source/src/utils/directories.hpp b/source/src/utils/directories.hpp index 93b47f3..3bf4bbe 100644 --- a/source/src/utils/directories.hpp +++ b/source/src/utils/directories.hpp @@ -18,6 +18,23 @@ namespace dropshell { // |-- files_for_remote_agent // |-- (other agent files, including _allservicesstatus.sh) + // ~/.local/dropshell_files + // |-- backups + // |-- katie-_-squashkiwi-_-squashkiwi-test-_-2025-04-28_21-23-59.tgz + // |-- temp_files + // |-- template_cache + // |-- templates + // | |-- .json + // | |-- + // | |-- (...script files...) + // | |-- _default.env + // | |-- config + // | |-- service.env + // | |-- .template_info.env + // | |-- (...other service config files...) + // |-- remote_versions + // | |-- server_name-service_name.json + // server_definition_path // |-- // |-- server.json @@ -27,23 +44,7 @@ namespace dropshell { // |-- .template_info.env // |-- (...other config files for specific server&service...) - // backup path - // |-- katie-_-squashkiwi-_-squashkiwi-test-_-2025-04-28_21-23-59.tgz - - // temp files path - // template cache path - // |-- templates - // | |-- .json - // | |-- - // | |-- (...script files...) - // | |-- _default.env - // | |-- config - // | |-- service.env - // | |-- .template_info.env - // | |-- (...other service config files...) - // |-- remote_versions - // | |-- server_name-service_name.json namespace localfile { // ~/.config/dropshell/dropshell.json @@ -62,6 +63,14 @@ namespace dropshell { std::string agent(); std::string files_for_remote_agent(); std::string current_user_home(); + + std::string dropshell_files(); + std::string backups(); + std::string temp_files(); + std::string template_cache(); + + + bool create_directories(); } // namespace local