dropshell release 2025.0524.1149
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 17s
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 17s
This commit is contained in:
parent
0934179053
commit
763293c7d0
@ -1,5 +1,5 @@
|
||||
SSH_ADDRESS=localhost
|
||||
SSH_PORT=22
|
||||
SSH_USER=$(whoami)
|
||||
SSH_UNPRIVILEGED_USER=$(whoami)
|
||||
|
||||
|
||||
|
@ -152,7 +152,7 @@ namespace dropshell
|
||||
recursive_copy(tinfo.local_template_path() / "config", service_dir);
|
||||
|
||||
// append TEMPLATE_HASH to the .template_info.env file
|
||||
std::string template_info_env_file = service_dir + "/.template_info.env";
|
||||
std::string template_info_env_file = service_dir + "/" + filenames::template_info_env;
|
||||
std::ofstream template_info_env_file_out(template_info_env_file);
|
||||
template_info_env_file_out << "TEMPLATE_HASH=" << tinfo.hash() << std::endl;
|
||||
template_info_env_file_out.close();
|
||||
@ -191,12 +191,12 @@ namespace dropshell
|
||||
}
|
||||
|
||||
|
||||
info << "Setting SSH_USER to " << sshuser << " in service.env file" << std::endl;
|
||||
info << "Setting SSH_USER to " << sshuser << " in the " << filenames::service_env << " file" << std::endl;
|
||||
{ // edit the service.env file to set the SSH_USER.
|
||||
std::string template_service_env_file = tinfo.local_template_path() / "config" / "service.env";
|
||||
std::string template_service_env_file = tinfo.local_template_path() / "config" / filenames::service_env;
|
||||
ASSERT(std::filesystem::exists(template_service_env_file), "Template service env file not found: " + template_service_env_file);
|
||||
std::ifstream template_service_env_file_in(template_service_env_file);
|
||||
std::ofstream service_env_file_out(service_dir + "/service.env");
|
||||
std::ofstream service_env_file_out(localfile::template_info_env(server_name, service_name));
|
||||
std::string line;
|
||||
while (std::getline(template_service_env_file_in, line))
|
||||
{
|
||||
@ -239,6 +239,23 @@ namespace dropshell
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool merge_updated_service_template(const std::string &server_name, const std::string &service_name)
|
||||
{
|
||||
LocalServiceInfo service_info = get_service_info(server_name, service_name);
|
||||
ASSERT(SIvalid(service_info), "Service info is not valid for " + service_name + " on " + server_name);
|
||||
|
||||
template_info tinfo = gTemplateManager().get_template_info(service_info.template_name);
|
||||
ASSERT(tinfo.is_set(), "Failed to load template " + service_info.template_name);
|
||||
|
||||
// copy across .template_info.env file
|
||||
std::string template_service_env_file = "";
|
||||
std::string target_service_env_file = localfile::template_info_env(server_name, service_name);
|
||||
ASSERT(std::filesystem::exists(template_service_env_file), "Template service env file not found: " + template_service_env_file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace shared_commands
|
||||
|
||||
} // namespace dropshell
|
@ -70,6 +70,15 @@ namespace dropshell
|
||||
if (!SIvalid(service_info))
|
||||
return false;
|
||||
|
||||
if (!service_info.service_template_hash_match)
|
||||
{
|
||||
warning << "Service " << service << " is using an old template. Updating. " << std::endl;
|
||||
if (!merge_updated_service_template(server_env.get_server_name(), service))
|
||||
{
|
||||
error << "Failed to merge updated service template. " << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
maketitle("Installing " + service + " (" + service_info.template_name + ") on " + server);
|
||||
|
||||
|
@ -98,6 +98,7 @@ namespace dropshell
|
||||
|
||||
// defined in create-service.cpp
|
||||
bool create_service(const std::string &server_name, const std::string &template_name, const std::string &service_name, std::string user_override="");
|
||||
bool merge_updated_service_template(const std::string &server_name, const std::string &service_name);
|
||||
|
||||
} // namespace shared_commands
|
||||
} // namespace dropshell
|
||||
|
@ -28,23 +28,22 @@ namespace dropshell
|
||||
if (server_name.empty())
|
||||
return;
|
||||
|
||||
// Construct the full path to server.json
|
||||
std::string server_env_path = localfile::server_json(server_name);
|
||||
std::string server_json_path = localfile::server_json(server_name);
|
||||
|
||||
// Check if file exists
|
||||
if (!std::filesystem::exists(server_env_path))
|
||||
if (!std::filesystem::exists(server_json_path))
|
||||
{
|
||||
std::cerr << "Server environment file not found: " + server_env_path << " for server " << server_name << std::endl;
|
||||
std::cerr << "Server environment file not found: " + server_json_path << " for server " << server_name << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Use envmanager to handle the environment file
|
||||
nlohmann::json server_env_json = nlohmann::json::parse(std::ifstream(server_env_path));
|
||||
nlohmann::json server_env_json = nlohmann::json::parse(std::ifstream(server_json_path));
|
||||
if (server_env_json.empty())
|
||||
{
|
||||
error << "Failed to parse server environment file at "<< server_env_path << std::endl;
|
||||
error << "Failed to parse server environment file at "<< server_json_path << std::endl;
|
||||
info << "The returned json was empty." << std::endl;
|
||||
return;
|
||||
}
|
||||
@ -96,7 +95,7 @@ namespace dropshell
|
||||
|
||||
if (mUsers.empty())
|
||||
{
|
||||
error << "No users defined in server configuration " << server_env_path << std::endl;
|
||||
error << "No users defined in server configuration " << server_json_path << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -104,7 +103,7 @@ namespace dropshell
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
error << "Failed to parse " << server_env_path << std::endl;
|
||||
error << "Failed to parse " << server_json_path << std::endl;
|
||||
error << "Error: " << e.what() << std::endl;
|
||||
|
||||
mValid = false;
|
||||
@ -334,30 +333,10 @@ namespace dropshell
|
||||
argstr += " " + quote(dequote(trim(arg)));
|
||||
}
|
||||
|
||||
if (env_vars.find("RUNAS") == env_vars.end())
|
||||
{
|
||||
error << "Error: RUNAS is not set in .template_info.env for the service." << std::endl;
|
||||
return std::nullopt;
|
||||
}
|
||||
std::string runas = env_vars.find("RUNAS")->second;
|
||||
if (runas != "root" && runas != "user")
|
||||
{
|
||||
error << "Error: RUNAS is not set to root or user in .template_info.env for the service." << std::endl;
|
||||
return std::nullopt;
|
||||
}
|
||||
bool run_as_root = runas == "root";
|
||||
|
||||
if (run_as_root && !hasRootUser())
|
||||
{
|
||||
error << "Error: The service " << service_name << " is set to run as root on the remote server, but the server environment does not allow root services." << std::endl;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
sCommand sc(
|
||||
remote_service_template_path,
|
||||
quote(script_path) + argstr + (silent ? " > /dev/null 2>&1" : ""),
|
||||
env_vars,
|
||||
run_as_root);
|
||||
env_vars);
|
||||
|
||||
if (sc.empty())
|
||||
{
|
||||
@ -427,7 +406,7 @@ namespace dropshell
|
||||
|
||||
// 3. create a template server.env file in the server directory
|
||||
std::string user = getenv("USER");
|
||||
std::string server_env_path = server_dir + "/server.json";
|
||||
std::string server_env_path = server_dir + "/" + filenames::server_json;
|
||||
std::ofstream server_env_file(server_env_path);
|
||||
server_env_file << "{" << std::endl;
|
||||
server_env_file << " \"SSH_HOST\": \"" << server_name << "\"," << std::endl;
|
||||
|
@ -67,7 +67,7 @@ namespace dropshell
|
||||
auto it = variables.find(variable_name);
|
||||
if (it == variables.end())
|
||||
{
|
||||
error << "Variable " << variable_name << " not found in the service .template_info.env file" << std::endl;
|
||||
error << "Variable " << variable_name << " not found in the service " << filenames::template_info_env << std::endl;
|
||||
return false;
|
||||
}
|
||||
return it->second == "true";
|
||||
@ -237,7 +237,7 @@ namespace dropshell
|
||||
if (user.empty())
|
||||
{
|
||||
error << "SSH_USER variable not defined in service " << service_name << " on server " << server_name << std::endl;
|
||||
info << "This variable definition is always required, and usually set int he service.env file." << std::endl;
|
||||
info << "This variable definition is always required, and usually set in the "<<filenames::service_env << " file." << std::endl;
|
||||
info << "Please check " << localfile::service_env(server_name, service_name) << std::endl;
|
||||
return false;
|
||||
}
|
||||
@ -256,7 +256,7 @@ namespace dropshell
|
||||
{
|
||||
error << "TEMPLATE variable not defined in service " << service_name << " on server " << server_name << std::endl;
|
||||
info << "The TEMPLATE variable is required to determine the template name." << std::endl;
|
||||
info << "Please check the service.env file and the .template_info.env file in:" << std::endl;
|
||||
info << "Please check the " << filenames::service_env << " file and the "<< filenames::template_info_env << " file in:" << std::endl;
|
||||
info << " " << localpath::service(server_name, service_name) << std::endl
|
||||
<< std::endl;
|
||||
return false;
|
||||
|
@ -220,9 +220,9 @@
|
||||
// modify the TEMPLATE=example line in the .template_info.env file to TEMPLATE=<template_name>
|
||||
std::string search_string = "TEMPLATE=";
|
||||
std::string replacement_line = "TEMPLATE=" + template_name;
|
||||
std::string service_env_path = new_template_path + "/config/.template_info.env";
|
||||
std::string service_env_path = new_template_path + "/config/" + filenames::template_info_env;
|
||||
if (!replace_line_in_file(service_env_path, search_string, replacement_line)) {
|
||||
std::cerr << "Error: Failed to replace TEMPLATE= line in the .template_info.env file" << std::endl;
|
||||
std::cerr << "Error: Failed to replace TEMPLATE= line in the " << filenames::template_info_env <<" file" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -306,8 +306,8 @@
|
||||
std::string template_name = std::filesystem::path(template_path).filename().string();
|
||||
|
||||
std::vector<std::string> required_files = {
|
||||
"config/service.env",
|
||||
"config/.template_info.env",
|
||||
"config/" + filenames::service_env,
|
||||
"config/" + filenames::template_info_env,
|
||||
"install.sh",
|
||||
"uninstall.sh"
|
||||
};
|
||||
@ -331,8 +331,8 @@
|
||||
// check TEMPLATE= line.
|
||||
std::map<std::string, std::string> all_env_vars;
|
||||
std::vector<std::string> env_files = {
|
||||
"config/service.env",
|
||||
"config/.template_info.env"
|
||||
"config/" + filenames::service_env,
|
||||
"config/" + filenames::template_info_env
|
||||
};
|
||||
for (const auto& file : env_files) {
|
||||
{ // load service.env from the service on this machine.
|
||||
|
@ -19,7 +19,7 @@ namespace localfile {
|
||||
// Try ~/.config/dropshell/dropshell.json
|
||||
std::string homedir = localpath::current_user_home();
|
||||
if (!homedir.empty()) {
|
||||
fs::path user_path = fs::path(homedir) / ".config" / "dropshell" / "dropshell.json";
|
||||
fs::path user_path = fs::path(homedir) / ".config" / "dropshell" / filenames::dropshell_json;
|
||||
return user_path.string();
|
||||
}
|
||||
return std::string();
|
||||
@ -27,18 +27,18 @@ namespace localfile {
|
||||
|
||||
std::string server_json(const std::string &server_name) {
|
||||
std::string serverpath = localpath::server(server_name);
|
||||
return (serverpath.empty() ? "" : (fs::path(serverpath) / "server.json").string());
|
||||
return (serverpath.empty() ? "" : (fs::path(serverpath) / filenames::server_json).string());
|
||||
}
|
||||
|
||||
std::string service_env(const std::string &server_name, const std::string &service_name) {
|
||||
std::string servicepath = localpath::service(server_name, service_name);
|
||||
return (servicepath.empty() ? "" : (fs::path(servicepath) / "service.env").string());
|
||||
return (servicepath.empty() ? "" : (fs::path(servicepath) / filenames::service_env).string());
|
||||
}
|
||||
|
||||
std::string template_info_env(const std::string &server_name, const std::string &service_name)
|
||||
{
|
||||
std::string servicepath = localpath::service(server_name, service_name);
|
||||
return (servicepath.empty() ? "" : (fs::path(servicepath) / ".template_info.env").string());
|
||||
return (servicepath.empty() ? "" : (fs::path(servicepath) / filenames::template_info_env).string());
|
||||
}
|
||||
|
||||
std::string template_example()
|
||||
@ -165,7 +165,7 @@ namespace localpath {
|
||||
|
||||
std::string remotefile::service_env(const std::string &service_name) const
|
||||
{
|
||||
return remotepath(mServer_name,mUser).service_config(service_name) + "/service.env";
|
||||
return remotepath(mServer_name,mUser).service_config(service_name) + "/" + filenames::service_env;
|
||||
}
|
||||
|
||||
|
||||
@ -218,12 +218,6 @@ namespace localpath {
|
||||
return (dsp.empty() ? "" : (dsp + "/agent"));
|
||||
}
|
||||
|
||||
// std::string remotepath::service_env(const std::string &service_name) const
|
||||
// {
|
||||
// std::string service_path = service_config(service_name);
|
||||
// return (service_path.empty() ? "" : (service_path + "/service.env"));
|
||||
// }
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// Utility functions
|
||||
|
@ -44,7 +44,13 @@ namespace dropshell {
|
||||
// |-- .template_info.env
|
||||
// |-- (...other config files for specific server&service...)
|
||||
|
||||
|
||||
namespace filenames {
|
||||
static const std::string template_info_env = ".template_info.env";
|
||||
static const std::string service_env = "service.env";
|
||||
static const std::string readme = "README.txt";
|
||||
static const std::string server_json = "server.json";
|
||||
static const std::string dropshell_json = "dropshell.json";
|
||||
} // namespace filenames.
|
||||
|
||||
namespace localfile {
|
||||
// ~/.config/dropshell/dropshell.json
|
||||
|
@ -54,13 +54,12 @@ bool execute_ssh_command(const sSSHInfo & ssh_info, const sCommand & remote_comm
|
||||
// class to hold a command to run on the remote server.
|
||||
class sCommand {
|
||||
public:
|
||||
sCommand(std::string directory_to_run_in, std::string command_to_run, const std::map<std::string, std::string> & env_vars, bool requires_root = false) :
|
||||
mDir(directory_to_run_in), mCmd(command_to_run), mVars(env_vars), mRequiresRoot(requires_root) {}
|
||||
sCommand(std::string directory_to_run_in, std::string command_to_run, const std::map<std::string, std::string> & env_vars) :
|
||||
mDir(directory_to_run_in), mCmd(command_to_run), mVars(env_vars) {}
|
||||
|
||||
std::string get_directory_to_run_in() const { return mDir; }
|
||||
std::string get_command_to_run() const { return mCmd; }
|
||||
const std::map<std::string, std::string>& get_env_vars() const { return mVars; }
|
||||
bool requires_root() const { return mRequiresRoot; }
|
||||
|
||||
void add_env_var(const std::string& key, const std::string& value) { mVars[key] = value; }
|
||||
|
||||
@ -72,7 +71,6 @@ class sCommand {
|
||||
std::string makesafecmd(std::string bb64path, const std::string& command) const;
|
||||
|
||||
private:
|
||||
bool mRequiresRoot;
|
||||
std::string mDir;
|
||||
std::string mCmd;
|
||||
std::map<std::string, std::string> mVars;
|
||||
|
Loading…
x
Reference in New Issue
Block a user