Seg fault!

This commit is contained in:
Your Name 2025-04-30 19:31:50 +12:00
parent 47d64a1a0d
commit 87ab33dce9
11 changed files with 84 additions and 89 deletions

View File

@ -69,7 +69,7 @@ int die(const std::string & msg) {
return 1; return 1;
} }
bool parseargs(std::string arg2, std::string arg3, std::string & server_name, std::vector<ServiceInfo>& servicelist) bool parseargs(std::string arg2, std::string arg3, std::string & server_name, std::vector<LocalServiceInfo>& servicelist)
{ {
if (arg2.empty()) return false; if (arg2.empty()) return false;
server_name = arg2; server_name = arg2;
@ -218,7 +218,7 @@ int main(int argc, char* argv[]) {
for (const auto& command : commands) { for (const auto& command : commands) {
if (cmd == command) { if (cmd == command) {
std::string server_name; std::string server_name;
std::vector<ServiceInfo> servicelist; std::vector<LocalServiceInfo> servicelist;
if (!parseargs(safearg(argc, argv, 2), safearg(argc, argv, 3), server_name, servicelist)) { if (!parseargs(safearg(argc, argv, 2), safearg(argc, argv, 3), server_name, servicelist)) {
std::cerr << "Error: " << command << " command requires server name and optionally service name" << std::endl; std::cerr << "Error: " << command << " command requires server name and optionally service name" << std::endl;
return 1; return 1;

View File

@ -64,7 +64,7 @@ int restore(const std::vector<std::string> &args, bool silent)
std::string service_name = args[3]; std::string service_name = args[3];
std::string backup_file = args[4]; std::string backup_file = args[4];
ServiceInfo service_info = get_service_info(server_name, service_name); auto service_info = get_service_info(server_name, service_name);
if (service_info.local_service_path.empty()) { if (service_info.local_service_path.empty()) {
std::cerr << "Error: Service not found" << std::endl; std::cerr << "Error: Service not found" << std::endl;
return 1; return 1;
@ -182,7 +182,7 @@ int backup(const std::vector<std::string> & args, bool silent) {
std::string server_name = args[2]; std::string server_name = args[2];
std::string service_name = args[3]; std::string service_name = args[3];
ServiceInfo service_info = get_service_info(server_name, service_name); auto service_info = get_service_info(server_name, service_name);
if (service_info.local_service_path.empty()) { if (service_info.local_service_path.empty()) {
std::cerr << "Error: Service not found" << std::endl; std::cerr << "Error: Service not found" << std::endl;
return 1; return 1;

View File

@ -75,7 +75,7 @@ std::string server_env_manager::construct_standard_command_run_cmd(const std::st
std::string script_path = remote_service_template_path + "/" + command + ".sh"; std::string script_path = remote_service_template_path + "/" + command + ".sh";
std::map<std::string, std::string> env_vars; std::map<std::string, std::string> env_vars;
get_all_service_env_vars(service_name, env_vars); get_all_service_env_vars(mServerName, service_name, env_vars);
std::string argstr = ""; std::string argstr = "";
for (const auto& arg : args) { for (const auto& arg : args) {
@ -87,48 +87,6 @@ std::string server_env_manager::construct_standard_command_run_cmd(const std::st
return run_cmd; return run_cmd;
} }
void server_env_manager::get_all_service_env_vars(const std::string &service_name, std::map<std::string, std::string> & all_env_vars) const
{
all_env_vars.clear();
// add in some handy variables.
all_env_vars["CONFIG_PATH"] = remotepath::service_config(mServerName,service_name);
all_env_vars["SERVER"] = mServerName;
all_env_vars["SERVICE"] = service_name;
{ // load service.env from the service on this machine.
std::map<std::string, std::string> env_vars;
envmanager env_manager(localfile::service_env(mServerName,service_name));
env_manager.load();
env_manager.get_all_variables(env_vars);
all_env_vars.merge(env_vars);
}
{ // load .template_info.env from the service on this machine.
std::map<std::string, std::string> env_vars;
envmanager env_manager(localfile::template_info_env(mServerName,service_name));
env_manager.load();
env_manager.get_all_variables(env_vars);
all_env_vars.merge(env_vars);
}
{ // load _default.env from the template on this machine - gets overridden by service.env
std::map<std::string, std::string> env_vars;
ServiceInfo service_info = get_service_info(mServerName, service_name);
std::string defaultenvpath = service_info.local_template_path + "/_default.env";
if (std::filesystem::exists(defaultenvpath)) {
envmanager env_manager(defaultenvpath);
env_manager.load();
env_manager.get_all_variables(env_vars);
all_env_vars.merge(env_vars);
}
else
std::cerr << "Warning: _default.env not found in template: " << defaultenvpath << std::endl;
}
}
bool server_env_manager::check_remote_dir_exists(const std::string &dir_path) const bool server_env_manager::check_remote_dir_exists(const std::string &dir_path) const
{ {

View File

@ -76,14 +76,10 @@ class server_env_manager {
std::string construct_ssh_cmd() const; std::string construct_ssh_cmd() const;
std::string construct_standard_command_run_cmd(const std::string& service_name, const std::string& command, std::vector<std::string> args, bool silent) const; std::string construct_standard_command_run_cmd(const std::string& service_name, const std::string& command, std::vector<std::string> args, bool silent) const;
private:
void get_all_service_env_vars(const std::string& service_name, std::map<std::string, std::string> & all_env_vars) const;
private: private:
std::string mServerName; std::string mServerName;
std::map<std::string, std::string> mVariables; std::map<std::string, std::string> mVariables;
bool mValid; bool mValid;
//std::unique_ptr<envmanager> m_env_manager;
}; };
} // namespace dropshell } // namespace dropshell

View File

@ -188,7 +188,7 @@ void get_all_used_commands(std::set<std::string> &commands)
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::vector<dropshell::ServiceInfo> services = dropshell::get_server_services_info(server.name); auto services = dropshell::get_server_services_info(server.name);
for (const auto& service : services) for (const auto& service : services)
commands.merge(dropshell::get_used_commands(server.name, service.service_name)); commands.merge(dropshell::get_used_commands(server.name, service.service_name));
} }

View File

@ -94,7 +94,7 @@ class service_runner {
private: private:
std::string mServer; std::string mServer;
server_env_manager mServerEnv; server_env_manager mServerEnv;
ServiceInfo mServiceInfo; LocalServiceInfo mServiceInfo;
std::string mService; std::string mService;
bool mValid; bool mValid;

View File

@ -12,8 +12,8 @@ namespace fs = std::filesystem;
namespace dropshell { namespace dropshell {
std::vector<ServiceInfo> get_server_services_info(const std::string& server_name) { std::vector<LocalServiceInfo> get_server_services_info(const std::string& server_name) {
std::vector<ServiceInfo> services; std::vector<LocalServiceInfo> services;
if (server_name.empty()) if (server_name.empty())
return services; return services;
@ -35,7 +35,7 @@ std::vector<ServiceInfo> get_server_services_info(const std::string& server_name
if (fs::exists(server_dir)) { if (fs::exists(server_dir)) {
for (const auto& entry : fs::directory_iterator(server_dir)) { for (const auto& entry : fs::directory_iterator(server_dir)) {
if (fs::is_directory(entry)) { if (fs::is_directory(entry)) {
ServiceInfo service = get_service_info(server_name, entry.path().filename().string()); auto service = get_service_info(server_name, entry.path().filename().string());
if (!service.template_name.empty()) { if (!service.template_name.empty()) {
services.push_back(service); services.push_back(service);
} }
@ -49,48 +49,36 @@ std::vector<ServiceInfo> get_server_services_info(const std::string& server_name
} }
ServiceInfo get_service_info(const std::string &server_name, const std::string &service_name) LocalServiceInfo get_service_info(const std::string &server_name, const std::string &service_name)
{ {
ServiceInfo service; LocalServiceInfo service;
if (server_name.empty() || service_name.empty()) if (server_name.empty() || service_name.empty())
return ServiceInfo(); return LocalServiceInfo();
service.service_name = service_name; service.service_name = service_name;
service.local_service_path = localpath::service(server_name, service_name); service.local_service_path = localpath::service(server_name, service_name);
if (service.local_service_path.empty()) if (service.local_service_path.empty())
return ServiceInfo(); return LocalServiceInfo();
// now set the template name and path. // now set the template name and path.
std::string local_service_env_path = localfile::service_env(server_name, service_name); std::map<std::string, std::string> variables;
envmanager env(local_service_env_path); get_all_service_env_vars(server_name, service_name, variables);
if (!env.load()) {
if (std::filesystem::exists(localpath::service(server_name, service_name)))
std::cerr << "Error: service malformed - service.env missing from " << local_service_env_path << std::endl;
else
{
template_info tinfo;
get_template_info(service_name, tinfo);
std::string template_name = service_name;
if (tinfo.local_template_path.empty())
template_name = "TEMPLATE";
std::cerr << "Error: you need to create that service first, with: dropshell create-service " << server_name << " "<<template_name<<" " << service_name << std::endl;
}
return ServiceInfo();
}
service.template_name = env.get_variable("TEMPLATE");
if (service.template_name.empty()) { // load the service.env file
std::cerr << "Error: TEMPLATE variable not defined in " << local_service_env_path << std::endl; auto it = variables.find("TEMPLATE");
return ServiceInfo(); if (it == variables.end()) {
std::cerr << "Error: TEMPLATE variable not defined in service " << service_name << " on server " << server_name << std::endl;
return LocalServiceInfo();
} }
service.template_name = it->second;
template_info tinfo; template_info tinfo;
if (!get_template_info(service.template_name, tinfo)) { if (!get_template_info(service.template_name, tinfo)) {
std::cerr << "Error: Template '" << service.template_name << "' not found" << std::endl; std::cerr << "Error: Template '" << service.template_name << "' not found" << std::endl;
return ServiceInfo(); return LocalServiceInfo();
} }
// find the template path // find the template path
@ -106,7 +94,7 @@ std::set<std::string> get_used_commands(const std::string &server_name, const st
if (server_name.empty() || service_name.empty()) if (server_name.empty() || service_name.empty())
return commands; return commands;
ServiceInfo service_info = get_service_info(server_name, service_name); auto service_info = get_service_info(server_name, service_name);
if (service_info.local_template_path.empty()) { if (service_info.local_template_path.empty()) {
std::cerr << "Error: Service not found: " << service_name << std::endl; std::cerr << "Error: Service not found: " << service_name << std::endl;
return commands; return commands;
@ -129,7 +117,7 @@ std::set<std::string> list_backups(const std::string &server_name, const std::st
return backups; return backups;
// need to find the template for the service. // need to find the template for the service.
ServiceInfo service_info = get_service_info(server_name, service_name); auto service_info = get_service_info(server_name, service_name);
if (service_info.local_template_path.empty()) { if (service_info.local_template_path.empty()) {
std::cerr << "Error: Service not found: " << service_name << std::endl; std::cerr << "Error: Service not found: " << service_name << std::endl;
return backups; return backups;
@ -210,4 +198,49 @@ bool create_service(const std::string &server_name, const std::string &template_
return true; return true;
} }
void get_all_service_env_vars(const std::string &server_name, const std::string &service_name, std::map<std::string, std::string> & all_env_vars)
{
all_env_vars.clear();
// add in some handy variables.
all_env_vars["CONFIG_PATH"] = remotepath::service_config(server_name,service_name);
all_env_vars["SERVER"] = server_name;
all_env_vars["SERVICE"] = service_name;
{ // load service.env from the service on this machine.
std::map<std::string, std::string> env_vars;
envmanager env_manager(localfile::service_env(server_name,service_name));
env_manager.load();
env_manager.get_all_variables(env_vars);
all_env_vars.merge(env_vars);
}
{ // load .template_info.env from the service on this machine.
std::map<std::string, std::string> env_vars;
envmanager env_manager(localfile::template_info_env(server_name,service_name));
env_manager.load();
env_manager.get_all_variables(env_vars);
all_env_vars.merge(env_vars);
}
{ // load _default.env from the template on this machine - gets overridden by service.env
std::map<std::string, std::string> env_vars;
auto service_info = get_service_info(server_name, service_name);
std::string defaultenvpath = service_info.local_template_path + "/_default.env";
if (std::filesystem::exists(defaultenvpath)) {
envmanager env_manager(defaultenvpath);
env_manager.load();
env_manager.get_all_variables(env_vars);
all_env_vars.merge(env_vars);
}
else
std::cerr << "Warning: _default.env not found in template: " << defaultenvpath << std::endl;
}
}
} // namespace dropshell } // namespace dropshell

View File

@ -4,20 +4,25 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <set> #include <set>
#include <map>
namespace dropshell { namespace dropshell {
struct ServiceInfo { struct LocalServiceInfo {
std::string service_name; std::string service_name;
std::string template_name; std::string template_name;
std::string local_service_path; std::string local_service_path;
std::string local_template_path; std::string local_template_path;
}; };
std::vector<ServiceInfo> get_server_services_info(const std::string& server_name); std::vector<LocalServiceInfo> get_server_services_info(const std::string& server_name);
ServiceInfo get_service_info(const std::string& server_name, const std::string& service_name); LocalServiceInfo get_service_info(const std::string& server_name, const std::string& service_name);
std::set<std::string> get_used_commands(const std::string& server_name, const std::string& service_name); std::set<std::string> get_used_commands(const std::string& server_name, const std::string& service_name);
// get all env vars for a given service
void get_all_service_env_vars(const std::string& server_name, const std::string& service_name, std::map<std::string, std::string> & all_env_vars);
// list all backups for a given service (across all servers) // list all backups for a given service (across all servers)
std::set<std::string> list_backups(const std::string& server_name, const std::string& service_name); std::set<std::string> list_backups(const std::string& server_name, const std::string& service_name);

View File

@ -162,7 +162,7 @@ namespace remotepath {
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
// Utility functions // Utility functions
std::string get_parent(std::string path) std::string get_parent(const std::string &path)
{ {
if (path.empty()) if (path.empty())
return std::string(); return std::string();

View File

@ -84,7 +84,7 @@ namespace dropshell {
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
// utility functions // utility functions
std::string get_parent(std::string path); std::string get_parent(const std::string &path);
} // namespace dropshell } // namespace dropshell

View File

@ -0,0 +1,3 @@
# Template to use - always required!
TEMPLATE=watchtower