dropshell release 2025.0518.1558
Some checks failed
Dropshell Test / Build_and_Test (push) Has been cancelled
Some checks failed
Dropshell Test / Build_and_Test (push) Has been cancelled
This commit is contained in:
parent
e45afe460b
commit
263edd9b50
137
source/src/commands/restoredata.cpp
Normal file
137
source/src/commands/restoredata.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <filesystem>
|
||||
|
||||
#include "utils/output.hpp"
|
||||
#include "utils/assert.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
#include "command_registry.hpp"
|
||||
#include "config.hpp"
|
||||
#include "services.hpp"
|
||||
#include "servers.hpp"
|
||||
#include "server_env_manager.hpp"
|
||||
#include "templates.hpp"
|
||||
#include "utils/directories.hpp"
|
||||
#include "shared_commands.hpp"
|
||||
|
||||
|
||||
namespace dropshell {
|
||||
|
||||
int restoredata_handler(const CommandContext& ctx);
|
||||
|
||||
void restoredata_autocomplete(const CommandContext& ctx);
|
||||
|
||||
|
||||
static std::vector<std::string> restoredata_name_list={"restoredata","rd","restore","rest"};
|
||||
|
||||
// Static registration
|
||||
struct RestoreDataCommandRegister {
|
||||
RestoreDataCommandRegister() {
|
||||
CommandRegistry::instance().register_command({
|
||||
restoredata_name_list,
|
||||
restoredata_handler,
|
||||
restoredata_autocomplete,
|
||||
false, // hidden
|
||||
true, // requires_config
|
||||
true, // requires_install
|
||||
3, // min_args (after command)
|
||||
3, // max_args (after command)
|
||||
"restoredata SERVER SERVICE BACKUP_FILE",
|
||||
"Restore data for a service on a server, overwriting the existing data.",
|
||||
// heredoc
|
||||
R"(
|
||||
restoredata SERVER SERVICE BACKUP_FILE Restore data to a service on a server. Destructive.
|
||||
|
||||
Note: This command will not create any service configuration, you need
|
||||
to have a valid service installed first.
|
||||
The backup file must be in the local backups directory.
|
||||
|
||||
WARNING: This will permanently overwrite the service's data on the remote server!
|
||||
)"
|
||||
});
|
||||
}
|
||||
} restoredata_command_register;
|
||||
|
||||
|
||||
|
||||
int restoredata_handler(const CommandContext& ctx)
|
||||
{
|
||||
ASSERT(ctx.args.size() == 2, "Invalid number of arguments");
|
||||
std::string server = ctx.args[0];
|
||||
std::string service = ctx.args[1];
|
||||
std::string backup_file = ctx.args[2];
|
||||
|
||||
server_env_manager server_env(server);
|
||||
if (!server_env.is_valid()) {
|
||||
error << "Server " << server << " is not valid" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
shared_commands::cBackupFileName backup_details(backup_file);
|
||||
if (!backup_details.is_valid()) {
|
||||
error << "Invalid backup file: " << backup_file << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void restoredata_autocomplete(const CommandContext& ctx)
|
||||
{
|
||||
shared_commands::std_autocomplete(ctx);
|
||||
if (ctx.args.size() == 2) // next arg is the backup file
|
||||
{
|
||||
std::string server = ctx.args[0];
|
||||
std::string service = ctx.args[1];
|
||||
|
||||
std::vector<shared_commands::cBackupFileName> backups;
|
||||
|
||||
LocalServiceInfo service_info = get_service_info(server, service);
|
||||
if (!SIvalid(service_info)) {
|
||||
error << "Service " << service << " is not valid" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::string template_name = service_info.template_name;
|
||||
|
||||
std::string local_backups_dir = gConfig().get_local_backup_path();
|
||||
if (local_backups_dir.empty() || !std::filesystem::exists(local_backups_dir)) {
|
||||
error << "Error: Local backups directory not found: " << local_backups_dir << std::endl;
|
||||
return;
|
||||
}
|
||||
for (const auto& entry : std::filesystem::directory_iterator(local_backups_dir)) {
|
||||
if (!entry.is_regular_file()) continue;
|
||||
std::string filename = entry.path().filename().string();
|
||||
shared_commands::cBackupFileName backup_details(filename);
|
||||
if (backup_details.is_valid()) {
|
||||
if (backup_details.get_template_name() == template_name) {
|
||||
backups.push_back(backup_details);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort backups by datetime
|
||||
std::sort(backups.begin(), backups.end(), [](const shared_commands::cBackupFileName& a, const shared_commands::cBackupFileName& b) {
|
||||
return a.get_datetime() > b.get_datetime();
|
||||
});
|
||||
|
||||
// print most recent backup for each {host,service} pair
|
||||
std::map<std::string, std::string> unique_backups;
|
||||
for (const auto& backup : backups) {
|
||||
std::string key = backup.get_server() + "-" + backup.get_service();
|
||||
if (unique_backups.find(key) == unique_backups.end()) {
|
||||
unique_backups[key] = backup.get_filename();
|
||||
}
|
||||
}
|
||||
for (const auto& [key, value] : unique_backups) {
|
||||
rawout << value << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace dropshell
|
Loading…
x
Reference in New Issue
Block a user