aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/config/config.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2025-10-15 09:51:52 +0200
committerGitHub Enterprise <[email protected]>2025-10-15 09:51:52 +0200
commite747932819e2a64a1396cfbc3422a9b61c9470dc (patch)
tree1db1d13cf7fe873d71128a7879d269174f8eaf16 /src/zenserver/config/config.cpp
parentrefactor builds cmd part3 (#573) (diff)
downloadzen-e747932819e2a64a1396cfbc3422a9b61c9470dc.tar.xz
zen-e747932819e2a64a1396cfbc3422a9b61c9470dc.zip
restructured zenserver configuration (#575)
this breaks out the configuration logic to allow multiple applications to share common configuration and initialization logic whilst customizing chosen aspects of the process
Diffstat (limited to 'src/zenserver/config/config.cpp')
-rw-r--r--src/zenserver/config/config.cpp152
1 files changed, 103 insertions, 49 deletions
diff --git a/src/zenserver/config/config.cpp b/src/zenserver/config/config.cpp
index d044c61d5..70590b4e6 100644
--- a/src/zenserver/config/config.cpp
+++ b/src/zenserver/config/config.cpp
@@ -88,19 +88,21 @@ ReadAllCentralManifests(const std::filesystem::path& SystemRoot)
}
void
-ParseEnvVariables(ZenServerOptions& ServerOptions, const cxxopts::ParseResult& CmdLineResult)
+ZenServerConfiguratorBase::ParseEnvVariables(const cxxopts::ParseResult& CmdLineResult)
{
using namespace std::literals;
EnvironmentOptions Options;
- Options.AddOption("UE_ZEN_SENTRY_ALLOWPERSONALINFO"sv, ServerOptions.SentryConfig.AllowPII, "sentry-allow-personal-info"sv);
- Options.AddOption("UE_ZEN_SENTRY_DSN"sv, ServerOptions.SentryConfig.Dsn, "sentry-dsn"sv);
- Options.AddOption("UE_ZEN_SENTRY_ENVIRONMENT"sv, ServerOptions.SentryConfig.Environment, "sentry-environment"sv);
+ ZenServerConfig& ServerOptions = m_ServerOptions;
+ bool EnvEnableSentry = !ServerOptions.SentryConfig.Disable;
- bool EnvEnableSentry = !ServerOptions.SentryConfig.Disable;
- Options.AddOption("UE_ZEN_SENTRY_ENABLED"sv, EnvEnableSentry, "no-sentry"sv);
-
- Options.AddOption("UE_ZEN_SENTRY_DEBUG"sv, ServerOptions.SentryConfig.Debug, "sentry-debug"sv);
+ // clang-format off
+ Options.AddOption("UE_ZEN_SENTRY_ALLOWPERSONALINFO"sv, ServerOptions.SentryConfig.AllowPII, "sentry-allow-personal-info"sv);
+ Options.AddOption("UE_ZEN_SENTRY_DSN"sv, ServerOptions.SentryConfig.Dsn, "sentry-dsn"sv);
+ Options.AddOption("UE_ZEN_SENTRY_ENVIRONMENT"sv, ServerOptions.SentryConfig.Environment, "sentry-environment"sv);
+ Options.AddOption("UE_ZEN_SENTRY_ENABLED"sv, EnvEnableSentry, "no-sentry"sv);
+ Options.AddOption("UE_ZEN_SENTRY_DEBUG"sv, ServerOptions.SentryConfig.Debug, "sentry-debug"sv);
+ // clang-format on
Options.Parse(CmdLineResult);
@@ -111,10 +113,12 @@ ParseEnvVariables(ZenServerOptions& ServerOptions, const cxxopts::ParseResult& C
}
void
-AddServerConfigOptions(LuaConfig::Options& LuaOptions, ZenServerOptions& ServerOptions)
+ZenServerConfiguratorBase::AddCommonConfigOptions(LuaConfig::Options& LuaOptions)
{
using namespace std::literals;
+ ZenServerConfig& ServerOptions = m_ServerOptions;
+
// server
LuaOptions.AddOption("server.dedicated"sv, ServerOptions.IsDedicated, "dedicated"sv);
@@ -177,13 +181,14 @@ struct ZenServerCmdLineOptions
std::string ContentDir;
std::string DataDir;
std::string AbsLogFile;
+ std::string BaseSnapshotDir;
- void AddCliOptions(cxxopts::Options& options, ZenServerOptions& ServerOptions);
- void ApplyOptions(ZenServerOptions& ServerOptions);
+ void AddCliOptions(cxxopts::Options& options, ZenServerConfig& ServerOptions);
+ void ApplyOptions(cxxopts::Options& options, ZenServerConfig& ServerOptions);
};
void
-ZenServerCmdLineOptions::AddCliOptions(cxxopts::Options& options, ZenServerOptions& ServerOptions)
+ZenServerCmdLineOptions::AddCliOptions(cxxopts::Options& options, ZenServerConfig& ServerOptions)
{
const char* DefaultHttp = "asio";
@@ -209,6 +214,9 @@ ZenServerCmdLineOptions::AddCliOptions(cxxopts::Options& options, ZenServerOptio
options.add_options()("content-dir", "Frontend content directory", cxxopts::value<std::string>(ContentDir));
options.add_options()("config", "Path to Lua config file", cxxopts::value<std::string>(ConfigFile));
options.add_options()("write-config", "Path to output Lua config file", cxxopts::value<std::string>(OutputConfigFile));
+ options.add_options()("snapshot-dir",
+ "Specify a snapshot of server state to mirror into the persistence root at startup",
+ cxxopts::value<std::string>(BaseSnapshotDir));
options.add_options()("no-sentry",
"Disable Sentry crash handler",
@@ -227,6 +235,7 @@ ZenServerCmdLineOptions::AddCliOptions(cxxopts::Options& options, ZenServerOptio
options.add_options()("malloc",
"Configure memory allocator subsystem",
cxxopts::value(ServerOptions.MemoryOptions)->default_value("mimalloc"));
+ options.add_options()("corelimit", "Limit concurrency", cxxopts::value(ServerOptions.CoreLimit));
options.add_options()("powercycle",
"Exit immediately after initialization is complete",
cxxopts::value<bool>(ServerOptions.IsPowerCycle));
@@ -368,35 +377,55 @@ ZenServerCmdLineOptions::AddCliOptions(cxxopts::Options& options, ZenServerOptio
}
void
-ZenServerCmdLineOptions::ApplyOptions(ZenServerOptions& ServerOptions)
+ZenServerCmdLineOptions::ApplyOptions(cxxopts::Options& options, ZenServerConfig& ServerOptions)
+{
+ if (!BaseSnapshotDir.empty())
+ {
+ if (ServerOptions.DataDir.empty())
+ throw OptionParseException("'--snapshot-dir' requires '--data-dir'", options.help());
+
+ if (!IsDir(ServerOptions.BaseSnapshotDir))
+ throw std::runtime_error(fmt::format("'--snapshot-dir' ('{}') must be a directory", ServerOptions.BaseSnapshotDir));
+ }
+
+ ServerOptions.SystemRootDir = MakeSafeAbsolutePath(SystemRootDir);
+ ServerOptions.DataDir = MakeSafeAbsolutePath(DataDir);
+ ServerOptions.ContentDir = MakeSafeAbsolutePath(ContentDir);
+ ServerOptions.AbsLogFile = MakeSafeAbsolutePath(AbsLogFile);
+ ServerOptions.ConfigFile = MakeSafeAbsolutePath(ConfigFile);
+ ServerOptions.BaseSnapshotDir = MakeSafeAbsolutePath(BaseSnapshotDir);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+ZenServerConfiguratorBase::ZenServerConfiguratorBase(ZenServerConfig& BaseServerOptions) : m_ServerOptions(BaseServerOptions)
+{
+}
+
+ZenServerConfiguratorBase::~ZenServerConfiguratorBase()
{
- ServerOptions.SystemRootDir = MakeSafeAbsolutePath(SystemRootDir);
- ServerOptions.DataDir = MakeSafeAbsolutePath(DataDir);
- ServerOptions.ContentDir = MakeSafeAbsolutePath(ContentDir);
- ServerOptions.AbsLogFile = MakeSafeAbsolutePath(AbsLogFile);
- ServerOptions.ConfigFile = MakeSafeAbsolutePath(ConfigFile);
}
void
-ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
+ZenServerConfiguratorBase::Configure(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i)
{
if (i)
{
- ServerOptions.CommandLine.push_back(' ');
+ m_ServerOptions.CommandLine.push_back(' ');
}
- ServerOptions.CommandLine += argv[i];
+ m_ServerOptions.CommandLine += argv[i];
}
cxxopts::Options options("zenserver", "Zen Storage Server");
ZenServerCmdLineOptions BaseOptions;
- BaseOptions.AddCliOptions(options, ServerOptions);
+ BaseOptions.AddCliOptions(options, m_ServerOptions);
- ZenStorageServerCmdLineOptions StorageOptions;
- StorageOptions.AddCliOptions(options, ServerOptions);
+ // Add subclass' command line options
+ AddCliOptions(options);
try
{
@@ -426,18 +455,18 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
exit(0);
}
- if (!ServerOptions.HasTraceCommandlineOptions)
+ if (!m_ServerOptions.HasTraceCommandlineOptions)
{
// Apply any Lua settings if we don't have them set from the command line
- TraceConfigure(ServerOptions.TraceOptions);
+ TraceConfigure(m_ServerOptions.TraceOptions);
}
- if (ServerOptions.QuietConsole)
+ if (m_ServerOptions.QuietConsole)
{
bool HasExplicitConsoleLevel = false;
for (int i = 0; i < logging::level::LogLevelCount; ++i)
{
- if (ServerOptions.Loggers[i].find("console") != std::string::npos)
+ if (m_ServerOptions.Loggers[i].find("console") != std::string::npos)
{
HasExplicitConsoleLevel = true;
break;
@@ -446,7 +475,7 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
if (!HasExplicitConsoleLevel)
{
- std::string& WarnLoggers = ServerOptions.Loggers[logging::level::Warn];
+ std::string& WarnLoggers = m_ServerOptions.Loggers[logging::level::Warn];
if (!WarnLoggers.empty())
{
WarnLoggers += ",";
@@ -457,32 +486,29 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
for (int i = 0; i < logging::level::LogLevelCount; ++i)
{
- logging::ConfigureLogLevels(logging::level::LogLevel(i), ServerOptions.Loggers[i]);
+ logging::ConfigureLogLevels(logging::level::LogLevel(i), m_ServerOptions.Loggers[i]);
}
logging::RefreshLogLevels();
- BaseOptions.ApplyOptions(ServerOptions);
- StorageOptions.ApplyOptions(options, ServerOptions);
+ BaseOptions.ApplyOptions(options, m_ServerOptions);
+ ApplyOptions(options);
+
+ // Handle any environment variables
- ParseEnvVariables(ServerOptions, Result);
+ ParseEnvVariables(Result);
ZEN_TRACE_CPU("ConfigParse");
- if (!ServerOptions.ConfigFile.empty())
+ if (!m_ServerOptions.ConfigFile.empty())
{
- ParseConfigFile(ServerOptions.ConfigFile, ServerOptions, Result, BaseOptions.OutputConfigFile);
+ ParseConfigFile(m_ServerOptions.ConfigFile, Result, BaseOptions.OutputConfigFile);
}
else
{
- ParseConfigFile(ServerOptions.DataDir / "zen_cfg.lua", ServerOptions, Result, BaseOptions.OutputConfigFile);
+ ParseConfigFile(m_ServerOptions.DataDir / "zen_cfg.lua", Result, BaseOptions.OutputConfigFile);
}
- if (!ServerOptions.PluginsConfigFile.empty())
- {
- ParsePluginsConfigFile(ServerOptions.PluginsConfigFile, ServerOptions, ServerOptions.BasePort);
- }
-
- ValidateOptions(ServerOptions);
+ ValidateOptions(); // subclass validation
}
catch (const OptionParseException& e)
{
@@ -491,22 +517,50 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
throw;
}
- if (ServerOptions.SystemRootDir.empty())
+ if (m_ServerOptions.SystemRootDir.empty())
{
- ServerOptions.SystemRootDir = PickDefaultSystemRootDirectory();
+ m_ServerOptions.SystemRootDir = PickDefaultSystemRootDirectory();
}
- if (ServerOptions.DataDir.empty())
+ if (m_ServerOptions.DataDir.empty())
{
- ServerOptions.DataDir = PickDefaultStateDirectory(ServerOptions.SystemRootDir);
+ m_ServerOptions.DataDir = PickDefaultStateDirectory(m_ServerOptions.SystemRootDir);
}
- if (ServerOptions.AbsLogFile.empty())
+ if (m_ServerOptions.AbsLogFile.empty())
{
- ServerOptions.AbsLogFile = ServerOptions.DataDir / "logs" / "zenserver.log";
+ m_ServerOptions.AbsLogFile = m_ServerOptions.DataDir / "logs" / "zenserver.log";
}
- ServerOptions.HttpServerConfig.IsDedicatedServer = ServerOptions.IsDedicated;
+ m_ServerOptions.HttpServerConfig.IsDedicatedServer = m_ServerOptions.IsDedicated;
+}
+
+void
+ZenServerConfiguratorBase::ParseConfigFile(const std::filesystem::path& Path,
+ const cxxopts::ParseResult& CmdLineResult,
+ std::string_view OutputConfigFile)
+{
+ ZEN_TRACE_CPU("ParseConfigFile");
+
+ LuaConfig::Options LuaOptions;
+
+ AddCommonConfigOptions(LuaOptions);
+ AddConfigOptions(LuaOptions); // subclass options
+
+ LuaOptions.Parse(Path, CmdLineResult);
+
+ OnConfigFileParsed(LuaOptions); // subclass hook
+
+ if (!OutputConfigFile.empty())
+ {
+ ExtendableStringBuilder<512> ConfigStringBuilder;
+ LuaOptions.Print(ConfigStringBuilder, CmdLineResult);
+
+ BasicFile Output;
+ std::filesystem::path WritePath(MakeSafeAbsolutePath(OutputConfigFile));
+ Output.Open(WritePath, BasicFile::Mode::kTruncate);
+ Output.Write(ConfigStringBuilder.Data(), ConfigStringBuilder.Size(), 0);
+ }
}
} // namespace zen