This commit is contained in:
138
source/src/commands/health.cpp
Normal file
138
source/src/commands/health.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
#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"
|
||||
#include "transwarp.hpp"
|
||||
|
||||
namespace dropshell
|
||||
{
|
||||
|
||||
int health_handler(const CommandContext &ctx);
|
||||
|
||||
static std::vector<std::string> health_name_list = {"health", "check", "healthcheck", "status"};
|
||||
|
||||
// Static registration
|
||||
struct HealthCommandRegister
|
||||
{
|
||||
HealthCommandRegister()
|
||||
{
|
||||
CommandRegistry::instance().register_command({health_name_list,
|
||||
health_handler,
|
||||
std_autocomplete_allowallservices,
|
||||
false, // hidden
|
||||
true, // requires_config
|
||||
true, // requires_install
|
||||
1, // min_args (after command)
|
||||
2, // max_args (after command)
|
||||
"health SERVER",
|
||||
"Check the health of a server.",
|
||||
R"(
|
||||
health <server>
|
||||
)"});
|
||||
}
|
||||
} health_command_register;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// health command implementation
|
||||
|
||||
HealthStatus is_healthy(const std::string &server, const std::string &service)
|
||||
{
|
||||
server_env_manager env(server);
|
||||
if (!env.is_valid())
|
||||
{
|
||||
std::cerr << "Error: Server service not initialized" << std::endl;
|
||||
return HealthStatus::ERROR;
|
||||
}
|
||||
|
||||
if (!env.check_remote_dir_exists(remotepath::service(server, service)))
|
||||
{
|
||||
return HealthStatus::NOTINSTALLED;
|
||||
}
|
||||
|
||||
std::string script_path = remotepath::service_template(server, service) + "/status.sh";
|
||||
if (!env.check_remote_file_exists(script_path))
|
||||
{
|
||||
return HealthStatus::UNKNOWN;
|
||||
}
|
||||
|
||||
// Run status script, does not display output.
|
||||
if (!env.run_remote_template_command(service, "status", {}, true, {}))
|
||||
return HealthStatus::UNHEALTHY;
|
||||
return HealthStatus::HEALTHY;
|
||||
}
|
||||
|
||||
std::string healthtick(const std::string &server, const std::string &service)
|
||||
{
|
||||
std::string green_tick = "\033[32m✓\033[0m";
|
||||
std::string red_cross = "\033[31m✗\033[0m";
|
||||
std::string yellow_exclamation = "\033[33m!\033[0m";
|
||||
std::string unknown = "\033[37m✓\033[0m";
|
||||
|
||||
HealthStatus status = is_healthy(server, service);
|
||||
if (status == HealthStatus::HEALTHY)
|
||||
return green_tick;
|
||||
else if (status == HealthStatus::UNHEALTHY)
|
||||
return red_cross;
|
||||
else if (status == HealthStatus::UNKNOWN)
|
||||
return unknown;
|
||||
else
|
||||
return yellow_exclamation;
|
||||
}
|
||||
|
||||
std::string HealthStatus2String(HealthStatus status)
|
||||
{
|
||||
if (status == HealthStatus::HEALTHY)
|
||||
return ":tick:";
|
||||
else if (status == HealthStatus::UNHEALTHY)
|
||||
return ":cross:";
|
||||
else if (status == HealthStatus::UNKNOWN)
|
||||
return ":greytick:";
|
||||
else if (status == HealthStatus::NOTINSTALLED)
|
||||
return ":warning:";
|
||||
else
|
||||
return ":error:";
|
||||
}
|
||||
|
||||
std::string healthmark(const std::string &server, const std::string &service)
|
||||
{
|
||||
HealthStatus status = is_healthy(server, service);
|
||||
return HealthStatus2String(status);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// health command implementation
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
int health_handler(const CommandContext &ctx)
|
||||
{
|
||||
if (ctx.args.size() < 1)
|
||||
{
|
||||
std::cerr << "Error: Server name is required" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string server = safearg(ctx.args, 0);
|
||||
|
||||
if (ctx.args.size() == 1) {
|
||||
// get all services on server
|
||||
std::vector<LocalServiceInfo> services = get_server_services_info(server);
|
||||
transwarp::parallel exec{services.size()};
|
||||
auto task = transwarp::for_each(exec, services.begin(), services.end(), [&](const LocalServiceInfo& service) {
|
||||
std::string status = healthtick(server, service.service_name);
|
||||
std::cout << status << " " << service.service_name << " (" << service.template_name << ")" << std::endl << std::flush;
|
||||
});
|
||||
task->wait();
|
||||
return 0;
|
||||
} else {
|
||||
// get service status
|
||||
std::string service = safearg(ctx.args, 1);
|
||||
LocalServiceInfo service_info = get_service_info(server, service);
|
||||
std::cout << healthtick(server, service) << " " << service << " (" << service_info.template_name << ")" << std::endl << std::flush;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace dropshell
|
Reference in New Issue
Block a user