From 27f86e95e7cc1ffcca132f38c1fd3f7b103e12eb Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 17 May 2025 22:24:25 +1200 Subject: [PATCH] . --- source/src/autogen/version.hpp | 11 ++++ source/src/commands/help.cpp | 10 ++++ source/src/commands/install.cpp | 1 + source/src/commands/nuke.cpp | 9 ++- source/src/commands/start.cpp | 91 +++++++++++++++++++++++++++++++ source/src/commands/stop.cpp | 91 +++++++++++++++++++++++++++++++ source/src/commands/uninstall.cpp | 20 +++---- 7 files changed, 221 insertions(+), 12 deletions(-) create mode 100644 source/src/autogen/version.hpp create mode 100644 source/src/commands/start.cpp create mode 100644 source/src/commands/stop.cpp diff --git a/source/src/autogen/version.hpp b/source/src/autogen/version.hpp new file mode 100644 index 0000000..d83b925 --- /dev/null +++ b/source/src/autogen/version.hpp @@ -0,0 +1,11 @@ +// version.hpp (dummy for linter/IntelliSense) +#pragma once + +#include + +namespace dropshell { + extern const std::string VERSION; + extern const std::string RELEASE_DATE; + extern const std::string AUTHOR; + extern const std::string LICENSE; +} \ No newline at end of file diff --git a/source/src/commands/help.cpp b/source/src/commands/help.cpp index 12fc959..ca34459 100644 --- a/source/src/commands/help.cpp +++ b/source/src/commands/help.cpp @@ -57,7 +57,10 @@ void help_autocomplete(const CommandContext& ctx) { void show_command(const std::string& cmd) { const auto& cmd_info = CommandRegistry::instance().find_command(cmd); if (!cmd_info) + { std::cout << "Unknown command: " << cmd << std::endl; + return; + } std::cout << " "; print_left_aligned(cmd_info->help_usage, 30); @@ -119,6 +122,13 @@ int help_handler(const CommandContext& ctx) { { // show more! show_command("list"); + std::cout << std::endl; + show_command("install"); + show_command("uninstall"); + show_command("nuke"); + std::cout << std::endl; + show_command("start"); + show_command("stop"); } return 0; } diff --git a/source/src/commands/install.cpp b/source/src/commands/install.cpp index 4d2d7fd..ec4da3b 100644 --- a/source/src/commands/install.cpp +++ b/source/src/commands/install.cpp @@ -121,6 +121,7 @@ namespace dropshell // Run install script { + std::cout << "Running " << service_info.template_name << " install script on " << server << "..." << std::endl; server_env.run_remote_template_command(service, "install", {}, silent, {}); } diff --git a/source/src/commands/nuke.cpp b/source/src/commands/nuke.cpp index 2f6bfc0..535a880 100644 --- a/source/src/commands/nuke.cpp +++ b/source/src/commands/nuke.cpp @@ -33,9 +33,16 @@ struct NukeCommandRegister { "Nuke a service on a server. Destroys everything, both local and remote!", // heredoc R"( - Nuke a service on a server. Destroys everything, both local and remote! + Nuke a service. + + Examples: nuke SERVER SERVICE nuke the given service on the given server. nuke SERVER all nuke all services on the given server. + + Note: This command is destructive and will destroy all data and all configuration, + both on the dropshell host and on the remote server. + + Use with caution! )" }); } diff --git a/source/src/commands/start.cpp b/source/src/commands/start.cpp new file mode 100644 index 0000000..dfc6991 --- /dev/null +++ b/source/src/commands/start.cpp @@ -0,0 +1,91 @@ +#include "command_registry.hpp" +#include "config.hpp" +#include "utils/utils.hpp" +#include "utils/directories.hpp" +#include "shared_commands.hpp" +#include "server_env_manager.hpp" +#include "services.hpp" +#include "servers.hpp" + +namespace dropshell +{ + + int start_handler(const CommandContext &ctx); + + static std::vector start_name_list = {"start", "start-service"}; + + // Static registration + struct StartCommandRegister + { + StartCommandRegister() + { + CommandRegistry::instance().register_command({start_name_list, + start_handler, + shared_commands::std_autocomplete_allowall, + false, // hidden + true, // requires_config + true, // requires_install + 1, // min_args (after command) + 2, // max_args (after command) + "start SERVER SERVICE|all", + "Start a service or all services on a server.", + R"( + + start SERVER SERVICE Starts the given service on the given server. + start SERVER all Starts all services on the given server. + + Note: This command will not create any data or configuration. + It will simply start the service on the remote server. + Stop the service with stop, or uninstall with uninstall. + )"}); + } + } start_command_register; + + bool start_service(const std::string &server, const std::string &service) + { + server_env_manager server_env(server); + if (!server_env.is_valid()) + { + std::cerr << "Error: Server " << server << " is not valid" << std::endl; + return false; + } + + // run the start script. + bool started = server_env.run_remote_template_command(service, "start", {}, false, {}); + + if (started) + { + std::cout << "Service " << service << " on server " << server << " started." << std::endl; + return true; + } + std::cerr << "Error: Failed to start service " << service << " on server " << server << std::endl; + return false; + } + + int start_handler(const CommandContext &ctx) + { + if (ctx.args.size() < 2) + { + std::cerr << "Error: Server name and service name are both required" << std::endl; + return 1; + } + + std::string server = safearg(ctx.args, 0); + std::string service = safearg(ctx.args, 1); + + if (service == "all") + { + // install all services on the server + maketitle("Stopping all services on " + server); + bool okay = true; + std::vector services = get_server_services_info(server); + for (const auto &service : services) + okay &= start_service(server, service.service_name); + return okay ? 0 : 1; + } + + // start the specific service. + return start_service(server, service) ? 0 : 1; + } + +} // namespace dropshell \ No newline at end of file diff --git a/source/src/commands/stop.cpp b/source/src/commands/stop.cpp new file mode 100644 index 0000000..2f16557 --- /dev/null +++ b/source/src/commands/stop.cpp @@ -0,0 +1,91 @@ +#include "command_registry.hpp" +#include "config.hpp" +#include "utils/utils.hpp" +#include "utils/directories.hpp" +#include "shared_commands.hpp" +#include "server_env_manager.hpp" +#include "services.hpp" +#include "servers.hpp" + +namespace dropshell +{ + + int stop_handler(const CommandContext &ctx); + + static std::vector stop_name_list = {"stop", "stop-service"}; + + // Static registration + struct StopCommandRegister + { + StopCommandRegister() + { + CommandRegistry::instance().register_command({stop_name_list, + stop_handler, + shared_commands::std_autocomplete_allowall, + false, // hidden + true, // requires_config + true, // requires_install + 1, // min_args (after command) + 2, // max_args (after command) + "stop SERVER SERVICE|all", + "Stop a service or all services on a server.", + R"( + + stop SERVER SERVICE Stops the given service on the given server. + stop SERVER all Stops all services on the given server. + + Note: This command will not destroy any data or configuration. + It will simply stop the service on the remote server. + Restart the service with start, or update and start it with install. + )"}); + } + } stop_command_register; + + bool stop_service(const std::string &server, const std::string &service) + { + server_env_manager server_env(server); + if (!server_env.is_valid()) + { + std::cerr << "Error: Server " << server << " is not valid" << std::endl; + return false; + } + + // run the stop script. + bool stopped = server_env.run_remote_template_command(service, "stop", {}, false, {}); + + if (stopped) + { + std::cout << "Service " << service << " on server " << server << " stopped." << std::endl; + return true; + } + std::cerr << "Error: Failed to stop service " << service << " on server " << server << std::endl; + return false; + } + + int stop_handler(const CommandContext &ctx) + { + if (ctx.args.size() < 2) + { + std::cerr << "Error: Server name and service name are both required" << std::endl; + return 1; + } + + std::string server = safearg(ctx.args, 0); + std::string service = safearg(ctx.args, 1); + + if (service == "all") + { + // install all services on the server + maketitle("Stopping all services on " + server); + bool okay = true; + std::vector services = get_server_services_info(server); + for (const auto &service : services) + okay &= stop_service(server, service.service_name); + return okay ? 0 : 1; + } + + // stop the specific service. + return stop_service(server, service) ? 0 : 1; + } + +} // namespace dropshell \ No newline at end of file diff --git a/source/src/commands/uninstall.cpp b/source/src/commands/uninstall.cpp index b0ca97e..3569b47 100644 --- a/source/src/commands/uninstall.cpp +++ b/source/src/commands/uninstall.cpp @@ -23,25 +23,25 @@ namespace dropshell uninstall_handler, shared_commands::std_autocomplete_allowall, false, // hidden - true, // requires_config - true, // requires_install + true, // requires_config + true, // requires_install 2, // min_args (after command) 2, // max_args (after command) "uninstall SERVER SERVICE|all", "Uninstall a service on a server. Does not remove configuration or user data.", // heredoc R"( - Uninstall a service on a server. Does not remove configuration or user data. - uninstall SERVER SERVICE uninstall the given service on the given server. - uninstall SERVER all uninstall all services on the given server. + Uninstall a service, leaving all configuration and data intact. + + uninstall SERVER SERVICE Uninstall the given service on the given server. + uninstall SERVER all Uninstall all services on the given server. + + Update and reinstall the service with install, or delete all configuration and data with nuke. )"}); } } uninstall_command_register; - - - - bool uninstall_service(const std::string &server, const std::string &service, bool silent=false) + bool uninstall_service(const std::string &server, const std::string &service, bool silent = false) { if (!silent) maketitle("Uninstalling " + service + " on " + server); @@ -81,7 +81,6 @@ namespace dropshell return true; } - int uninstall_handler(const CommandContext &ctx) { if (ctx.args.size() < 1) @@ -109,5 +108,4 @@ namespace dropshell return uninstall_service(server, service) ? 0 : 1; } - } // namespace dropshell \ No newline at end of file