Pre big change
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 20s

This commit is contained in:
Your Name
2025-05-11 11:33:21 +12:00
parent ea3367d8d9
commit 3c8a66c241
3 changed files with 83 additions and 40 deletions

View File

@ -16,6 +16,7 @@
#include <iomanip>
#include <chrono>
#include <libassert/assert.hpp>
#include <sstream>
namespace dropshell {
@ -45,7 +46,7 @@ bool print_help() {
std::cout << std::endl;
std::cout << " install SERVER [SERVICE] Install/reinstall/update service(s). Safe/non-destructive." << std::endl;
std::cout << " uninstall SERVER [SERVICE] Uninstalls the service on the remote server. Leaves data intact." << std::endl;
std::cout << " nuke SERVER SERVICE Nuke the service on the remote server, deleting all remote data." << std::endl;
std::cout << " nuke SERVER SERVICE Nuke the service, deleting ALL local and remote data." << std::endl;
std::cout << std::endl;
std::cout << " COMMAND SERVER [SERVICE] Run a command on service(s), e.g." << std::endl;
std::cout << " backup, restore, start, stop, logs" << std::endl;
@ -103,59 +104,84 @@ void printversion() {
std::cout << "License: " << LICENSE << std::endl;
}
#define HAPPYEXIT(CMD, RUNCMD) {if (safearg(argc,argv,1) == CMD) {RUNCMD; return 0;}}
#define BOOLEXIT(CMD, RUNCMD) {if (safearg(argc,argv,1) == CMD) {return (RUNCMD) ? 0 : 1;}}
auto command_match = [](const std::string& cmd_list, int argc, char* argv[]) -> bool {
std::istringstream iss(cmd_list);
std::string cmd_item;
while (iss >> cmd_item) {
if (cmd_item == safearg(argc, argv, 1)) {
return true;
}
}
return false;
};
#define BOOLEXIT(CMD_LIST, RUNCMD) { \
if (command_match(CMD_LIST, argc, argv)) { \
return (RUNCMD) ? 0 : 1; \
} \
}
#define HAPPYEXIT(CMD_LIST, RUNCMD) { \
if (command_match(CMD_LIST, argc, argv)) { \
RUNCMD; \
return 0; \
} \
}
int edit_config()
{
if (!gConfig().is_config_set())
gConfig().save_config(false); // save defaults.
std::string config_file = localfile::dropshell_json();
if (!service_runner::edit_file(config_file) || !std::filesystem::exists(config_file))
return die("Error: Failed to edit config file.");
gConfig().load_config();
if (!gConfig().is_config_set())
return die("Error: Failed to load and parse edited config file!");
gConfig().save_config(true);
std::cout << "Successfully edited config file at " << config_file << std::endl;
return 0;
}
int main(int argc, char* argv[]) {
HAPPYEXIT("hash", hash_demo_raw(safearg(argc,argv,2)))
HAPPYEXIT("makesafecmd", std::cout<<makesafecmd(safearg(argc,argv,2))<<std::endl)
HAPPYEXIT("version", printversion())
BOOLEXIT("test-template", gTemplateManager().test_template(safearg(argc,argv,2)))
BOOLEXIT("help -h --help h halp", print_help())
ASSERT(safearg(argc,argv,1) != "assert", "Hello! Here is an assert.");
try {
// silently attempt to load the config file and templates.
gConfig().load_config();
if (gConfig().is_config_set())
if (gConfig().is_config_set())
gTemplateManager().load_sources();
if (argc < 2)
if (argc < 2)
return print_help() ? 0 : 1;
std::string cmd = argv[1];
if (cmd == "autocomplete") {
if (cmd == "autocomplete")
{
std::vector<std::string> argvec;
for (int i=0; i<argc; i++)
for (int i = 0; i < argc; i++)
argvec.push_back(argv[i]);
return autocomplete(argvec) ? 0 : 1;
return autocomplete::autocomplete(argvec) ? 0 : 1;
}
if (cmd == "help" || cmd == "-h" || cmd == "--help" || cmd== "h" || cmd=="halp")
return print_help() ? 0 : 1;
if (cmd == "edit" && argc < 3) {
if (!gConfig().is_config_set())
gConfig().save_config(false);
std::string config_file = localfile::dropshell_json();
if (!service_runner::edit_file(config_file) || !std::filesystem::exists(config_file))
return die("Error: Failed to edit config file.");
gConfig().load_config();
if (!gConfig().is_config_set())
return die("Error: Failed to load and parse edited config file.");
gConfig().save_config(true);
std::cout << "Successfully edited config file at " << config_file << std::endl;
return 0;
}
if (cmd == "edit" && argc < 3)
return edit_config();
// ------------------------------------------------------------
// from here we require the config file to be loaded.
if (!gConfig().is_config_set())
return die("Please run 'dropshell edit' to set up the dropshell configuration.");
const std::vector<std::string> & server_definition_paths = gConfig().get_local_server_definition_paths();
if (server_definition_paths.size()>1) { // only show if there are multiple.
std::cout << "Server definition paths: ";
@ -182,10 +208,7 @@ int main(int argc, char* argv[]) {
return die("dropshell server: too many arguments");
}
if (cmd == "templates") {
gTemplateManager().list_templates();
return 0;
}
HAPPYEXIT("templates", gTemplateManager().list_templates());
if (cmd == "create-template") {
if (argc < 3) return die("Error: create-template requires a template name");
@ -217,7 +240,8 @@ int main(int argc, char* argv[]) {
// handle running a command.
std::set<std::string> commands;
get_all_used_commands(commands);
commands.merge(std::set<std::string>{"ssh","edit","_allservicesstatus","fullnuke"}); // handled by service_runner, but not in template_shell_commands.
autocomplete::merge_commands(commands, autocomplete::service_commands_require_config); // handled by service_runner, but not in template_shell_commands.
if (commands.count(cmd)) {
std::set<std::string> safe_commands = {"nuke", "fullnuke"};