aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/config.cpp
diff options
context:
space:
mode:
authorzousar <[email protected]>2025-06-24 16:26:29 -0600
committerzousar <[email protected]>2025-06-24 16:26:29 -0600
commitbb298631ba35a323827dda0b8cd6158e276b5f61 (patch)
tree7ba8db91c44ce83f2c518f80f80ab14910eefa6f /src/zenserver/config.cpp
parentChange to PutResult structure (diff)
parent5.6.14 (diff)
downloadzen-bb298631ba35a323827dda0b8cd6158e276b5f61.tar.xz
zen-bb298631ba35a323827dda0b8cd6158e276b5f61.zip
Merge branch 'main' into zs/put-overwrite-policy
Diffstat (limited to 'src/zenserver/config.cpp')
-rw-r--r--src/zenserver/config.cpp334
1 files changed, 297 insertions, 37 deletions
diff --git a/src/zenserver/config.cpp b/src/zenserver/config.cpp
index c8949f5fd..d53bedad0 100644
--- a/src/zenserver/config.cpp
+++ b/src/zenserver/config.cpp
@@ -15,12 +15,15 @@
#include <zencore/logging.h>
#include <zencore/string.h>
#include <zenhttp/zenhttp.h>
+#include <zenutil/commandlineoptions.h>
+#include <zenutil/environmentoptions.h>
ZEN_THIRD_PARTY_INCLUDES_START
#include <fmt/format.h>
#include <fmt/ranges.h>
#include <zencore/logging.h>
#include <cxxopts.hpp>
+#include <json11.hpp>
#include <sol/sol.hpp>
ZEN_THIRD_PARTY_INCLUDES_END
@@ -178,27 +181,6 @@ ParseBucketConfigs(std::span<std::string> Buckets)
return Cfg;
}
-static std::string
-MakeSafePath(const std::string_view Path)
-{
-#if ZEN_PLATFORM_WINDOWS
- if (Path.empty())
- {
- return std::string(Path);
- }
-
- std::string FixedPath(Path);
- std::replace(FixedPath.begin(), FixedPath.end(), '/', '\\');
- if (!FixedPath.starts_with("\\\\?\\"))
- {
- FixedPath.insert(0, "\\\\?\\");
- }
- return FixedPath;
-#else
- return std::string(Path);
-#endif
-};
-
class CachePolicyOption : public LuaConfig::OptionValue
{
public:
@@ -324,7 +306,7 @@ public:
std::string Name = Bucket.value().get_or("name", std::string("Default"));
std::string Directory = Bucket.value().get_or("directory", std::string());
- Value.Buckets.push_back({.Name = std::move(Name), .Directory = LuaConfig::MakeSafePath(Directory)});
+ Value.Buckets.push_back({.Name = std::move(Name), .Directory = MakeSafeAbsolutePath(Directory)});
}
}
}
@@ -332,6 +314,97 @@ public:
ZenObjectStoreConfig& Value;
};
+class ZenStructuredCacheBucketsConfigOption : public LuaConfig::OptionValue
+{
+public:
+ ZenStructuredCacheBucketsConfigOption(std::vector<std::pair<std::string, ZenStructuredCacheBucketConfig>>& Value) : Value(Value) {}
+ virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) override
+ {
+ if (Value.empty())
+ {
+ StringBuilder.Append("{}");
+ return;
+ }
+ LuaConfig::LuaContainerWriter Writer(StringBuilder, Indent);
+ for (const std::pair<std::string, ZenStructuredCacheBucketConfig>& Bucket : Value)
+ {
+ Writer.BeginContainer("");
+ {
+ Writer.WriteValue("name", Bucket.first);
+ const ZenStructuredCacheBucketConfig& BucketConfig = Bucket.second;
+
+ Writer.WriteValue("maxblocksize", fmt::format("{}", BucketConfig.MaxBlockSize));
+ Writer.BeginContainer("memlayer");
+ {
+ Writer.WriteValue("sizethreshold", fmt::format("{}", BucketConfig.MemCacheSizeThreshold));
+ }
+ Writer.EndContainer();
+
+ Writer.WriteValue("payloadalignment", fmt::format("{}", BucketConfig.PayloadAlignment));
+ Writer.WriteValue("largeobjectthreshold", fmt::format("{}", BucketConfig.PayloadAlignment));
+ }
+ Writer.EndContainer();
+ }
+ }
+ virtual void Parse(sol::object Object) override
+ {
+ if (sol::optional<sol::table> Buckets = Object.as<sol::table>())
+ {
+ for (const auto& Kv : Buckets.value())
+ {
+ if (sol::optional<sol::table> Bucket = Kv.second.as<sol::table>())
+ {
+ ZenStructuredCacheBucketConfig BucketConfig;
+ std::string Name = Kv.first.as<std::string>();
+ if (Name.empty())
+ {
+ throw zen::OptionParseException(fmt::format("cache bucket option must have a name."));
+ }
+
+ const uint64_t MaxBlockSize = Bucket.value().get_or("maxblocksize", BucketConfig.MaxBlockSize);
+ if (MaxBlockSize == 0)
+ {
+ throw zen::OptionParseException(
+ fmt::format("maxblocksize option for cache bucket '{}' is invalid. It must be non-zero.", Name));
+ }
+ BucketConfig.MaxBlockSize = MaxBlockSize;
+
+ if (sol::optional<sol::table> Memlayer = Bucket.value().get_or("memlayer", sol::table()))
+ {
+ const uint64_t MemCacheSizeThreshold = Bucket.value().get_or("sizethreshold", BucketConfig.MemCacheSizeThreshold);
+ if (MemCacheSizeThreshold == 0)
+ {
+ throw zen::OptionParseException(
+ fmt::format("memlayer.sizethreshold option for cache bucket '{}' is invalid. It must be non-zero.", Name));
+ }
+ BucketConfig.MemCacheSizeThreshold = Bucket.value().get_or("sizethreshold", BucketConfig.MemCacheSizeThreshold);
+ }
+
+ const uint32_t PayloadAlignment = Bucket.value().get_or("payloadalignment", BucketConfig.PayloadAlignment);
+ if (PayloadAlignment == 0 || !IsPow2(PayloadAlignment))
+ {
+ throw zen::OptionParseException(fmt::format(
+ "payloadalignment option for cache bucket '{}' is invalid. It needs to be non-zero and a power of two.",
+ Name));
+ }
+ BucketConfig.PayloadAlignment = PayloadAlignment;
+
+ const uint64_t LargeObjectThreshold = Bucket.value().get_or("largeobjectthreshold", BucketConfig.LargeObjectThreshold);
+ if (LargeObjectThreshold == 0)
+ {
+ throw zen::OptionParseException(
+ fmt::format("largeobjectthreshold option for cache bucket '{}' is invalid. It must be non-zero.", Name));
+ }
+ BucketConfig.LargeObjectThreshold = LargeObjectThreshold;
+
+ Value.push_back(std::make_pair(std::move(Name), BucketConfig));
+ }
+ }
+ }
+ }
+ std::vector<std::pair<std::string, ZenStructuredCacheBucketConfig>>& Value;
+};
+
std::shared_ptr<LuaConfig::OptionValue>
MakeOption(zen::UpstreamCachePolicy& Value)
{
@@ -350,6 +423,35 @@ MakeOption(zen::ZenObjectStoreConfig& Value)
return std::make_shared<ZenObjectStoreConfigOption>(Value);
};
+std::shared_ptr<LuaConfig::OptionValue>
+MakeOption(std::vector<std::pair<std::string, ZenStructuredCacheBucketConfig>>& Value)
+{
+ return std::make_shared<ZenStructuredCacheBucketsConfigOption>(Value);
+};
+
+void
+ParseEnvVariables(ZenServerOptions& ServerOptions, 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);
+
+ 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);
+
+ Options.Parse(CmdLineResult);
+
+ if (EnvEnableSentry != !ServerOptions.SentryConfig.Disable)
+ {
+ ServerOptions.SentryConfig.Disable = !EnvEnableSentry;
+ }
+}
+
void
ParseConfigFile(const std::filesystem::path& Path,
ZenServerOptions& ServerOptions,
@@ -363,12 +465,16 @@ ParseConfigFile(const std::filesystem::path& Path,
////// server
LuaOptions.AddOption("server.dedicated"sv, ServerOptions.IsDedicated, "dedicated"sv);
LuaOptions.AddOption("server.logid"sv, ServerOptions.LogId, "log-id"sv);
- LuaOptions.AddOption("server.sentry.disable"sv, ServerOptions.NoSentry, "no-sentry"sv);
- LuaOptions.AddOption("server.sentry.allowpersonalinfo"sv, ServerOptions.SentryAllowPII, "sentry-allow-personal-info"sv);
+ LuaOptions.AddOption("server.sentry.disable"sv, ServerOptions.SentryConfig.Disable, "no-sentry"sv);
+ LuaOptions.AddOption("server.sentry.allowpersonalinfo"sv, ServerOptions.SentryConfig.AllowPII, "sentry-allow-personal-info"sv);
+ LuaOptions.AddOption("server.sentry.dsn"sv, ServerOptions.SentryConfig.Dsn, "sentry-dsn"sv);
+ LuaOptions.AddOption("server.sentry.environment"sv, ServerOptions.SentryConfig.Environment, "sentry-environment"sv);
+ LuaOptions.AddOption("server.sentry.debug"sv, ServerOptions.SentryConfig.Debug, "sentry-debug"sv);
LuaOptions.AddOption("server.systemrootdir"sv, ServerOptions.SystemRootDir, "system-dir"sv);
LuaOptions.AddOption("server.datadir"sv, ServerOptions.DataDir, "data-dir"sv);
LuaOptions.AddOption("server.contentdir"sv, ServerOptions.ContentDir, "content-dir"sv);
LuaOptions.AddOption("server.abslog"sv, ServerOptions.AbsLogFile, "abslog"sv);
+ LuaOptions.AddOption("server.pluginsconfigfile"sv, ServerOptions.PluginsConfigFile, "plugins-config"sv);
LuaOptions.AddOption("server.debug"sv, ServerOptions.IsDebug, "debug"sv);
LuaOptions.AddOption("server.clean"sv, ServerOptions.IsCleanStart, "clean"sv);
LuaOptions.AddOption("server.noconsole"sv, ServerOptions.NoConsoleOutput, "quiet"sv);
@@ -377,6 +483,10 @@ ParseConfigFile(const std::filesystem::path& Path,
LuaOptions.AddOption("server.objectstore.enabled"sv, ServerOptions.ObjectStoreEnabled, "objectstore-enabled"sv);
LuaOptions.AddOption("server.objectstore.buckets"sv, ServerOptions.ObjectStoreConfig);
+ ////// buildsstore
+ LuaOptions.AddOption("server.buildstore.enabled"sv, ServerOptions.BuildStoreConfig.Enabled, "buildstore-enabled"sv);
+ LuaOptions.AddOption("server.buildstore.disksizelimit"sv, ServerOptions.BuildStoreConfig.MaxDiskSpaceLimit, "buildstore-disksizelimit");
+
////// network
LuaOptions.AddOption("network.httpserverclass"sv, ServerOptions.HttpServerConfig.ServerClass, "http"sv);
LuaOptions.AddOption("network.httpserverthreads"sv, ServerOptions.HttpServerConfig.ThreadCount, "http-threads"sv);
@@ -411,7 +521,7 @@ ParseConfigFile(const std::filesystem::path& Path,
LuaOptions.AddOption("cache.limitoverwrites"sv, ServerOptions.StructuredCacheConfig.LimitOverwrites, "cache-limit-overwrites"sv);
LuaOptions.AddOption("cache.memlayer.sizethreshold"sv,
- ServerOptions.StructuredCacheConfig.MemCacheSizeThreshold,
+ ServerOptions.StructuredCacheConfig.BucketConfig.MemCacheSizeThreshold,
"cache-memlayer-sizethreshold"sv);
LuaOptions.AddOption("cache.memlayer.targetfootprint"sv,
ServerOptions.StructuredCacheConfig.MemTargetFootprintBytes,
@@ -421,6 +531,19 @@ ParseConfigFile(const std::filesystem::path& Path,
"cache-memlayer-triminterval"sv);
LuaOptions.AddOption("cache.memlayer.maxage"sv, ServerOptions.StructuredCacheConfig.MemMaxAgeSeconds, "cache-memlayer-maxage"sv);
+ LuaOptions.AddOption("cache.bucket.maxblocksize"sv,
+ ServerOptions.StructuredCacheConfig.BucketConfig.MaxBlockSize,
+ "cache-bucket-maxblocksize"sv);
+ LuaOptions.AddOption("cache.bucket.memlayer.sizethreshold"sv,
+ ServerOptions.StructuredCacheConfig.BucketConfig.MemCacheSizeThreshold,
+ "cache-bucket-memlayer-sizethreshold"sv);
+ LuaOptions.AddOption("cache.bucket.payloadalignment"sv,
+ ServerOptions.StructuredCacheConfig.BucketConfig.PayloadAlignment,
+ "cache-bucket-payloadalignment"sv);
+ LuaOptions.AddOption("cache.bucket.largeobjectthreshold"sv,
+ ServerOptions.StructuredCacheConfig.BucketConfig.LargeObjectThreshold,
+ "cache-bucket-largeobjectthreshold"sv);
+
////// cache.upstream
LuaOptions.AddOption("cache.upstream.policy"sv, ServerOptions.UpstreamCacheConfig.CachePolicy, "upstream-cache-policy"sv);
LuaOptions.AddOption("cache.upstream.upstreamthreadcount"sv,
@@ -493,6 +616,9 @@ ParseConfigFile(const std::filesystem::path& Path,
LuaOptions.AddOption("gc.projectstore.duration.seconds"sv,
ServerOptions.GcConfig.ProjectStore.MaxDurationSeconds,
"gc-projectstore-duration-seconds");
+ LuaOptions.AddOption("gc.buildstore.duration.seconds"sv,
+ ServerOptions.GcConfig.BuildStore.MaxDurationSeconds,
+ "gc-buildstore-duration-seconds");
////// security
LuaOptions.AddOption("security.encryptionaeskey"sv, ServerOptions.EncryptionKey, "encryption-aes-key"sv);
@@ -505,6 +631,8 @@ ParseConfigFile(const std::filesystem::path& Path,
ServerOptions.WorksSpacesConfig.AllowConfigurationChanges,
"workspaces-allow-changes"sv);
+ LuaOptions.AddOption("cache.buckets"sv, ServerOptions.StructuredCacheConfig.PerBucketConfigs, "cache.buckets"sv);
+
LuaOptions.Parse(Path, CmdLineResult);
// These have special command line processing so we make sure we export them if they were configured on command line
@@ -516,10 +644,14 @@ ParseConfigFile(const std::filesystem::path& Path,
{
LuaOptions.Touch("server.objectstore.buckets"sv);
}
+ if (!ServerOptions.StructuredCacheConfig.PerBucketConfigs.empty())
+ {
+ LuaOptions.Touch("cache.buckets"sv);
+ }
if (!OutputConfigFile.empty())
{
- std::filesystem::path WritePath(MakeSafePath(OutputConfigFile));
+ std::filesystem::path WritePath(MakeSafeAbsolutePath(OutputConfigFile));
zen::ExtendableStringBuilder<512> ConfigStringBuilder;
LuaOptions.Print(ConfigStringBuilder, CmdLineResult);
zen::BasicFile Output;
@@ -529,6 +661,68 @@ ParseConfigFile(const std::filesystem::path& Path,
}
void
+ParsePluginsConfigFile(const std::filesystem::path& Path, ZenServerOptions& ServerOptions, int BasePort)
+{
+ using namespace std::literals;
+
+ IoBuffer Body = IoBufferBuilder::MakeFromFile(Path);
+ std::string JsonText(reinterpret_cast<const char*>(Body.GetData()), Body.GetSize());
+ std::string JsonError;
+ json11::Json PluginsInfo = json11::Json::parse(JsonText, JsonError);
+ if (!JsonError.empty())
+ {
+ ZEN_WARN("failed parsing plugins config file '{}'. Reason: '{}'", Path, JsonError);
+ return;
+ }
+ for (const json11::Json& PluginInfo : PluginsInfo.array_items())
+ {
+ if (!PluginInfo.is_object())
+ {
+ ZEN_WARN("the json file '{}' does not contain a valid plugin definition, object expected, got '{}'", Path, PluginInfo.dump());
+ continue;
+ }
+
+ HttpServerPluginConfig Config = {};
+
+ bool bNeedsPort = true;
+
+ for (const std::pair<const std::string, json11::Json>& Items : PluginInfo.object_items())
+ {
+ if (!Items.second.is_string())
+ {
+ ZEN_WARN("the json file '{}' does not contain a valid plugins definition, string expected, got '{}'",
+ Path,
+ Items.second.dump());
+ continue;
+ }
+
+ const std::string& Name = Items.first;
+ const std::string& Value = Items.second.string_value();
+
+ if (Name == "name"sv)
+ Config.PluginName = Value;
+ else
+ {
+ Config.PluginOptions.push_back({Name, Value});
+
+ if (Name == "port"sv)
+ {
+ bNeedsPort = false;
+ }
+ }
+ }
+
+ // add a default base port in case if json config didn't provide one
+ if (bNeedsPort)
+ {
+ Config.PluginOptions.push_back({"port", std::to_string(BasePort)});
+ }
+
+ ServerOptions.HttpServerConfig.PluginConfigs.push_back(Config);
+ }
+}
+
+void
ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
{
const char* DefaultHttp = "asio";
@@ -560,6 +754,7 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
std::string ContentDir;
std::string AbsLogFile;
std::string ConfigFile;
+ std::string PluginsConfigFile;
std::string OutputConfigFile;
std::string BaseSnapshotDir;
@@ -587,13 +782,19 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
"Exit immediately after initialization is complete",
cxxopts::value<bool>(ServerOptions.IsPowerCycle));
options.add_options()("config", "Path to Lua config file", cxxopts::value<std::string>(ConfigFile));
+ options.add_options()("plugins-config", "Path to plugins config file", cxxopts::value<std::string>(PluginsConfigFile));
options.add_options()("write-config", "Path to output Lua config file", cxxopts::value<std::string>(OutputConfigFile));
options.add_options()("no-sentry",
"Disable Sentry crash handler",
- cxxopts::value<bool>(ServerOptions.NoSentry)->default_value("false"));
+ cxxopts::value<bool>(ServerOptions.SentryConfig.Disable)->default_value("false"));
options.add_options()("sentry-allow-personal-info",
"Allow personally identifiable information in sentry crash reports",
- cxxopts::value<bool>(ServerOptions.SentryAllowPII)->default_value("false"));
+ cxxopts::value<bool>(ServerOptions.SentryConfig.AllowPII)->default_value("false"));
+ options.add_options()("sentry-dsn", "Sentry DSN to send events to", cxxopts::value<std::string>(ServerOptions.SentryConfig.Dsn));
+ options.add_options()("sentry-environment", "Sentry environment", cxxopts::value<std::string>(ServerOptions.SentryConfig.Environment));
+ options.add_options()("sentry-debug",
+ "Enable debug mode for Sentry",
+ cxxopts::value<bool>(ServerOptions.SentryConfig.Debug)->default_value("false"));
options.add_options()("detach",
"Indicate whether zenserver should detach from parent process group",
cxxopts::value<bool>(ServerOptions.Detach)->default_value("true"));
@@ -871,8 +1072,9 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
"cache",
"",
"cache-memlayer-sizethreshold",
- "The largest size of a cache entry that may be cached in memory. Default set to 1024 (1 Kb). Set to 0 to disable memory caching.",
- cxxopts::value<uint64_t>(ServerOptions.StructuredCacheConfig.MemCacheSizeThreshold)->default_value("1024"),
+ "The largest size of a cache entry that may be cached in memory. Default set to 1024 (1 Kb). Set to 0 to disable memory caching. "
+ "Obsolete, replaced by `--cache-bucket-memlayer-sizethreshold`",
+ cxxopts::value<uint64_t>(ServerOptions.StructuredCacheConfig.BucketConfig.MemCacheSizeThreshold)->default_value("1024"),
"");
options.add_option("cache",
@@ -896,6 +1098,36 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
cxxopts::value<uint64_t>(ServerOptions.StructuredCacheConfig.MemMaxAgeSeconds)->default_value("86400"),
"");
+ options.add_option("cache",
+ "",
+ "cache-bucket-maxblocksize",
+ "Max size of cache bucket blocks. Default set to 1073741824 (1GB).",
+ cxxopts::value<uint64_t>(ServerOptions.StructuredCacheConfig.BucketConfig.MaxBlockSize)->default_value("1073741824"),
+ "");
+
+ options.add_option("cache",
+ "",
+ "cache-bucket-payloadalignment",
+ "Payload alignement for cache bucket blocks. Default set to 16.",
+ cxxopts::value<uint32_t>(ServerOptions.StructuredCacheConfig.BucketConfig.PayloadAlignment)->default_value("16"),
+ "");
+
+ options.add_option(
+ "cache",
+ "",
+ "cache-bucket-largeobjectthreshold",
+ "Threshold for storing cache bucket values as loose files. Default set to 131072 (128 KB).",
+ cxxopts::value<uint64_t>(ServerOptions.StructuredCacheConfig.BucketConfig.LargeObjectThreshold)->default_value("131072"),
+ "");
+
+ options.add_option(
+ "cache",
+ "",
+ "cache-bucket-memlayer-sizethreshold",
+ "The largest size of a cache entry that may be cached in memory. Default set to 1024 (1 Kb). Set to 0 to disable memory caching.",
+ cxxopts::value<uint64_t>(ServerOptions.StructuredCacheConfig.BucketConfig.MemCacheSizeThreshold)->default_value("1024"),
+ "");
+
options.add_option("gc",
"",
"gc-cache-attachment-store",
@@ -968,6 +1200,13 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
options.add_option("gc",
"",
+ "gc-buildstore-duration-seconds",
+ "Max duration in seconds before build store entries get evicted. Default set to 604800 (1 week)",
+ cxxopts::value<int32_t>(ServerOptions.GcConfig.BuildStore.MaxDurationSeconds)->default_value("604800"),
+ "");
+
+ options.add_option("gc",
+ "",
"disk-reserve-size",
"Size of gc disk reserve in bytes. Default set to 268435456 (256 Mb). Set to zero to disable.",
cxxopts::value<uint64_t>(ServerOptions.GcConfig.DiskReserveSize)->default_value("268435456"),
@@ -1039,6 +1278,19 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
cxxopts::value<std::vector<std::string>>(BucketConfigs),
"");
+ options.add_option("buildstore",
+ "",
+ "buildstore-enabled",
+ "Whether the builds store is enabled or not.",
+ cxxopts::value<bool>(ServerOptions.BuildStoreConfig.Enabled)->default_value("false"),
+ "");
+ options.add_option("buildstore",
+ "",
+ "buildstore-disksizelimit",
+ "Max number of bytes before build store entries get evicted. Default set to 1099511627776 (1TB week)",
+ cxxopts::value<uint64_t>(ServerOptions.BuildStoreConfig.MaxDiskSpaceLimit)->default_value("1099511627776"),
+ "");
+
options.add_option("stats",
"",
"statsd",
@@ -1091,12 +1343,13 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
}
logging::RefreshLogLevels();
- ServerOptions.SystemRootDir = MakeSafePath(SystemRootDir);
- ServerOptions.DataDir = MakeSafePath(DataDir);
- ServerOptions.BaseSnapshotDir = MakeSafePath(BaseSnapshotDir);
- ServerOptions.ContentDir = MakeSafePath(ContentDir);
- ServerOptions.AbsLogFile = MakeSafePath(AbsLogFile);
- ServerOptions.ConfigFile = MakeSafePath(ConfigFile);
+ ServerOptions.SystemRootDir = MakeSafeAbsolutePath(SystemRootDir);
+ ServerOptions.DataDir = MakeSafeAbsolutePath(DataDir);
+ ServerOptions.BaseSnapshotDir = MakeSafeAbsolutePath(BaseSnapshotDir);
+ ServerOptions.ContentDir = MakeSafeAbsolutePath(ContentDir);
+ ServerOptions.AbsLogFile = MakeSafeAbsolutePath(AbsLogFile);
+ ServerOptions.ConfigFile = MakeSafeAbsolutePath(ConfigFile);
+ ServerOptions.PluginsConfigFile = MakeSafeAbsolutePath(PluginsConfigFile);
ServerOptions.UpstreamCacheConfig.CachePolicy = ParseUpstreamCachePolicy(UpstreamCachePolicyOptions);
if (!BaseSnapshotDir.empty())
@@ -1104,7 +1357,7 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
if (DataDir.empty())
throw zen::OptionParseException("You must explicitly specify a data directory when specifying a base snapshot");
- if (!std::filesystem::is_directory(ServerOptions.BaseSnapshotDir))
+ if (!IsDir(ServerOptions.BaseSnapshotDir))
throw OptionParseException(fmt::format("Snapshot directory must be a directory: '{}", BaseSnapshotDir));
}
@@ -1121,6 +1374,8 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
ServerOptions.ObjectStoreConfig = ParseBucketConfigs(BucketConfigs);
+ ParseEnvVariables(ServerOptions, Result);
+
if (!ServerOptions.ConfigFile.empty())
{
ParseConfigFile(ServerOptions.ConfigFile, ServerOptions, Result, OutputConfigFile);
@@ -1130,6 +1385,11 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
ParseConfigFile(ServerOptions.DataDir / "zen_cfg.lua", ServerOptions, Result, OutputConfigFile);
}
+ if (!ServerOptions.PluginsConfigFile.empty())
+ {
+ ParsePluginsConfigFile(ServerOptions.PluginsConfigFile, ServerOptions, ServerOptions.BasePort);
+ }
+
ValidateOptions(ServerOptions);
}
catch (const zen::OptionParseException& e)