From 9d01554b13ed5f8b4b476e58b2c4ce3e2dc0e45d Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 5 May 2025 21:48:36 +1200 Subject: [PATCH] Add 'latest' hidden option to restore --- src/main.cpp | 6 ++--- src/service_runner.cpp | 52 +++++++++++++++++++++++++++++++++++++++--- src/service_runner.hpp | 21 ++++++++--------- 3 files changed, 62 insertions(+), 17 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b528dbc..b243c9b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -140,7 +140,7 @@ int main(int argc, char* argv[]) { gConfig().save_config(false); std::string config_file = localfile::dropshell_json(); - if (!edit_file(config_file) || !std::filesystem::exists(config_file)) + if (!service_runner::edit_file(config_file) || !std::filesystem::exists(config_file)) return die("Error: Failed to edit config file."); gConfig().load_config(); @@ -208,13 +208,13 @@ int main(int argc, char* argv[]) { if (cmd == "ssh" && argc < 4) { if (argc < 3) return die("Error: ssh requires a server name and optionally service name"); - interactive_ssh(argv[2], "bash"); + service_runner::interactive_ssh(argv[2], "bash"); return 0; } if (cmd == "edit" && argc < 4) { ASSERT_MSG(argc>=3, "Error: logic error!"); - edit_server(safearg(argc,argv,2)); + service_runner::edit_server(safearg(argc,argv,2)); return 0; } diff --git a/src/service_runner.cpp b/src/service_runner.cpp index 61668cb..f9f5bba 100644 --- a/src/service_runner.cpp +++ b/src/service_runner.cpp @@ -379,7 +379,7 @@ std::string service_runner::healthmark() return HealthStatus2String(status); } -void interactive_ssh(const std::string & server_name, const std::string & command) { +void 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; @@ -409,7 +409,7 @@ void interactive_ssh(const std::string & server_name, const std::string & comman exit(EXIT_FAILURE); } -void edit_server(const std::string &server_name) +void service_runner::edit_server(const std::string &server_name) { std::string serverpath = localpath::server(server_name); if (serverpath.empty()) { @@ -432,7 +432,7 @@ void edit_server(const std::string &server_name) std::cout << aftertext.str() << std::endl; } -bool edit_file(const std::string &file_path) +bool service_runner::edit_file(const std::string &file_path) { // make sure parent directory exists. std::string parent_dir = get_parent(file_path); @@ -698,5 +698,51 @@ std::string cRemoteTempFolder::path() const return mPath; } +// Helper function to get the latest backup file for a given server and service +std::string service_runner::get_latest_backup_file(const std::string& server, const std::string& service) { + std::string local_backups_dir = gConfig().get_local_backup_path(); + if (local_backups_dir.empty() || !std::filesystem::exists(local_backups_dir)) { + std::cerr << "Error: Local backups directory not found: " << local_backups_dir << std::endl; + return ""; + } + + // Get the template name for this service + LocalServiceInfo info = get_service_info(server, service); + if (info.template_name.empty()) { + std::cerr << "Error: Could not determine template name for service: " << service << std::endl; + return ""; + } + + // Build the expected prefix for backup files + std::string prefix = server + magic_string + info.template_name + magic_string + service + magic_string; + std::string latest_file; + std::string latest_datetime; + + std::cout << "Looking for backup files in " << local_backups_dir << std::endl; + + 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; + } + + std::cout << "Latest backup file: " << latest_file << std::endl; + return latest_file; +} } // namespace dropshell \ No newline at end of file diff --git a/src/service_runner.hpp b/src/service_runner.hpp index 81284a0..6923936 100644 --- a/src/service_runner.hpp +++ b/src/service_runner.hpp @@ -56,10 +56,6 @@ class service_runner { std::string healthtick(); std::string healthmark(); - // get the status of all services on the server - static std::map get_all_services_status(std::string server_name); - static std::string HealthStatus2String(HealthStatus status); - private: // install the service over ssh, using the credentials from server.env (via server_env.hpp), by: // 1. check if the server_name exists, and the service_name refers to a valid template @@ -91,6 +87,16 @@ class service_runner { // edit the service configuration file void edit_service_config(); + + public: + // utility functions + static std::string get_latest_backup_file(const std::string& server, const std::string& service); + static void interactive_ssh(const std::string & server_name, const std::string & command); + static void edit_server(const std::string & server_name); + static bool edit_file(const std::string & file_path); + static std::map get_all_services_status(std::string server_name); + static std::string HealthStatus2String(HealthStatus status); + private: std::string mServer; server_env_manager mServerEnv; @@ -112,13 +118,6 @@ class service_runner { const server_env_manager & mServerEnv; }; - - -// other utility routines (not specific to service_runner) -void interactive_ssh(const std::string & server_name, const std::string & command); -void edit_server(const std::string & server_name); -bool edit_file(const std::string & file_path); - } // namespace dropshell #endif // SERVICE_RUNNER_HPP