Install working
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 19s

This commit is contained in:
Your Name 2025-05-11 16:26:25 +12:00
parent 25bc0b4655
commit 7e95779d98
8 changed files with 146 additions and 103 deletions

View File

@ -1,9 +1,8 @@
#include "command_registry.hpp" #include "command_registry.hpp"
#include "config.hpp" #include "config.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
#include "service_runner.hpp"
#include "utils/directories.hpp" #include "utils/directories.hpp"
#include "standard_autocomplete.hpp" #include "shared_commands.hpp"
#include <unistd.h> #include <unistd.h>
#include <cstring> #include <cstring>
@ -14,7 +13,6 @@
namespace dropshell { namespace dropshell {
void edit_autocomplete(const CommandContext& ctx);
int edit_handler(const CommandContext& ctx); int edit_handler(const CommandContext& ctx);
static std::vector<std::string> edit_name_list={"edit"}; static std::vector<std::string> edit_name_list={"edit"};
@ -25,7 +23,7 @@ struct EditCommandRegister {
CommandRegistry::instance().register_command({ CommandRegistry::instance().register_command({
edit_name_list, edit_name_list,
edit_handler, edit_handler,
edit_autocomplete, std_autocomplete,
false, // hidden false, // hidden
false, // requires_config false, // requires_config
0, // min_args (after command) 0, // min_args (after command)
@ -166,12 +164,6 @@ int edit_handler(const CommandContext& ctx) {
return -1; return -1;
} }
// ------------------------------------------------------------------------------------------------
// edit command autocomplete
// ------------------------------------------------------------------------------------------------
void edit_autocomplete(const CommandContext& ctx) {
std_autocomplete(edit_name_list, ctx);
}

View File

@ -1,64 +1,132 @@
#include "command_registry.hpp" #include "command_registry.hpp"
#include "config.hpp" #include "config.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
#include "service_runner.hpp"
#include "utils/directories.hpp" #include "utils/directories.hpp"
#include "standard_autocomplete.hpp"
#include "templates.hpp" #include "templates.hpp"
#include "shared_commands.hpp" #include "shared_commands.hpp"
#include "server_env_manager.hpp"
#include "services.hpp"
#include "servers.hpp"
namespace dropshell
{
namespace dropshell { int health_handler(const CommandContext &ctx);
int health_handler(const CommandContext& ctx); static std::vector<std::string> health_name_list = {"health", "check", "healthcheck", "status"};
void health_autocomplete(const CommandContext& ctx);
static std::vector<std::string> health_name_list={"health","check","healthcheck","status"};
// Static registration // Static registration
struct HealthCommandRegister { struct HealthCommandRegister
HealthCommandRegister() { {
CommandRegistry::instance().register_command({ HealthCommandRegister()
health_name_list, {
health_handler, CommandRegistry::instance().register_command({health_name_list,
health_autocomplete, health_handler,
false, // hidden std_autocomplete,
false, // requires_config false, // hidden
1, // min_args (after command) false, // requires_config
2, // max_args (after command) 1, // min_args (after command)
"health SERVER", 2, // max_args (after command)
"Check the health of a server.", "health SERVER",
R"( "Check the health of a server.",
R"(
health <server> health <server>
)" )"});
});
} }
} health_command_register; } health_command_register;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// health command implementation // health command implementation
std::string healthtick(const std::string& server, const std::string& service) { HealthStatus is_healthy(const std::string &server, const std::string &service)
return "OK"; {
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 // health command implementation
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
int health_handler(const CommandContext& ctx) { int health_handler(const CommandContext &ctx)
if (ctx.args.size() < 1) { {
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);
for (const auto& service : services) {
std::cout << service.service_name << " " << healthtick(server, service.service_name) << std::endl;
}
} else {
// get service status
std::string service = safearg(ctx.args, 1);
std::cout << service << " " << healthtick(server, service) << std::endl;
} }
return 0; return 0;
} }
// ------------------------------------------------------------------------------------------------
// health autocomplete
// ------------------------------------------------------------------------------------------------
void health_autocomplete(const CommandContext& ctx) {
if (ctx.args.size() == 1) {
}
}
} // namespace dropshell } // namespace dropshell

View File

@ -1,9 +1,8 @@
#include "command_registry.hpp" #include "command_registry.hpp"
#include "config.hpp" #include "config.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
#include "service_runner.hpp"
#include "utils/directories.hpp" #include "utils/directories.hpp"
#include "standard_autocomplete.hpp" #include "shared_commands.hpp"
#include "version.hpp" #include "version.hpp"
#include <unistd.h> #include <unistd.h>

View File

@ -1,9 +1,7 @@
#include "command_registry.hpp" #include "command_registry.hpp"
#include "config.hpp" #include "config.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
#include "service_runner.hpp"
#include "utils/directories.hpp" #include "utils/directories.hpp"
#include "standard_autocomplete.hpp"
#include "templates.hpp" #include "templates.hpp"
#include "shared_commands.hpp" #include "shared_commands.hpp"
@ -16,7 +14,6 @@
namespace dropshell { namespace dropshell {
void install_autocomplete(const CommandContext& ctx);
int install_handler(const CommandContext& ctx); int install_handler(const CommandContext& ctx);
static std::vector<std::string> install_name_list={"install"}; static std::vector<std::string> install_name_list={"install"};
@ -27,17 +24,18 @@ struct InstallCommandRegister {
CommandRegistry::instance().register_command({ CommandRegistry::instance().register_command({
install_name_list, install_name_list,
install_handler, install_handler,
install_autocomplete, std_autocomplete,
false, // hidden false, // hidden
false, // requires_config false, // requires_config
2, // min_args (after command) 1, // min_args (after command)
2, // max_args (after command) 2, // max_args (after command)
"install SERVER SERVICE", "install SERVER [SERVICE]",
"Install/reinstall/update service(s). Safe/non-destructive.", "Install/reinstall/update service(s). Safe/non-destructive.",
// heredoc // heredoc
R"( R"(
Install a service on a server. Install a service(s) on a server.
install <server> <service> install the given service on the given server. install <server> <service> (re)install the given service on the given server.
install <server> (re)install all configured services on the given server.
Note you need to create the service first with: Note you need to create the service first with:
dropshell create-service <server> <template> <service> dropshell create-service <server> <template> <service>
@ -137,24 +135,28 @@ bool install_service(const std::string& server, const std::string& service, bool
// install command implementation // install command implementation
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
int install_handler(const CommandContext& ctx) { int install_handler(const CommandContext& ctx) {
if (ctx.args.size() < 2) { if (ctx.args.size() < 1) {
std::cerr << "Error: install requires a server and service" << std::endl; std::cerr << "Error: install requires a server and (optionally) a service" << std::endl;
return 1; return 1;
} }
std::string server = safearg(ctx.args,0); std::string server = safearg(ctx.args,0);
if (ctx.args.size() == 1) {
// install all services on the server
bool okay=true;
std::vector<LocalServiceInfo> services = get_server_services_info(server);
for (const auto& service : services) {
if (!install_service(server, service.service_name, false))
okay=false;
}
return okay ? 0 : 1;
}
std::string service = safearg(ctx.args,1); std::string service = safearg(ctx.args,1);
return install_service(server, service, false) ? 0 : 1; return install_service(server, service, false) ? 0 : 1;
} }
// ------------------------------------------------------------------------------------------------
// install command autocomplete
// ------------------------------------------------------------------------------------------------
void install_autocomplete(const CommandContext& ctx) {
std_autocomplete(install_name_list, ctx);
}
} // namespace dropshell } // namespace dropshell

View File

@ -1,9 +1,8 @@
#include "command_registry.hpp" #include "command_registry.hpp"
#include "config.hpp" #include "config.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
#include "service_runner.hpp"
#include "utils/directories.hpp" #include "utils/directories.hpp"
#include "standard_autocomplete.hpp" #include "shared_commands.hpp"
#include "servers.hpp" #include "servers.hpp"
#include "tableprint.hpp" #include "tableprint.hpp"
#include "transwarp.hpp" #include "transwarp.hpp"
@ -17,7 +16,6 @@
namespace dropshell { namespace dropshell {
void list_autocomplete(const CommandContext& ctx);
int list_handler(const CommandContext& ctx); int list_handler(const CommandContext& ctx);
static std::vector<std::string> list_name_list={"list","ls","info","-l"}; static std::vector<std::string> list_name_list={"list","ls","info","-l"};
@ -28,7 +26,7 @@ struct ListCommandRegister {
CommandRegistry::instance().register_command({ CommandRegistry::instance().register_command({
list_name_list, list_name_list,
list_handler, list_handler,
list_autocomplete, std_autocomplete,
false, // hidden false, // hidden
false, // requires_config false, // requires_config
0, // min_args (after command) 0, // min_args (after command)
@ -46,14 +44,6 @@ List details for servers and services controller by dropshell.
} }
} list_command_register; } list_command_register;
// ------------------------------------------------------------------------------------------------
// list command autocomplete
// ------------------------------------------------------------------------------------------------
void list_autocomplete(const CommandContext& ctx) {
std_autocomplete(list_name_list, ctx);
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// list command handler // list command handler
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -2,6 +2,7 @@
#define SHARED_COMMANDS_HPP #define SHARED_COMMANDS_HPP
#include "servers.hpp" #include "servers.hpp"
#include "command_registry.hpp"
namespace dropshell { namespace dropshell {
@ -18,5 +19,8 @@ namespace dropshell {
// defined in health.cpp // defined in health.cpp
std::string healthtick(const std::string& server, const std::string& service); std::string healthtick(const std::string& server, const std::string& service);
// defined in standard_autocomplete.cpp
void std_autocomplete(const CommandContext& ctx);
} // namespace dropshell } // namespace dropshell
#endif #endif

View File

@ -1,23 +1,24 @@
#include "standard_autocomplete.hpp" #include "shared_commands.hpp"
#include "command_registry.hpp"
#include "servers.hpp" #include "servers.hpp"
#include "services.hpp" #include "services.hpp"
void dropshell::std_autocomplete(const std::vector<std::string> &name_list, const CommandContext &ctx)
#include <libassert/assert.hpp>
namespace dropshell {
void std_autocomplete(const CommandContext &ctx)
{ {
ASSERT(ctx.args.size() > 0);
if (ctx.args.size() == 1) { if (ctx.args.size() == 1) {
// edit command
for (const auto& name : name_list) {
std::cout << name << std::endl;
}
}
else if (ctx.args.size() == 2) {
// list servers // list servers
std::vector<ServerInfo> servers = get_configured_servers(); std::vector<ServerInfo> servers = get_configured_servers();
for (const auto& server : servers) { for (const auto& server : servers) {
std::cout << server.name << std::endl; std::cout << server.name << std::endl;
} }
} }
else if (ctx.args.size() == 3) { else if (ctx.args.size() == 2) {
// list services // list services
std::vector<LocalServiceInfo> services = get_server_services_info(ctx.args[2]); std::vector<LocalServiceInfo> services = get_server_services_info(ctx.args[2]);
for (const auto& service : services) { for (const auto& service : services) {
@ -25,3 +26,5 @@ void dropshell::std_autocomplete(const std::vector<std::string> &name_list, cons
} }
} }
} }
} // namespace dropshell

View File

@ -1,15 +0,0 @@
#ifndef STANDARD_AUTOCOMPLETE_HPP
#define STANDARD_AUTOCOMPLETE_HPP
#include <vector>
#include <string>
#include "command_registry.hpp"
namespace dropshell {
void std_autocomplete(const std::vector<std::string>& name_list, const CommandContext& ctx);
} // namespace dropshell
#endif