Add overrides.env support for per-location service env overrides
All checks were successful
Build-Test-Publish / build (linux/amd64) (push) Successful in 48s
Build-Test-Publish / build (linux/arm64) (push) Successful in 3m44s

This commit is contained in:
j
2026-03-30 08:04:23 +13:00
parent bf9cdeccc7
commit 735e2f083a
7 changed files with 169 additions and 3 deletions

View File

@@ -8,7 +8,9 @@
#include "templates.hpp"
#include <unistd.h>
#include <termios.h>
#include <cstring>
#include <fstream>
#include <iostream>
#include <sstream>
#include <filesystem>
@@ -32,12 +34,13 @@ struct EditCommandRegister {
false, // requires_install
0, // min_args (after command)
2, // max_args (after command)
"edit [SERVER] [SERVICE]",
"Edit dropshell, server or service configuration",
"edit [SERVER] [SERVICE] | edit override",
"Edit dropshell, server, service, or override configuration",
// heredoc
R"(
Edit dropshell, server or service configuration.
edit edit the dropshell config.
edit override edit the overrides.env for a server location.
edit <server> edit the server config.
edit <server> <service> edit the service config.
)"
@@ -241,12 +244,70 @@ int edit_service_config(const std::string &server, const std::string &service)
return 0;
}
// ------------------------------------------------------------------------------------------------
// edit override
// ------------------------------------------------------------------------------------------------
int edit_override()
{
auto paths = gConfig().get_local_server_definition_paths();
if (paths.empty()) {
error << "No server definition paths configured." << std::endl;
return 1;
}
std::string chosen_path;
if (paths.size() == 1) {
chosen_path = paths[0];
} else {
// Multiple paths - ask user to choose with single keypress
info << "Multiple server locations found. Choose one:" << std::endl;
for (size_t i = 0; i < paths.size() && i < 9; ++i)
info << " " << (i + 1) << ") " << paths[i] << std::endl;
info << "Enter choice [1-" << std::min(paths.size(), (size_t)9) << "]: " << std::flush;
// Read single keypress
struct termios oldt, newt;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
int ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
info << (char)ch << std::endl;
int idx = ch - '1';
if (idx < 0 || idx >= (int)paths.size()) {
error << "Invalid choice." << std::endl;
return 1;
}
chosen_path = paths[idx];
}
std::string override_file = (std::filesystem::path(chosen_path) / filenames::overrides_env).string();
// Create with comment header if it doesn't exist
if (!std::filesystem::exists(override_file)) {
std::ofstream f(override_file);
f << "# Overrides for all services in this server location." << std::endl;
f << "# Variables set here will be forced into every service.env" << std::endl;
f << "# during create-service and install." << std::endl;
f << "#" << std::endl;
f << "# Format is the same as service.env:" << std::endl;
f << "# VARIABLE_NAME=\"value\"" << std::endl;
f << std::endl;
info << "Created new overrides file: " << override_file << std::endl;
}
return edit_file(override_file, true) ? 0 : 1;
}
// ------------------------------------------------------------------------------------------------
// edit command handler
// ------------------------------------------------------------------------------------------------
int edit_handler(const CommandContext& ctx) {
// edit dropshell config
if (ctx.args.size() < 1)
if (ctx.args.size() < 1)
{
if (ctx.command=="create-config")
{
@@ -258,6 +319,10 @@ int edit_handler(const CommandContext& ctx) {
return edit_config();
}
// edit override - check before server/service dispatch
if (safearg(ctx.args, 0) == "override")
return edit_override();
// edit server config
if (ctx.args.size() < 2) {
edit_server(safearg(ctx.args,0));