aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/config.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2025-10-13 16:52:19 +0200
committerGitHub Enterprise <[email protected]>2025-10-13 16:52:19 +0200
commit61a0439e0257766b5b4bed163db2acce7dadde64 (patch)
tree518a235e070a5d70458e3704a2c296da7bad826f /src/zenserver/config.cpp
parentextract storage server into separate source files (#569) (diff)
downloadzen-61a0439e0257766b5b4bed163db2acce7dadde64.tar.xz
zen-61a0439e0257766b5b4bed163db2acce7dadde64.zip
split storage config from base config (#570)
this change splits the configuration logic into a base part and a storage server part manually tested with shared server config file
Diffstat (limited to 'src/zenserver/config.cpp')
-rw-r--r--src/zenserver/config.cpp1131
1 files changed, 82 insertions, 1049 deletions
diff --git a/src/zenserver/config.cpp b/src/zenserver/config.cpp
index ce3a70184..8ee50cee2 100644
--- a/src/zenserver/config.cpp
+++ b/src/zenserver/config.cpp
@@ -2,6 +2,8 @@
#include "config.h"
+#include "storageconfig.h"
+
#include "config/luaconfig.h"
#include "diag/logging.h"
@@ -9,23 +11,17 @@
#include <zencore/compactbinarybuilder.h>
#include <zencore/compactbinaryutil.h>
#include <zencore/compactbinaryvalidation.h>
-#include <zencore/crypto.h>
#include <zencore/except.h>
#include <zencore/fmtutils.h>
#include <zencore/iobuffer.h>
#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
#if ZEN_PLATFORM_WINDOWS
@@ -34,9 +30,6 @@ ZEN_THIRD_PARTY_INCLUDES_END
# include <unistd.h>
#endif
-#include <unordered_map>
-#include <unordered_set>
-
namespace zen {
std::filesystem::path
@@ -95,352 +88,7 @@ ReadAllCentralManifests(const std::filesystem::path& SystemRoot)
}
void
-ValidateOptions(ZenStorageServerOptions& ServerOptions)
-{
- if (ServerOptions.EncryptionKey.empty() == false)
- {
- const auto Key = AesKey256Bit::FromString(ServerOptions.EncryptionKey);
-
- if (Key.IsValid() == false)
- {
- throw OptionParseException(fmt::format("'--encryption-aes-key' ('{}') is malformed", ServerOptions.EncryptionKey), {});
- }
- }
-
- if (ServerOptions.EncryptionIV.empty() == false)
- {
- const auto IV = AesIV128Bit::FromString(ServerOptions.EncryptionIV);
-
- if (IV.IsValid() == false)
- {
- throw OptionParseException(fmt::format("'--encryption-aes-iv' ('{}') is malformed", ServerOptions.EncryptionIV), {});
- }
- }
- if (ServerOptions.HttpServerConfig.ForceLoopback && ServerOptions.IsDedicated)
- {
- throw OptionParseException("'--dedicated' conflicts with '--http-forceloopback'", {});
- }
- if (ServerOptions.GcConfig.AttachmentPassCount > ZenGcConfig::GcMaxAttachmentPassCount)
- {
- throw OptionParseException(fmt::format("'--gc-attachment-passes' ('{}') is invalid, maximum is {}.",
- ServerOptions.GcConfig.AttachmentPassCount,
- ZenGcConfig::GcMaxAttachmentPassCount),
- {});
- }
- if (ServerOptions.GcConfig.UseGCV2 == false)
- {
- ZEN_WARN("'--gc-v2=false' is deprecated, reverting to '--gc-v2=true'");
- ServerOptions.GcConfig.UseGCV2 = true;
- }
-}
-
-UpstreamCachePolicy
-ParseUpstreamCachePolicy(std::string_view Options)
-{
- if (Options == "readonly")
- {
- return UpstreamCachePolicy::Read;
- }
- else if (Options == "writeonly")
- {
- return UpstreamCachePolicy::Write;
- }
- else if (Options == "disabled")
- {
- return UpstreamCachePolicy::Disabled;
- }
- else
- {
- return UpstreamCachePolicy::ReadWrite;
- }
-}
-
-ZenObjectStoreConfig
-ParseBucketConfigs(std::span<std::string> Buckets)
-{
- using namespace std::literals;
-
- ZenObjectStoreConfig Cfg;
-
- // split bucket args in the form of "{BucketName};{LocalPath}"
- for (std::string_view Bucket : Buckets)
- {
- ZenObjectStoreConfig::BucketConfig NewBucket;
-
- if (auto Idx = Bucket.find_first_of(";"); Idx != std::string_view::npos)
- {
- NewBucket.Name = Bucket.substr(0, Idx);
- NewBucket.Directory = Bucket.substr(Idx + 1);
- }
- else
- {
- NewBucket.Name = Bucket;
- }
-
- Cfg.Buckets.push_back(std::move(NewBucket));
- }
-
- return Cfg;
-}
-
-class CachePolicyOption : public LuaConfig::OptionValue
-{
-public:
- CachePolicyOption(UpstreamCachePolicy& Value) : Value(Value) {}
- virtual void Print(std::string_view, StringBuilderBase& StringBuilder) override
- {
- switch (Value)
- {
- case UpstreamCachePolicy::Read:
- StringBuilder.Append("readonly");
- break;
- case UpstreamCachePolicy::Write:
- StringBuilder.Append("writeonly");
- break;
- case UpstreamCachePolicy::Disabled:
- StringBuilder.Append("disabled");
- break;
- case UpstreamCachePolicy::ReadWrite:
- StringBuilder.Append("readwrite");
- break;
- default:
- ZEN_ASSERT(false);
- }
- }
- virtual void Parse(sol::object Object) override
- {
- std::string PolicyString = Object.as<std::string>();
- if (PolicyString == "readonly")
- {
- Value = UpstreamCachePolicy::Read;
- }
- else if (PolicyString == "writeonly")
- {
- Value = UpstreamCachePolicy::Write;
- }
- else if (PolicyString == "disabled")
- {
- Value = UpstreamCachePolicy::Disabled;
- }
- else if (PolicyString == "readwrite")
- {
- Value = UpstreamCachePolicy::ReadWrite;
- }
- }
- UpstreamCachePolicy& Value;
-};
-
-class ZenAuthConfigOption : public LuaConfig::OptionValue
-{
-public:
- ZenAuthConfigOption(ZenAuthConfig& Value) : Value(Value) {}
- virtual void Print(std::string_view Indent, StringBuilderBase& StringBuilder) override
- {
- if (Value.OpenIdProviders.empty())
- {
- StringBuilder.Append("{}");
- return;
- }
- LuaConfig::LuaContainerWriter Writer(StringBuilder, Indent);
- for (const ZenOpenIdProviderConfig& Config : Value.OpenIdProviders)
- {
- Writer.BeginContainer("");
- {
- Writer.WriteValue("name", Config.Name);
- Writer.WriteValue("url", Config.Url);
- Writer.WriteValue("clientid", Config.ClientId);
- }
- Writer.EndContainer();
- }
- }
- virtual void Parse(sol::object Object) override
- {
- if (sol::optional<sol::table> OpenIdProviders = Object.as<sol::table>())
- {
- for (const auto& Kv : OpenIdProviders.value())
- {
- if (sol::optional<sol::table> OpenIdProvider = Kv.second.as<sol::table>())
- {
- std::string Name = OpenIdProvider.value().get_or("name", std::string("Default"));
- std::string Url = OpenIdProvider.value().get_or("url", std::string());
- std::string ClientId = OpenIdProvider.value().get_or("clientid", std::string());
-
- Value.OpenIdProviders.push_back({.Name = std::move(Name), .Url = std::move(Url), .ClientId = std::move(ClientId)});
- }
- }
- }
- }
- ZenAuthConfig& Value;
-};
-
-class ZenObjectStoreConfigOption : public LuaConfig::OptionValue
-{
-public:
- ZenObjectStoreConfigOption(ZenObjectStoreConfig& Value) : Value(Value) {}
- virtual void Print(std::string_view Indent, StringBuilderBase& StringBuilder) override
- {
- if (Value.Buckets.empty())
- {
- StringBuilder.Append("{}");
- return;
- }
- LuaConfig::LuaContainerWriter Writer(StringBuilder, Indent);
- for (const ZenObjectStoreConfig::BucketConfig& Config : Value.Buckets)
- {
- Writer.BeginContainer("");
- {
- Writer.WriteValue("name", Config.Name);
- std::string Directory = Config.Directory.string();
- LuaConfig::EscapeBackslash(Directory);
- Writer.WriteValue("directory", Directory);
- }
- 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>())
- {
- 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 = MakeSafeAbsolutePath(Directory)});
- }
- }
- }
- }
- 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, 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.WriteValue("limitoverwrites", fmt::format("{}", BucketConfig.LimitOverwrites));
- }
- 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 OptionParseException("Cache bucket option must have a name.", {});
- }
-
- const uint64_t MaxBlockSize = Bucket.value().get_or("maxblocksize", BucketConfig.MaxBlockSize);
- if (MaxBlockSize == 0)
- {
- throw 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 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 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 OptionParseException(
- fmt::format("'largeobjectthreshold' option for cache bucket '{}' is invalid. It must be non-zero.", Name),
- {});
- }
- BucketConfig.LargeObjectThreshold = LargeObjectThreshold;
-
- BucketConfig.LimitOverwrites = Bucket.value().get_or("limitoverwrites", BucketConfig.LimitOverwrites);
-
- Value.push_back(std::make_pair(std::move(Name), BucketConfig));
- }
- }
- }
- }
- std::vector<std::pair<std::string, ZenStructuredCacheBucketConfig>>& Value;
-};
-
-std::shared_ptr<LuaConfig::OptionValue>
-MakeOption(UpstreamCachePolicy& Value)
-{
- return std::make_shared<CachePolicyOption>(Value);
-};
-
-std::shared_ptr<LuaConfig::OptionValue>
-MakeOption(ZenAuthConfig& Value)
-{
- return std::make_shared<ZenAuthConfigOption>(Value);
-};
-
-std::shared_ptr<LuaConfig::OptionValue>
-MakeOption(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(ZenStorageServerOptions& ServerOptions, const cxxopts::ParseResult& CmdLineResult)
+ParseEnvVariables(ZenServerOptions& ServerOptions, const cxxopts::ParseResult& CmdLineResult)
{
using namespace std::literals;
@@ -463,18 +111,12 @@ ParseEnvVariables(ZenStorageServerOptions& ServerOptions, const cxxopts::ParseRe
}
void
-ParseConfigFile(const std::filesystem::path& Path,
- ZenStorageServerOptions& ServerOptions,
- const cxxopts::ParseResult& CmdLineResult,
- std::string_view OutputConfigFile)
+AddServerConfigOptions(LuaConfig::Options& LuaOptions, ZenServerOptions& ServerOptions)
{
- ZEN_TRACE_CPU("ParseConfigFile");
-
using namespace std::literals;
- LuaConfig::Options LuaOptions;
+ // server
- ////// 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.SentryConfig.Disable, "no-sentry"sv);
@@ -486,20 +128,11 @@ ParseConfigFile(const std::filesystem::path& Path,
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.quiet"sv, ServerOptions.QuietConsole, "quiet"sv);
LuaOptions.AddOption("server.noconsole"sv, ServerOptions.NoConsoleOutput, "noconsole"sv);
- ////// objectstore
- 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);
@@ -529,219 +162,28 @@ ParseConfigFile(const std::filesystem::path& Path,
LuaOptions.AddOption("stats.enable"sv, ServerOptions.StatsConfig.Enabled, "statsd"sv);
LuaOptions.AddOption("stats.host"sv, ServerOptions.StatsConfig.StatsdHost);
LuaOptions.AddOption("stats.port"sv, ServerOptions.StatsConfig.StatsdPort);
-
- ////// cache
- LuaOptions.AddOption("cache.enable"sv, ServerOptions.StructuredCacheConfig.Enabled);
- LuaOptions.AddOption("cache.writelog"sv, ServerOptions.StructuredCacheConfig.WriteLogEnabled, "cache-write-log"sv);
- LuaOptions.AddOption("cache.accesslog"sv, ServerOptions.StructuredCacheConfig.AccessLogEnabled, "cache-access-log"sv);
-
- LuaOptions.AddOption("cache.memlayer.sizethreshold"sv,
- ServerOptions.StructuredCacheConfig.BucketConfig.MemCacheSizeThreshold,
- "cache-memlayer-sizethreshold"sv);
- LuaOptions.AddOption("cache.memlayer.targetfootprint"sv,
- ServerOptions.StructuredCacheConfig.MemTargetFootprintBytes,
- "cache-memlayer-targetfootprint"sv);
- LuaOptions.AddOption("cache.memlayer.triminterval"sv,
- ServerOptions.StructuredCacheConfig.MemTrimIntervalSeconds,
- "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);
- LuaOptions.AddOption("cache.bucket.limitoverwrites"sv,
- ServerOptions.StructuredCacheConfig.BucketConfig.LimitOverwrites,
- "cache-bucket-limit-overwrites"sv);
-
- ////// cache.upstream
- LuaOptions.AddOption("cache.upstream.policy"sv, ServerOptions.UpstreamCacheConfig.CachePolicy, "upstream-cache-policy"sv);
- LuaOptions.AddOption("cache.upstream.upstreamthreadcount"sv,
- ServerOptions.UpstreamCacheConfig.UpstreamThreadCount,
- "upstream-thread-count"sv);
- LuaOptions.AddOption("cache.upstream.connecttimeoutms"sv,
- ServerOptions.UpstreamCacheConfig.ConnectTimeoutMilliseconds,
- "upstream-connect-timeout-ms"sv);
- LuaOptions.AddOption("cache.upstream.timeoutms"sv, ServerOptions.UpstreamCacheConfig.TimeoutMilliseconds, "upstream-timeout-ms"sv);
-
- ////// cache.upstream.jupiter
- LuaOptions.AddOption("cache.upstream.jupiter.name"sv, ServerOptions.UpstreamCacheConfig.JupiterConfig.Name);
- LuaOptions.AddOption("cache.upstream.jupiter.url"sv, ServerOptions.UpstreamCacheConfig.JupiterConfig.Url, "upstream-jupiter-url"sv);
- LuaOptions.AddOption("cache.upstream.jupiter.oauthprovider"sv,
- ServerOptions.UpstreamCacheConfig.JupiterConfig.OAuthUrl,
- "upstream-jupiter-oauth-url"sv);
- LuaOptions.AddOption("cache.upstream.jupiter.oauthclientid"sv,
- ServerOptions.UpstreamCacheConfig.JupiterConfig.OAuthClientId,
- "upstream-jupiter-oauth-clientid");
- LuaOptions.AddOption("cache.upstream.jupiter.oauthclientsecret"sv,
- ServerOptions.UpstreamCacheConfig.JupiterConfig.OAuthClientSecret,
- "upstream-jupiter-oauth-clientsecret"sv);
- LuaOptions.AddOption("cache.upstream.jupiter.openidprovider"sv,
- ServerOptions.UpstreamCacheConfig.JupiterConfig.OpenIdProvider,
- "upstream-jupiter-openid-provider"sv);
- LuaOptions.AddOption("cache.upstream.jupiter.token"sv,
- ServerOptions.UpstreamCacheConfig.JupiterConfig.AccessToken,
- "upstream-jupiter-token"sv);
- LuaOptions.AddOption("cache.upstream.jupiter.namespace"sv,
- ServerOptions.UpstreamCacheConfig.JupiterConfig.Namespace,
- "upstream-jupiter-namespace"sv);
- LuaOptions.AddOption("cache.upstream.jupiter.ddcnamespace"sv,
- ServerOptions.UpstreamCacheConfig.JupiterConfig.DdcNamespace,
- "upstream-jupiter-namespace-ddc"sv);
-
- ////// cache.upstream.zen
- // LuaOptions.AddOption("cache.upstream.zen"sv, ServerOptions.UpstreamCacheConfig.ZenConfig);
- LuaOptions.AddOption("cache.upstream.zen.name"sv, ServerOptions.UpstreamCacheConfig.ZenConfig.Name);
- LuaOptions.AddOption("cache.upstream.zen.dns"sv, ServerOptions.UpstreamCacheConfig.ZenConfig.Dns);
- LuaOptions.AddOption("cache.upstream.zen.url"sv, ServerOptions.UpstreamCacheConfig.ZenConfig.Urls);
-
- ////// gc
- LuaOptions.AddOption("gc.enabled"sv, ServerOptions.GcConfig.Enabled, "gc-enabled"sv);
- LuaOptions.AddOption("gc.v2"sv, ServerOptions.GcConfig.UseGCV2, "gc-v2"sv);
-
- LuaOptions.AddOption("gc.monitorintervalseconds"sv, ServerOptions.GcConfig.MonitorIntervalSeconds, "gc-monitor-interval-seconds"sv);
- LuaOptions.AddOption("gc.intervalseconds"sv, ServerOptions.GcConfig.IntervalSeconds, "gc-interval-seconds"sv);
- LuaOptions.AddOption("gc.collectsmallobjects"sv, ServerOptions.GcConfig.CollectSmallObjects, "gc-small-objects"sv);
- LuaOptions.AddOption("gc.diskreservesize"sv, ServerOptions.GcConfig.DiskReserveSize, "disk-reserve-size"sv);
- LuaOptions.AddOption("gc.disksizesoftlimit"sv, ServerOptions.GcConfig.DiskSizeSoftLimit, "gc-disksize-softlimit"sv);
- LuaOptions.AddOption("gc.lowdiskspacethreshold"sv,
- ServerOptions.GcConfig.MinimumFreeDiskSpaceToAllowWrites,
- "gc-low-diskspace-threshold"sv);
- LuaOptions.AddOption("gc.lightweightintervalseconds"sv,
- ServerOptions.GcConfig.LightweightIntervalSeconds,
- "gc-lightweight-interval-seconds"sv);
- LuaOptions.AddOption("gc.compactblockthreshold"sv,
- ServerOptions.GcConfig.CompactBlockUsageThresholdPercent,
- "gc-compactblock-threshold"sv);
- LuaOptions.AddOption("gc.verbose"sv, ServerOptions.GcConfig.Verbose, "gc-verbose"sv);
- LuaOptions.AddOption("gc.single-threaded"sv, ServerOptions.GcConfig.SingleThreaded, "gc-single-threaded"sv);
- LuaOptions.AddOption("gc.cache.attachment.store"sv, ServerOptions.GcConfig.StoreCacheAttachmentMetaData, "gc-cache-attachment-store");
- LuaOptions.AddOption("gc.projectstore.attachment.store"sv,
- ServerOptions.GcConfig.StoreProjectAttachmentMetaData,
- "gc-projectstore-attachment-store");
- LuaOptions.AddOption("gc.attachment.passes"sv, ServerOptions.GcConfig.AttachmentPassCount, "gc-attachment-passes"sv);
- LuaOptions.AddOption("gc.validation"sv, ServerOptions.GcConfig.EnableValidation, "gc-validation");
-
- LuaOptions.AddOption("gc.cache.maxdurationseconds"sv, ServerOptions.GcConfig.Cache.MaxDurationSeconds, "gc-cache-duration-seconds"sv);
- 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);
- LuaOptions.AddOption("security.encryptionaesiv"sv, ServerOptions.EncryptionIV, "encryption-aes-iv"sv);
- LuaOptions.AddOption("security.openidproviders"sv, ServerOptions.AuthConfig);
-
- ////// workspaces
- LuaOptions.AddOption("workspaces.enabled"sv, ServerOptions.WorksSpacesConfig.Enabled, "workspaces-enabled"sv);
- LuaOptions.AddOption("workspaces.allowconfigchanges"sv,
- 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
- if (!ServerOptions.AuthConfig.OpenIdProviders.empty())
- {
- LuaOptions.Touch("security.openidproviders"sv);
- }
- if (!ServerOptions.ObjectStoreConfig.Buckets.empty())
- {
- LuaOptions.Touch("server.objectstore.buckets"sv);
- }
- if (!ServerOptions.StructuredCacheConfig.PerBucketConfigs.empty())
- {
- LuaOptions.Touch("cache.buckets"sv);
- }
-
- if (!OutputConfigFile.empty())
- {
- std::filesystem::path WritePath(MakeSafeAbsolutePath(OutputConfigFile));
- ExtendableStringBuilder<512> ConfigStringBuilder;
- LuaOptions.Print(ConfigStringBuilder, CmdLineResult);
- BasicFile Output;
- Output.Open(WritePath, BasicFile::Mode::kTruncate);
- Output.Write(ConfigStringBuilder.Data(), ConfigStringBuilder.Size(), 0);
- }
}
-void
-ParsePluginsConfigFile(const std::filesystem::path& Path, ZenStorageServerOptions& ServerOptions, int BasePort)
+struct ZenServerCmdLineOptions
{
- 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)});
- }
+ // Note to those adding future options; std::filesystem::path-type options
+ // must be read into a std::string first. As of cxxopts-3.0.0 it uses a >>
+ // stream operator to convert argv value into the options type. std::fs::path
+ // expects paths in streams to be quoted but argv paths are unquoted. By
+ // going into a std::string first, paths with whitespace parse correctly.
+ std::string ConfigFile;
+ std::string OutputConfigFile;
+ std::string SystemRootDir;
+ std::string ContentDir;
+ std::string DataDir;
+ std::string AbsLogFile;
- ServerOptions.HttpServerConfig.PluginConfigs.push_back(Config);
- }
-}
+ void AddCliOptions(cxxopts::Options& options, ZenServerOptions& ServerOptions);
+ void ApplyOptions(ZenServerOptions& ServerOptions);
+};
void
-ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
+ZenServerCmdLineOptions::AddCliOptions(cxxopts::Options& options, ZenServerOptions& ServerOptions)
{
const char* DefaultHttp = "asio";
@@ -752,31 +194,6 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
}
#endif
- for (int i = 0; i < argc; ++i)
- {
- if (i)
- {
- ServerOptions.CommandLine.push_back(' ');
- }
-
- ServerOptions.CommandLine += argv[i];
- }
-
- // Note to those adding future options; std::filesystem::path-type options
- // must be read into a std::string first. As of cxxopts-3.0.0 it uses a >>
- // stream operator to convert argv value into the options type. std::fs::path
- // expects paths in streams to be quoted but argv paths are unquoted. By
- // going into a std::string first, paths with whitespace parse correctly.
- std::string SystemRootDir;
- std::string DataDir;
- std::string ContentDir;
- std::string AbsLogFile;
- std::string ConfigFile;
- std::string PluginsConfigFile;
- std::string OutputConfigFile;
- std::string BaseSnapshotDir;
-
- cxxopts::Options options("zenserver", "Zen Server");
options.add_options()("dedicated",
"Enable dedicated server mode",
cxxopts::value<bool>(ServerOptions.IsDedicated)->default_value("false"));
@@ -784,24 +201,15 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
options.add_options()("clean",
"Clean out all state at startup",
cxxopts::value<bool>(ServerOptions.IsCleanStart)->default_value("false"));
- options.add_options()("scrub",
- "Validate state at startup",
- cxxopts::value(ServerOptions.ScrubOptions)->implicit_value("yes"),
- "(nocas,nogc,nodelete,yes,no)*");
options.add_options()("help", "Show command line help");
options.add_options()("t, test", "Enable test mode", cxxopts::value<bool>(ServerOptions.IsTest)->default_value("false"));
+
options.add_options()("data-dir", "Specify persistence root", cxxopts::value<std::string>(DataDir));
options.add_options()("system-dir", "Specify system root", cxxopts::value<std::string>(SystemRootDir));
- 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()("content-dir", "Frontend content directory", cxxopts::value<std::string>(ContentDir));
- options.add_options()("powercycle",
- "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.SentryConfig.Disable)->default_value("false"));
@@ -819,6 +227,16 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
options.add_options()("malloc",
"Configure memory allocator subsystem",
cxxopts::value(ServerOptions.MemoryOptions)->default_value("mimalloc"));
+ options.add_options()("powercycle",
+ "Exit immediately after initialization is complete",
+ cxxopts::value<bool>(ServerOptions.IsPowerCycle));
+
+ options.add_option("diagnostics",
+ "",
+ "crash",
+ "Simulate a crash",
+ cxxopts::value<bool>(ServerOptions.ShouldCrash)->default_value("false"),
+ "");
// clang-format off
options.add_options("logging")
@@ -836,34 +254,6 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
;
// clang-format on
- options.add_option("security",
- "",
- "encryption-aes-key",
- "256 bit AES encryption key",
- cxxopts::value<std::string>(ServerOptions.EncryptionKey),
- "");
-
- options.add_option("security",
- "",
- "encryption-aes-iv",
- "128 bit AES encryption initialization vector",
- cxxopts::value<std::string>(ServerOptions.EncryptionIV),
- "");
-
- std::string OpenIdProviderName;
- options.add_option("security",
- "",
- "openid-provider-name",
- "Open ID provider name",
- cxxopts::value<std::string>(OpenIdProviderName),
- "Default");
-
- std::string OpenIdProviderUrl;
- options.add_option("security", "", "openid-provider-url", "Open ID provider URL", cxxopts::value<std::string>(OpenIdProviderUrl), "");
-
- std::string OpenIdClientId;
- options.add_option("security", "", "openid-client-id", "Open ID client ID", cxxopts::value<std::string>(OpenIdClientId), "");
-
options
.add_option("lifetime", "", "owner-pid", "Specify owning process id", cxxopts::value<int>(ServerOptions.OwnerPid), "<identifier>");
options.add_option("lifetime",
@@ -890,17 +280,6 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
options.add_option("network",
"",
- "http",
- "Select HTTP server implementation (asio|"
-#if ZEN_WITH_HTTPSYS
- "httpsys|"
-#endif
- "null)",
- cxxopts::value<std::string>(ServerOptions.HttpServerConfig.ServerClass)->default_value(DefaultHttp),
- "<http class>");
-
- options.add_option("network",
- "",
"http-threads",
"Number of http server connection threads",
cxxopts::value<unsigned int>(ServerOptions.HttpServerConfig.ThreadCount),
@@ -943,6 +322,17 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
"<httpsys request logging>");
#endif
+ options.add_option("network",
+ "",
+ "http",
+ "Select HTTP server implementation (asio|"
+#if ZEN_WITH_HTTPSYS
+ "httpsys|"
+#endif
+ "null)",
+ cxxopts::value<std::string>(ServerOptions.HttpServerConfig.ServerClass)->default_value(DefaultHttp),
+ "<http class>");
+
#if ZEN_WITH_TRACE
// We only have this in options for command line help purposes - we parse these argument separately earlier using
// GetTraceOptionsFromCommandline()
@@ -969,376 +359,45 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
"");
#endif // ZEN_WITH_TRACE
- options.add_option("diagnostics",
- "",
- "crash",
- "Simulate a crash",
- cxxopts::value<bool>(ServerOptions.ShouldCrash)->default_value("false"),
- "");
-
- std::string UpstreamCachePolicyOptions;
- options.add_option("cache",
- "",
- "upstream-cache-policy",
- "",
- cxxopts::value<std::string>(UpstreamCachePolicyOptions)->default_value(""),
- "Upstream cache policy (readwrite|readonly|writeonly|disabled)");
-
- options.add_option("cache",
- "",
- "upstream-jupiter-url",
- "URL to a Jupiter instance",
- cxxopts::value<std::string>(ServerOptions.UpstreamCacheConfig.JupiterConfig.Url)->default_value(""),
- "");
-
- options.add_option("cache",
- "",
- "upstream-jupiter-oauth-url",
- "URL to the OAuth provier",
- cxxopts::value<std::string>(ServerOptions.UpstreamCacheConfig.JupiterConfig.OAuthUrl)->default_value(""),
- "");
-
- options.add_option("cache",
- "",
- "upstream-jupiter-oauth-clientid",
- "The OAuth client ID",
- cxxopts::value<std::string>(ServerOptions.UpstreamCacheConfig.JupiterConfig.OAuthClientId)->default_value(""),
- "");
-
- options.add_option("cache",
- "",
- "upstream-jupiter-oauth-clientsecret",
- "The OAuth client secret",
- cxxopts::value<std::string>(ServerOptions.UpstreamCacheConfig.JupiterConfig.OAuthClientSecret)->default_value(""),
- "");
-
- options.add_option("cache",
- "",
- "upstream-jupiter-openid-provider",
- "Name of a registered Open ID provider",
- cxxopts::value<std::string>(ServerOptions.UpstreamCacheConfig.JupiterConfig.OpenIdProvider)->default_value(""),
- "");
-
- options.add_option("cache",
- "",
- "upstream-jupiter-token",
- "A static authentication token",
- cxxopts::value<std::string>(ServerOptions.UpstreamCacheConfig.JupiterConfig.AccessToken)->default_value(""),
- "");
-
- options.add_option("cache",
- "",
- "upstream-jupiter-namespace",
- "The Common Blob Store API namespace",
- cxxopts::value<std::string>(ServerOptions.UpstreamCacheConfig.JupiterConfig.Namespace)->default_value(""),
- "");
-
- options.add_option("cache",
- "",
- "upstream-jupiter-namespace-ddc",
- "The lecacy DDC namespace",
- cxxopts::value<std::string>(ServerOptions.UpstreamCacheConfig.JupiterConfig.DdcNamespace)->default_value(""),
- "");
-
- options.add_option("cache",
- "",
- "upstream-zen-url",
- "URL to remote Zen server. Use a comma separated list to choose the one with the best latency.",
- cxxopts::value<std::vector<std::string>>(ServerOptions.UpstreamCacheConfig.ZenConfig.Urls),
- "");
-
- options.add_option("cache",
- "",
- "upstream-zen-dns",
- "DNS that resolves to one or more Zen server instance(s)",
- cxxopts::value<std::vector<std::string>>(ServerOptions.UpstreamCacheConfig.ZenConfig.Dns),
- "");
-
- options.add_option("cache",
- "",
- "upstream-thread-count",
- "Number of threads used for upstream procsssing",
- cxxopts::value<int32_t>(ServerOptions.UpstreamCacheConfig.UpstreamThreadCount)->default_value("4"),
- "");
-
- options.add_option("cache",
- "",
- "upstream-connect-timeout-ms",
- "Connect timeout in millisecond(s). Default 5000 ms.",
- cxxopts::value<int32_t>(ServerOptions.UpstreamCacheConfig.ConnectTimeoutMilliseconds)->default_value("5000"),
- "");
-
- options.add_option("cache",
- "",
- "upstream-timeout-ms",
- "Timeout in millisecond(s). Default 0 ms",
- cxxopts::value<int32_t>(ServerOptions.UpstreamCacheConfig.TimeoutMilliseconds)->default_value("0"),
- "");
-
- options.add_option("cache",
- "",
- "cache-write-log",
- "Whether cache write log is enabled",
- cxxopts::value<bool>(ServerOptions.StructuredCacheConfig.WriteLogEnabled)->default_value("false"),
- "");
-
- options.add_option("cache",
- "",
- "cache-access-log",
- "Whether cache access log is enabled",
- cxxopts::value<bool>(ServerOptions.StructuredCacheConfig.AccessLogEnabled)->default_value("false"),
- "");
-
- options.add_option(
- "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. "
- "Obsolete, replaced by `--cache-bucket-memlayer-sizethreshold`",
- cxxopts::value<uint64_t>(ServerOptions.StructuredCacheConfig.BucketConfig.MemCacheSizeThreshold)->default_value("1024"),
- "");
-
- options.add_option("cache",
- "",
- "cache-memlayer-targetfootprint",
- "Max allowed memory used by cache memory layer per namespace in bytes. Default set to 536870912 (512 Mb).",
- cxxopts::value<uint64_t>(ServerOptions.StructuredCacheConfig.MemTargetFootprintBytes)->default_value("536870912"),
- "");
-
- options.add_option("cache",
- "",
- "cache-memlayer-triminterval",
- "Minimum time between each attempt to trim cache memory layers in seconds. Default set to 60 (1 min).",
- cxxopts::value<uint64_t>(ServerOptions.StructuredCacheConfig.MemTrimIntervalSeconds)->default_value("60"),
- "");
-
- options.add_option("cache",
- "",
- "cache-memlayer-maxage",
- "Maximum age of payloads when trimming cache memory layers in seconds. Default set to 86400 (1 day).",
- 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("cache",
- "",
- "cache-bucket-limit-overwrites",
- "Whether to require policy flag pattern before allowing overwrites in cache bucket",
- cxxopts::value<bool>(ServerOptions.StructuredCacheConfig.BucketConfig.LimitOverwrites)->default_value("false"),
- "");
-
- options.add_option("gc",
- "",
- "gc-cache-attachment-store",
- "Enable storing attachments referenced by a cache record in block store meta data.",
- cxxopts::value<bool>(ServerOptions.GcConfig.StoreCacheAttachmentMetaData)->default_value("false"),
- "");
-
- options.add_option("gc",
- "",
- "gc-projectstore-attachment-store",
- "Enable storing attachments referenced by project oplogs in meta data.",
- cxxopts::value<bool>(ServerOptions.GcConfig.StoreProjectAttachmentMetaData)->default_value("false"),
- "");
-
- options.add_option("gc",
- "",
- "gc-validation",
- "Enable validation of references after full GC.",
- cxxopts::value<bool>(ServerOptions.GcConfig.EnableValidation)->default_value("true"),
- "");
-
- options.add_option("gc",
- "",
- "gc-enabled",
- "Whether garbage collection is enabled or not.",
- cxxopts::value<bool>(ServerOptions.GcConfig.Enabled)->default_value("true"),
- "");
-
- options.add_option("gc",
- "",
- "gc-v2",
- "Use V2 of GC implementation or not.",
- cxxopts::value<bool>(ServerOptions.GcConfig.UseGCV2)->default_value("true"),
- "");
-
- options.add_option("gc",
- "",
- "gc-small-objects",
- "Whether garbage collection of small objects is enabled or not.",
- cxxopts::value<bool>(ServerOptions.GcConfig.CollectSmallObjects)->default_value("true"),
- "");
-
- options.add_option("gc",
- "",
- "gc-interval-seconds",
- "Garbage collection interval in seconds. Default set to 3600 (1 hour).",
- cxxopts::value<int32_t>(ServerOptions.GcConfig.IntervalSeconds)->default_value("3600"),
- "");
-
- options.add_option("gc",
- "",
- "gc-lightweight-interval-seconds",
- "Lightweight garbage collection interval in seconds. Default set to 900 (30 min).",
- cxxopts::value<int32_t>(ServerOptions.GcConfig.LightweightIntervalSeconds)->default_value("900"),
- "");
-
- options.add_option("gc",
- "",
- "gc-cache-duration-seconds",
- "Max duration in seconds before Z$ entries get evicted. Default set to 1209600 (2 weeks)",
- cxxopts::value<int32_t>(ServerOptions.GcConfig.Cache.MaxDurationSeconds)->default_value("1209600"),
- "");
-
- options.add_option("gc",
- "",
- "gc-projectstore-duration-seconds",
- "Max duration in seconds before project store entries get evicted. Default set to 1209600 (2 weeks)",
- cxxopts::value<int32_t>(ServerOptions.GcConfig.ProjectStore.MaxDurationSeconds)->default_value("1209600"),
- "");
-
- 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"),
- "");
-
- options.add_option("gc",
- "",
- "gc-monitor-interval-seconds",
- "Garbage collection monitoring interval in seconds. Default set to 30 (30 seconds)",
- cxxopts::value<int32_t>(ServerOptions.GcConfig.MonitorIntervalSeconds)->default_value("30"),
- "");
-
- options.add_option("gc",
- "",
- "gc-low-diskspace-threshold",
- "Minimum free space on disk to allow writes to disk. Default set to 268435456 (256 Mb). Set to zero to disable.",
- cxxopts::value<uint64_t>(ServerOptions.GcConfig.MinimumFreeDiskSpaceToAllowWrites)->default_value("268435456"),
- "");
-
- options.add_option("gc",
- "",
- "gc-disksize-softlimit",
- "Garbage collection disk usage soft limit. Default set to 0 (Off).",
- cxxopts::value<uint64_t>(ServerOptions.GcConfig.DiskSizeSoftLimit)->default_value("0"),
- "");
-
- options.add_option("gc",
- "",
- "gc-compactblock-threshold",
- "Garbage collection - how much of a compact block should be used to skip compacting the block. 0 - compact only "
- "empty eligible blocks, 100 - compact all non-full eligible blocks.",
- cxxopts::value<uint32_t>(ServerOptions.GcConfig.CompactBlockUsageThresholdPercent)->default_value("60"),
- "");
-
- options.add_option("gc",
+ options.add_option("stats",
"",
- "gc-verbose",
- "Enable verbose logging for GC.",
- cxxopts::value<bool>(ServerOptions.GcConfig.Verbose)->default_value("false"),
- "");
-
- options.add_option("gc",
+ "statsd",
"",
- "gc-single-threaded",
- "Force GC to run single threaded.",
- cxxopts::value<bool>(ServerOptions.GcConfig.SingleThreaded)->default_value("false"),
- "");
+ cxxopts::value<bool>(ServerOptions.StatsConfig.Enabled)->default_value("false"),
+ "Enable statsd reporter (localhost:8125)");
+}
- options.add_option("gc",
- "",
- "gc-attachment-passes",
- "Limit the range of unreferenced attachments included in GC check by breaking it into passes. Default is one pass "
- "which includes all the attachments.",
- cxxopts::value<uint16_t>(ServerOptions.GcConfig.AttachmentPassCount)->default_value("1"),
- "");
+void
+ZenServerCmdLineOptions::ApplyOptions(ZenServerOptions& ServerOptions)
+{
+ ServerOptions.SystemRootDir = MakeSafeAbsolutePath(SystemRootDir);
+ ServerOptions.DataDir = MakeSafeAbsolutePath(DataDir);
+ ServerOptions.ContentDir = MakeSafeAbsolutePath(ContentDir);
+ ServerOptions.AbsLogFile = MakeSafeAbsolutePath(AbsLogFile);
+ ServerOptions.ConfigFile = MakeSafeAbsolutePath(ConfigFile);
+}
- options.add_option("objectstore",
- "",
- "objectstore-enabled",
- "Whether the object store is enabled or not.",
- cxxopts::value<bool>(ServerOptions.ObjectStoreEnabled)->default_value("false"),
- "");
+void
+ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
+{
+ for (int i = 0; i < argc; ++i)
+ {
+ if (i)
+ {
+ ServerOptions.CommandLine.push_back(' ');
+ }
- std::vector<std::string> BucketConfigs;
- options.add_option("objectstore",
- "",
- "objectstore-bucket",
- "Object store bucket mappings.",
- cxxopts::value<std::vector<std::string>>(BucketConfigs),
- "");
+ ServerOptions.CommandLine += argv[i];
+ }
- 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"),
- "");
+ cxxopts::Options options("zenserver", "Zen Storage Server");
- options.add_option("stats",
- "",
- "statsd",
- "",
- cxxopts::value<bool>(ServerOptions.StatsConfig.Enabled)->default_value("false"),
- "Enable statsd reporter (localhost:8125)");
+ ZenServerCmdLineOptions BaseOptions;
+ BaseOptions.AddCliOptions(options, ServerOptions);
- options.add_option("workspaces",
- "",
- "workspaces-enabled",
- "",
- cxxopts::value<bool>(ServerOptions.WorksSpacesConfig.Enabled)->default_value("true"),
- "Enable workspaces support with folder sharing");
+ ZenStorageServerCmdLineOptions StorageOptions;
+ StorageOptions.AddCliOptions(options, ServerOptions);
- options.add_option("workspaces",
- "",
- "workspaces-allow-changes",
- "",
- cxxopts::value<bool>(ServerOptions.WorksSpacesConfig.AllowConfigurationChanges)->default_value("false"),
- "Allow adding/modifying/deleting of workspace and shares via http endpoint");
try
{
cxxopts::ParseResult Result;
@@ -1355,6 +414,7 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
if (Result.count("help"))
{
ZEN_CONSOLE("{}", options.help());
+
#if ZEN_PLATFORM_WINDOWS
ZEN_CONSOLE("Press any key to exit!");
_getch();
@@ -1362,6 +422,7 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
// Assume the user's in a terminal on all other platforms and that
// they'll use less/more/etc. if need be.
#endif
+
exit(0);
}
@@ -1371,8 +432,6 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
TraceConfigure(ServerOptions.TraceOptions);
}
- ZEN_TRACE_CPU("ConfigParse");
-
if (ServerOptions.QuietConsole)
{
bool HasExplicitConsoleLevel = false;
@@ -1402,46 +461,20 @@ ParseCliOptions(int argc, char* argv[], ZenStorageServerOptions& ServerOptions)
}
logging::RefreshLogLevels();
- 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())
- {
- if (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", BaseSnapshotDir));
- }
-
- if (OpenIdProviderUrl.empty() == false)
- {
- if (OpenIdClientId.empty())
- {
- throw OptionParseException("'--openid-provider-url' requires '--openid-client-id'", options.help());
- }
-
- ServerOptions.AuthConfig.OpenIdProviders.push_back(
- {.Name = OpenIdProviderName, .Url = OpenIdProviderUrl, .ClientId = OpenIdClientId});
- }
-
- ServerOptions.ObjectStoreConfig = ParseBucketConfigs(BucketConfigs);
+ BaseOptions.ApplyOptions(ServerOptions);
+ StorageOptions.ApplyOptions(options, ServerOptions);
ParseEnvVariables(ServerOptions, Result);
+ ZEN_TRACE_CPU("ConfigParse");
+
if (!ServerOptions.ConfigFile.empty())
{
- ParseConfigFile(ServerOptions.ConfigFile, ServerOptions, Result, OutputConfigFile);
+ ParseConfigFile(ServerOptions.ConfigFile, ServerOptions, Result, BaseOptions.OutputConfigFile);
}
else
{
- ParseConfigFile(ServerOptions.DataDir / "zen_cfg.lua", ServerOptions, Result, OutputConfigFile);
+ ParseConfigFile(ServerOptions.DataDir / "zen_cfg.lua", ServerOptions, Result, BaseOptions.OutputConfigFile);
}
if (!ServerOptions.PluginsConfigFile.empty())