split check and reload
All checks were successful
Build-Test-Publish / build (linux/amd64) (push) Successful in 27s
Build-Test-Publish / build (linux/arm64) (push) Successful in 1m3s

This commit is contained in:
j
2026-01-03 10:05:49 +13:00
parent 0d02b02cde
commit a36c387eb5
2 changed files with 123 additions and 105 deletions

View File

@@ -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 <filesystem>
namespace dropshell
{
int check_config_handler(const CommandContext &ctx);
static std::vector<std::string> 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

View File

@@ -12,40 +12,10 @@
namespace dropshell
{
int check_config_handler(const CommandContext &ctx);
int reload_config_handler(const CommandContext &ctx);
static std::vector<std::string> check_config_name_list = {"check-config", "check"};
static std::vector<std::string> 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