diff options
| author | Stefan Boberg <[email protected]> | 2025-10-15 09:51:52 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-10-15 09:51:52 +0200 |
| commit | e747932819e2a64a1396cfbc3422a9b61c9470dc (patch) | |
| tree | 1db1d13cf7fe873d71128a7879d269174f8eaf16 /src/zenserver/config/config.cpp | |
| parent | refactor builds cmd part3 (#573) (diff) | |
| download | zen-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.cpp | 152 |
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 |