diff --git a/src/dropshell-completion.bash b/src/dropshell-completion.bash index 8adbed5..25ec1a8 100755 --- a/src/dropshell-completion.bash +++ b/src/dropshell-completion.bash @@ -42,6 +42,17 @@ _dropshell_completions() { local services=($(dropshell autocomplete_list_services "$server_name")) COMPREPLY=( $(compgen -W "${services[*]}" -- ${cur}) ) return 0 + elif [[ ${COMP_CWORD} -eq 4 ]]; then + if [[ ${root} == "restore" ]]; then + # Fourth argument is backup file name + local server_name="${COMP_WORDS[2]}" + local service_name="${COMP_WORDS[3]}" + local backup_files=($(dropshell autocomplete_list_backups "$server_name" "$service_name")) + COMPREPLY=( $(compgen -W "${backup_files[*]}" -- ${cur}) ) + return 0 + fi + COMPREPLY=() + return 0 fi ;; esac diff --git a/src/main.cpp b/src/main.cpp index 1c643e3..60303ca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,6 +12,7 @@ #include #include #include + namespace dropshell { void print_help() { @@ -163,6 +164,19 @@ int main(int argc, char* argv[]) { return 0; } + if (cmd == "autocomplete_list_backups") { + if (argc < 4) { + std::cerr << "Error: autocomplete_list_backups requires a server name and service name" << std::endl; + return 1; + } + if (cfg->is_config_set()) { + auto backups = dropshell::list_backups(argv[2], argv[3]); + for (const auto& backup : backups) + std::cout << backup << std::endl; + } + return 0; + } + // ------------------------------------------------------------ // from here we require the config file to be loaded. if (!cfg->is_config_set()) { diff --git a/src/service_runner.cpp b/src/service_runner.cpp index 4ed7fd0..c7008fc 100644 --- a/src/service_runner.cpp +++ b/src/service_runner.cpp @@ -557,6 +557,23 @@ void edit_file(const std::string &file_path, const std::string & aftertext) exit(EXIT_FAILURE); } +bool service_runner::restore(std::string backup_file) +{ + std::string command = "restore"; + std::string script_path = mRemote_service_template_path + "/" + command + ".sh"; + if (!template_command_exists(m_service_info.template_name, command)) { + std::cout << "No restore script for " << m_service_info.template_name << std::endl; + return true; // nothing to restore. + } + + /// TOODOOOOOO!!!!!! + std::cout << "Restore not implemented yet" << std::endl; + return true; + + // std::string run_cmd = construct_standard_command_run_cmd("restore"); + // return execute_ssh_command(run_cmd, "Restore script failed"); +} + void service_runner::interactive_ssh_service() { std::set used_commands = get_used_commands(m_server_name, m_service_info.service_name); diff --git a/src/service_runner.hpp b/src/service_runner.hpp index ddfeb62..cbb2365 100644 --- a/src/service_runner.hpp +++ b/src/service_runner.hpp @@ -80,6 +80,11 @@ class service_runner { // 4. copy it to the local user_dir/backups folder bool backup(); + // restore the service over ssh, using the credentials from server.env (via server_env.hpp) + // 1. copy the backup file to the server's DROPSHELL_DIR/backups folder + // 2. run the restore.sh script on the server, passing the {service_name}.env file as an argument + bool restore(std::string backup_file); + // launch an interactive ssh session on a server or service // replaces the current dropshell process with the ssh process void interactive_ssh_service(); diff --git a/src/services.cpp b/src/services.cpp index 4e02ace..a192220 100644 --- a/src/services.cpp +++ b/src/services.cpp @@ -111,6 +111,27 @@ std::set get_used_commands(const std::string &server_name, const st return commands; } +std::vector list_backups(const std::string &server_name, const std::string &service_name) +{ + std::vector backups; + + if (server_name.empty() || service_name.empty()) + return backups; + + std::string backups_dir = get_local_backup_path(); + if (backups_dir.empty()) + return backups; + + if (fs::exists(backups_dir)) { + for (const auto& entry : fs::directory_iterator(backups_dir)) { + if (fs::is_regular_file(entry) && entry.path().extension() == ".tgz") + if (entry.path().filename().string().find(service_name) != std::string::npos) + backups.push_back(entry.path().filename().string()); + } + } + return backups; +} + bool create_service(const std::string &server_name, const std::string &service_name) { if (server_name.empty() || service_name.empty()) diff --git a/src/services.hpp b/src/services.hpp index 80594dc..cd4010e 100644 --- a/src/services.hpp +++ b/src/services.hpp @@ -18,6 +18,9 @@ namespace dropshell { ServiceInfo get_service_info(const std::string& server_name, const std::string& service_name); std::set get_used_commands(const std::string& server_name, const std::string& service_name); + // list all backups for a given server and service + std::vector list_backups(const std::string& server_name, const std::string& service_name); + bool create_service(const std::string& server_name, const std::string& service_name); } // namespace dropshell