diff --git a/source/src/commands/check-config.cpp b/source/src/commands/check-config.cpp new file mode 100644 index 0000000..8d9ed60 --- /dev/null +++ b/source/src/commands/check-config.cpp @@ -0,0 +1,123 @@ +#include "command_registry.hpp" +#include "config.hpp" +#include "utils/utils.hpp" +#include "utils/directories.hpp" +#include "shared_commands.hpp" +#include "servers.hpp" +#include "services.hpp" +#include "utils/output.hpp" + +#include + +namespace dropshell +{ + + int check_config_handler(const CommandContext &ctx); + + static std::vector check_config_name_list = {"check-config", "check"}; + + // Static registration for check-config + struct CheckConfigCommandRegister + { + CheckConfigCommandRegister() + { + CommandRegistry::instance().register_command({check_config_name_list, + check_config_handler, + shared_commands::std_autocomplete, + false, // hidden + true, // requires_config + true, // requires_install + 2, // min_args (after command) + 2, // max_args (after command) + "check-config SERVER SERVICE", + "Sync config and validate it on the remote server (optional template command)", + R"( + + check-config SERVER SERVICE Syncs the configuration to the remote server and runs + the template's check-config.sh script to validate the config. + + This is useful for validating configuration changes before reloading. + The service is NOT restarted or modified - only config validation is performed. + + Note: This command is optional - templates must implement check-config.sh to support it. + )"}); + } + } check_config_command_register; + + // ------------------------------------------------------------------------------------------------ + // check_config implementation + // ------------------------------------------------------------------------------------------------ + bool check_config_service(const std::string &server, const std::string &service) + { + if (gConfig().is_server_disabled(server)) + { + warning << "Server '" << server << "' is disabled." << std::endl; + return false; + } + + ServerConfig server_env(server); + if (!server_env.is_valid()) + { + error << "Server " << server << " is not valid" << std::endl; + return false; + } + + if (!legal_service_name(service)) + { + error << "Service name contains illegal characters: " << service << std::endl; + return false; + } + + // Check if the template supports check-config + LocalServiceInfo service_info = get_service_info(server, service); + if (!SIvalid(service_info)) + { + error << "Service " << service << " not found on server " << server << std::endl; + return false; + } + + std::filesystem::path script_path = std::filesystem::path(service_info.local_template_path) / "check-config.sh"; + if (!std::filesystem::exists(script_path)) + { + info << "Template '" << service_info.template_name << "' does not support the check-config command." << std::endl; + debug << "To add support, create: " << script_path.filename().string() << std::endl; + return false; + } + + // Sync configuration to remote + info << "Syncing configuration for " << service << " on " << server << "..." << std::endl; + if (!shared_commands::rsync_service_config(server_env, service, false)) + { + error << "Failed to sync configuration" << std::endl; + return false; + } + + // Run check script + info << "Running config check..." << std::endl; + bool success = server_env.run_remote_template_command(service, "check-config", {}, false, {}, nullptr); + + if (success) + { + info << "Configuration check passed for " << service << " on " << server << std::endl; + return true; + } + + error << "Configuration check failed for " << service << " on " << server << std::endl; + return false; + } + + int check_config_handler(const CommandContext &ctx) + { + if (ctx.args.size() < 2) + { + 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); + + return check_config_service(server, service) ? 0 : 1; + } + +} // namespace dropshell diff --git a/source/src/commands/config.cpp b/source/src/commands/reload-config.cpp similarity index 51% rename from source/src/commands/config.cpp rename to source/src/commands/reload-config.cpp index 45f88b6..f48be46 100644 --- a/source/src/commands/config.cpp +++ b/source/src/commands/reload-config.cpp @@ -12,40 +12,10 @@ namespace dropshell { - int check_config_handler(const CommandContext &ctx); int reload_config_handler(const CommandContext &ctx); - static std::vector check_config_name_list = {"check-config", "check"}; static std::vector reload_config_name_list = {"reload-config", "reload"}; - // Static registration for check-config - struct CheckConfigCommandRegister - { - CheckConfigCommandRegister() - { - CommandRegistry::instance().register_command({check_config_name_list, - check_config_handler, - shared_commands::std_autocomplete, - false, // hidden - true, // requires_config - true, // requires_install - 2, // min_args (after command) - 2, // max_args (after command) - "check-config SERVER SERVICE", - "Sync config and validate it on the remote server (optional template command)", - R"( - - check-config SERVER SERVICE Syncs the configuration to the remote server and runs - the template's check-config.sh script to validate the config. - - This is useful for validating configuration changes before reloading. - The service is NOT restarted or modified - only config validation is performed. - - Note: This command is optional - templates must implement check-config.sh to support it. - )"}); - } - } check_config_command_register; - // Static registration for reload-config struct ReloadConfigCommandRegister { @@ -74,81 +44,6 @@ namespace dropshell } } reload_config_command_register; - // ------------------------------------------------------------------------------------------------ - // check_config implementation - // ------------------------------------------------------------------------------------------------ - bool check_config_service(const std::string &server, const std::string &service) - { - if (gConfig().is_server_disabled(server)) - { - warning << "Server '" << server << "' is disabled." << std::endl; - return false; - } - - ServerConfig server_env(server); - if (!server_env.is_valid()) - { - error << "Server " << server << " is not valid" << std::endl; - return false; - } - - if (!legal_service_name(service)) - { - error << "Service name contains illegal characters: " << service << std::endl; - return false; - } - - // Check if the template supports check-config - LocalServiceInfo service_info = get_service_info(server, service); - if (!SIvalid(service_info)) - { - error << "Service " << service << " not found on server " << server << std::endl; - return false; - } - - std::filesystem::path script_path = std::filesystem::path(service_info.local_template_path) / "check-config.sh"; - if (!std::filesystem::exists(script_path)) - { - info << "Template '" << service_info.template_name << "' does not support the check-config command." << std::endl; - debug << "To add support, create: " << script_path.filename().string() << std::endl; - return false; - } - - // Sync configuration to remote - info << "Syncing configuration for " << service << " on " << server << "..." << std::endl; - if (!shared_commands::rsync_service_config(server_env, service, false)) - { - error << "Failed to sync configuration" << std::endl; - return false; - } - - // Run check script - info << "Running config check..." << std::endl; - bool success = server_env.run_remote_template_command(service, "check-config", {}, false, {}, nullptr); - - if (success) - { - info << "Configuration check passed for " << service << " on " << server << std::endl; - return true; - } - - error << "Configuration check failed for " << service << " on " << server << std::endl; - return false; - } - - int check_config_handler(const CommandContext &ctx) - { - if (ctx.args.size() < 2) - { - 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); - - return check_config_service(server, service) ? 0 : 1; - } // ------------------------------------------------------------------------------------------------ // reload_config implementation