This commit is contained in:
parent
ea3367d8d9
commit
3c8a66c241
@ -14,15 +14,21 @@ namespace autocomplete {
|
|||||||
const std::set<std::string> system_commands_noargs = {"templates","autocomplete_list_servers","autocomplete_list_services","autocomplete_list_commands"};
|
const std::set<std::string> system_commands_noargs = {"templates","autocomplete_list_servers","autocomplete_list_services","autocomplete_list_commands"};
|
||||||
const std::set<std::string> system_commands_always_available = {"help","edit"};
|
const std::set<std::string> system_commands_always_available = {"help","edit"};
|
||||||
const std::set<std::string> system_commands_require_config = {"server","templates","create-service","create-template","create-server","ssh","list"};
|
const std::set<std::string> system_commands_require_config = {"server","templates","create-service","create-template","create-server","ssh","list"};
|
||||||
|
const std::set<std::string> system_commands_hidden = {"nuke","_allservicesstatus"};
|
||||||
|
|
||||||
|
const std::set<std::string> service_commands_require_config = {"ssh","edit","nuke","_allservicesstatus"};
|
||||||
|
|
||||||
|
void merge_commands(std::set<std::string> &commands, const std::set<std::string> &new_commands)
|
||||||
|
{
|
||||||
|
commands.insert(new_commands.begin(), new_commands.end());
|
||||||
|
}
|
||||||
|
|
||||||
bool is_no_arg_cmd(std::string cmd)
|
bool is_no_arg_cmd(std::string cmd)
|
||||||
{
|
{
|
||||||
return system_commands_noargs.find(cmd) != system_commands_noargs.end();
|
return system_commands_noargs.find(cmd) != system_commands_noargs.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
bool autocomplete(const std::vector<std::string> &args)
|
||||||
|
|
||||||
bool dropshell::autocomplete(const std::vector<std::string> &args)
|
|
||||||
{
|
{
|
||||||
if (args.size() < 3) // dropshell autocomplete ???
|
if (args.size() < 3) // dropshell autocomplete ???
|
||||||
{
|
{
|
||||||
@ -94,16 +100,16 @@ bool dropshell::autocomplete(const std::vector<std::string> &args)
|
|||||||
return false; // catch-all.
|
return false; // catch-all.
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dropshell::autocomplete_list_commands()
|
bool autocomplete_list_commands()
|
||||||
{
|
{
|
||||||
std::set<std::string> commands;
|
std::set<std::string> commands;
|
||||||
dropshell::get_all_used_commands(commands);
|
dropshell::get_all_used_commands(commands);
|
||||||
|
|
||||||
// add in commmands hard-coded and handled in main
|
// add in commmands hard-coded and handled in main
|
||||||
commands.insert(autocomplete::system_commands_always_available.begin(), autocomplete::system_commands_always_available.end());
|
autocomplete::merge_commands(commands, autocomplete::system_commands_always_available);
|
||||||
|
|
||||||
if (dropshell::gConfig().is_config_set())
|
if (dropshell::gConfig().is_config_set())
|
||||||
commands.insert(autocomplete::system_commands_require_config.begin(), autocomplete::system_commands_require_config.end());
|
autocomplete::merge_commands(commands, autocomplete::system_commands_require_config);
|
||||||
|
|
||||||
for (const auto& command : commands) {
|
for (const auto& command : commands) {
|
||||||
std::cout << command << std::endl;
|
std::cout << command << std::endl;
|
||||||
@ -111,3 +117,4 @@ bool dropshell::autocomplete_list_commands()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace autocomplete
|
@ -3,14 +3,26 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
namespace autocomplete {
|
||||||
|
|
||||||
namespace dropshell {
|
extern const std::set<std::string> system_commands_noargs;
|
||||||
|
extern const std::set<std::string> system_commands_always_available;
|
||||||
|
extern const std::set<std::string> system_commands_require_config;
|
||||||
|
extern const std::set<std::string> system_commands_hidden;
|
||||||
|
|
||||||
|
extern const std::set<std::string> service_commands_require_config;
|
||||||
|
|
||||||
|
void merge_commands(std::set<std::string> &commands, const std::set<std::string> &new_commands);
|
||||||
|
|
||||||
|
bool is_no_arg_cmd(std::string cmd);
|
||||||
|
|
||||||
bool autocomplete(const std::vector<std::string> &args);
|
bool autocomplete(const std::vector<std::string> &args);
|
||||||
|
|
||||||
bool autocomplete_list_commands();
|
bool autocomplete_list_commands();
|
||||||
|
|
||||||
} // namespace dropshell
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
84
src/main.cpp
84
src/main.cpp
@ -16,6 +16,7 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <libassert/assert.hpp>
|
#include <libassert/assert.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace dropshell {
|
namespace dropshell {
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ bool print_help() {
|
|||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << " install SERVER [SERVICE] Install/reinstall/update service(s). Safe/non-destructive." << 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 << " 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 << std::endl;
|
||||||
std::cout << " COMMAND SERVER [SERVICE] Run a command on service(s), e.g." << 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;
|
std::cout << " backup, restore, start, stop, logs" << std::endl;
|
||||||
@ -103,14 +104,54 @@ void printversion() {
|
|||||||
std::cout << "License: " << LICENSE << std::endl;
|
std::cout << "License: " << LICENSE << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HAPPYEXIT(CMD, RUNCMD) {if (safearg(argc,argv,1) == CMD) {RUNCMD; return 0;}}
|
auto command_match = [](const std::string& cmd_list, int argc, char* argv[]) -> bool {
|
||||||
#define BOOLEXIT(CMD, RUNCMD) {if (safearg(argc,argv,1) == CMD) {return (RUNCMD) ? 0 : 1;}}
|
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[]) {
|
int main(int argc, char* argv[]) {
|
||||||
HAPPYEXIT("hash", hash_demo_raw(safearg(argc,argv,2)))
|
HAPPYEXIT("hash", hash_demo_raw(safearg(argc,argv,2)))
|
||||||
HAPPYEXIT("makesafecmd", std::cout<<makesafecmd(safearg(argc,argv,2))<<std::endl)
|
HAPPYEXIT("makesafecmd", std::cout<<makesafecmd(safearg(argc,argv,2))<<std::endl)
|
||||||
HAPPYEXIT("version", printversion())
|
HAPPYEXIT("version", printversion())
|
||||||
BOOLEXIT("test-template", gTemplateManager().test_template(safearg(argc,argv,2)))
|
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.");
|
ASSERT(safearg(argc,argv,1) != "assert", "Hello! Here is an assert.");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -124,38 +165,23 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
std::string cmd = argv[1];
|
std::string cmd = argv[1];
|
||||||
|
|
||||||
if (cmd == "autocomplete") {
|
if (cmd == "autocomplete")
|
||||||
|
{
|
||||||
std::vector<std::string> argvec;
|
std::vector<std::string> argvec;
|
||||||
for (int i=0; i<argc; i++)
|
for (int i = 0; i < argc; i++)
|
||||||
argvec.push_back(argv[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")
|
if (cmd == "edit" && argc < 3)
|
||||||
return print_help() ? 0 : 1;
|
return edit_config();
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
// from here we require the config file to be loaded.
|
// from here we require the config file to be loaded.
|
||||||
if (!gConfig().is_config_set())
|
if (!gConfig().is_config_set())
|
||||||
return die("Please run 'dropshell edit' to set up the dropshell configuration.");
|
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();
|
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.
|
if (server_definition_paths.size()>1) { // only show if there are multiple.
|
||||||
std::cout << "Server definition paths: ";
|
std::cout << "Server definition paths: ";
|
||||||
@ -182,10 +208,7 @@ int main(int argc, char* argv[]) {
|
|||||||
return die("dropshell server: too many arguments");
|
return die("dropshell server: too many arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == "templates") {
|
HAPPYEXIT("templates", gTemplateManager().list_templates());
|
||||||
gTemplateManager().list_templates();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd == "create-template") {
|
if (cmd == "create-template") {
|
||||||
if (argc < 3) return die("Error: create-template requires a template name");
|
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.
|
// handle running a command.
|
||||||
std::set<std::string> commands;
|
std::set<std::string> commands;
|
||||||
get_all_used_commands(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)) {
|
if (commands.count(cmd)) {
|
||||||
std::set<std::string> safe_commands = {"nuke", "fullnuke"};
|
std::set<std::string> safe_commands = {"nuke", "fullnuke"};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user