This commit is contained in:
j
2025-12-30 09:04:06 +13:00
parent 30fa728f96
commit 0917e1e3f3
5 changed files with 130 additions and 14 deletions

View File

@@ -5,6 +5,7 @@
#include <libassert/assert.hpp> #include <libassert/assert.hpp>
#include "utils/utils.hpp" #include "utils/utils.hpp"
#include "utils/service_env_validator.hpp"
#include "services.hpp" #include "services.hpp"
#include <fstream> #include <fstream>
@@ -156,14 +157,6 @@ namespace dropshell
// copy the template config files to the service directory // copy the template config files to the service directory
recursive_copy(tinfo.local_template_path() / "config", service_dir); recursive_copy(tinfo.local_template_path() / "config", service_dir);
// append TEMPLATE to the service.env file
std::string service_env_file = localfile::service_env(server_name, service_name);
ASSERT(std::filesystem::exists(service_env_file),"service.env not found: "+ service_env_file);
std::ofstream ofs(service_env_file, std::ios::app);
ofs << std::endl << "# TEMPLATE set by dropshell on creation. Important this does not change." << std::endl;
ofs << "TEMPLATE=\"" << template_name <<"\"" << std::endl;
ofs.close();
// modify the SSH_USER to be nice. // modify the SSH_USER to be nice.
// everything is created, so we can get the service info. // everything is created, so we can get the service info.
LocalServiceInfo service_info = get_service_info(server_name, service_name); LocalServiceInfo service_info = get_service_info(server_name, service_name);
@@ -214,6 +207,17 @@ namespace dropshell
service_env_file_out.close(); service_env_file_out.close();
} }
// set TEMPLATE in service.env (removes any existing definition first)
if (!set_env_variable(
localfile::service_env(server_name, service_name),
"TEMPLATE",
template_name,
"TEMPLATE set by dropshell on creation. Important this does not change."))
{
error << "Failed to set TEMPLATE in service.env" << std::endl;
return false;
}
// check docker. // check docker.
if (service_info.requires_docker) if (service_info.requires_docker)
{ {

View File

@@ -2,7 +2,7 @@
#include "config.hpp" #include "config.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
#include "utils/directories.hpp" #include "utils/directories.hpp"
#include "utils/env_validator.hpp" #include "utils/service_env_validator.hpp"
#include "shared_commands.hpp" #include "shared_commands.hpp"
#include "services.hpp" #include "services.hpp"
#include "templates.hpp" #include "templates.hpp"

View File

@@ -9,7 +9,7 @@
#include "autogen/_agent-remote.hpp" #include "autogen/_agent-remote.hpp"
#include "services.hpp" #include "services.hpp"
#include "utils/output.hpp" #include "utils/output.hpp"
#include "utils/env_validator.hpp" #include "utils/service_env_validator.hpp"
#include <fstream> #include <fstream>
#include <unistd.h> #include <unistd.h>

View File

@@ -1,4 +1,4 @@
#include "env_validator.hpp" #include "service_env_validator.hpp"
#include "envmanager.hpp" #include "envmanager.hpp"
#include "ordered_env.hpp" #include "ordered_env.hpp"
#include "utils.hpp" #include "utils.hpp"
@@ -157,4 +157,96 @@ bool validate_and_fix_service_env(
return false; return false;
} }
bool set_env_variable(
const std::string& env_file_path,
const std::string& var_name,
const std::string& var_value,
const std::string& comment
) {
// Read existing file contents
std::vector<std::string> lines;
if (std::filesystem::exists(env_file_path)) {
std::ifstream infile(env_file_path);
if (!infile.is_open()) {
error << "Failed to open env file for reading: " << env_file_path << std::endl;
return false;
}
std::string line;
while (std::getline(infile, line)) {
lines.push_back(line);
}
infile.close();
}
// Build the comment line we're looking for (if comment provided)
std::string comment_line;
if (!comment.empty()) {
comment_line = "# " + comment;
}
// Build the pattern to match variable assignment: VAR_NAME= at start of line
std::string var_pattern = var_name + "=";
// Filter out existing variable definition and matching comment
std::vector<std::string> filtered_lines;
for (size_t i = 0; i < lines.size(); ++i) {
const std::string& line = lines[i];
std::string trimmed = trim(line);
// Check if this line is the exact comment we want to add
if (!comment_line.empty() && trimmed == comment_line) {
// Skip this comment line
continue;
}
// Check if this line defines our variable
if (!trimmed.empty() && trimmed[0] != '#') {
size_t eq_pos = trimmed.find('=');
if (eq_pos != std::string::npos) {
std::string key = trim(trimmed.substr(0, eq_pos));
if (key == var_name) {
// Skip this variable definition
continue;
}
}
}
filtered_lines.push_back(line);
}
// Remove trailing blank lines so we can control spacing
while (!filtered_lines.empty() && trim(filtered_lines.back()).empty()) {
filtered_lines.pop_back();
}
// Add exactly one blank line before our new content (if file is not empty)
if (!filtered_lines.empty()) {
filtered_lines.push_back("");
}
// Add the comment if provided
if (!comment_line.empty()) {
filtered_lines.push_back(comment_line);
}
// Add the variable assignment
filtered_lines.push_back(var_name + "=\"" + var_value + "\"");
// Write the file back
std::ofstream outfile(env_file_path);
if (!outfile.is_open()) {
error << "Failed to open env file for writing: " << env_file_path << std::endl;
return false;
}
for (const auto& l : filtered_lines) {
outfile << l << std::endl;
}
outfile.close();
return true;
}
} // namespace dropshell } // namespace dropshell

View File

@@ -1,5 +1,5 @@
#ifndef ENV_VALIDATOR_HPP #ifndef SERVICE_ENV_VALIDATOR_HPP
#define ENV_VALIDATOR_HPP #define SERVICE_ENV_VALIDATOR_HPP
#include <string> #include <string>
#include <vector> #include <vector>
@@ -24,6 +24,26 @@ bool validate_and_fix_service_env(
const std::string& template_info_env_path = "" const std::string& template_info_env_path = ""
); );
// Sets or updates a variable in an env file with an optional comment.
// - If the variable already exists, removes that line
// - If the comment already exists (exact match), removes that line too
// - Adds a single blank line, then the comment (if provided), then the variable assignment
// - The variable value is automatically quoted
//
// Parameters:
// env_file_path: Full path to the .env file
// var_name: Name of the variable to set
// var_value: Value to assign (will be quoted)
// comment: Optional comment to place before the variable (without # prefix)
//
// Returns true on success, false on failure
bool set_env_variable(
const std::string& env_file_path,
const std::string& var_name,
const std::string& var_value,
const std::string& comment = ""
);
} // namespace dropshell } // namespace dropshell
#endif // ENV_VALIDATOR_HPP #endif // SERVICE_ENV_VALIDATOR_HPP