diff options
| author | Dan Engelbrecht <[email protected]> | 2023-09-01 07:29:41 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-09-01 13:29:41 +0200 |
| commit | a165efeaf58dc7336e40d812359b0fc2ce0e7a83 (patch) | |
| tree | 6c7aa1dd0cbb7f0fa751f7bc1bff9b3e8205e1da /src | |
| parent | 0.2.19 (diff) | |
| download | zen-a165efeaf58dc7336e40d812359b0fc2ce0e7a83.tar.xz zen-a165efeaf58dc7336e40d812359b0fc2ce0e7a83.zip | |
add `--write-config` to zenserver options (#382)
- Feature: `zen up` command has two new command line options
- `--config <file_path>` tells zenserver to start with a specific config file
- `--owner-pid <pid>` tells zenserver to start with a owning process id
- Feature: `zen attach` command to add additional owning processes to a running zenserver instance
- `--owner-pid <pid>` adds pid to running zenserver instance list of owning processes
- Feature: `--write-config` command line option for zenserver
- `--write-config <file_path>` path to a file which will contain a lua config file for zenserver combining all command line options and optional lua config files
- Improvement: `zen up` command will check if zenserver is currently running before starting up a new instance
Diffstat (limited to 'src')
| -rw-r--r-- | src/zen/cmds/up.cpp | 76 | ||||
| -rw-r--r-- | src/zen/cmds/up.h | 18 | ||||
| -rw-r--r-- | src/zen/zen.cpp | 2 | ||||
| -rw-r--r-- | src/zenserver/config.cpp | 30 |
4 files changed, 115 insertions, 11 deletions
diff --git a/src/zen/cmds/up.cpp b/src/zen/cmds/up.cpp index 69bcbe829..d1ae0794a 100644 --- a/src/zen/cmds/up.cpp +++ b/src/zen/cmds/up.cpp @@ -12,6 +12,13 @@ namespace zen { UpCommand::UpCommand() { + m_Options.add_option("lifetime", + "", + "owner-pid", + "Specify owning process id", + cxxopts::value(m_OwnerPid)->default_value("0"), + "<identifier>"); + m_Options.add_options()("config", "Path to Lua config file", cxxopts::value(m_ConfigFile)); } UpCommand::~UpCommand() = default; @@ -21,12 +28,34 @@ UpCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { ZEN_UNUSED(GlobalOptions, argc, argv); - std::filesystem::path ExePath = zen::GetRunningExecutablePath(); + if (!ParseOptions(argc, argv)) + { + return 0; + } - ZenServerEnvironment ServerEnvironment; + { + ZenServerState State; + if (State.InitializeReadOnly()) + { + ZEN_CONSOLE("Zen server already running"); + return 0; + } + } + + std::filesystem::path ExePath = zen::GetRunningExecutablePath(); + ZenServerEnvironment ServerEnvironment; ServerEnvironment.Initialize(ExePath.parent_path()); ZenServerInstance Server(ServerEnvironment); - Server.SpawnServer(); + if (m_OwnerPid != 0) + { + Server.SetOwnerPid(m_OwnerPid); + } + std::string AdditionalArguments; + if (!m_ConfigFile.empty()) + { + AdditionalArguments = fmt::format("--config {}", m_ConfigFile); + } + Server.SpawnServer(0, AdditionalArguments); int Timeout = 10000; @@ -44,6 +73,45 @@ UpCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) ////////////////////////////////////////////////////////////////////////// +AttachCommand::AttachCommand() +{ + m_Options.add_option("", "p", "port", "Host port", cxxopts::value(m_Port)->default_value("1337"), "<hostport>"); + m_Options.add_option("lifetime", "", "owner-pid", "Specify owning process id", cxxopts::value(m_OwnerPid), "<identifier>"); +} + +AttachCommand::~AttachCommand() = default; + +int +AttachCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) +{ + ZEN_UNUSED(GlobalOptions, argc, argv); + + if (!ParseOptions(argc, argv)) + { + return 0; + } + + ZenServerState Instance; + Instance.Initialize(); + ZenServerState::ZenServerEntry* Entry = Instance.Lookup(m_Port); + if (!Entry) + { + ZEN_WARN("no zen server instance to add sponsor process to"); + return 1; + } + + if (!Entry->AddSponsorProcess(m_OwnerPid)) + { + ZEN_WARN("unable to add sponsor process to running zen server instance"); + return 1; + } + + ZEN_CONSOLE("added sponsor process {} to running instance {} on port {}", m_OwnerPid, Entry->Pid.load(), m_Port); + return 0; +} + +////////////////////////////////////////////////////////////////////////// + DownCommand::DownCommand() { m_Options.add_option("", "p", "port", "Host port", cxxopts::value(m_Port)->default_value("1337"), "<hostport>"); @@ -97,7 +165,7 @@ DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) // Since we cannot obtain a handle to the process we are unable to block on the process // handle to determine when the server has shut down. Thus we signal that we would like - // a shutdown via the shutdown flag and then + // a shutdown via the shutdown flag and then exit. ZEN_CONSOLE("requesting shutdown of server on port {}", m_Port); Entry->SignalShutdownRequest(); diff --git a/src/zen/cmds/up.h b/src/zen/cmds/up.h index 5af05541a..5b5c6a3f8 100644 --- a/src/zen/cmds/up.h +++ b/src/zen/cmds/up.h @@ -17,6 +17,24 @@ public: private: cxxopts::Options m_Options{"up", "Bring up zen service"}; + uint16_t m_Port; + int m_OwnerPid; + std::string m_ConfigFile; +}; + +class AttachCommand : public ZenCmdBase +{ +public: + AttachCommand(); + ~AttachCommand(); + + virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override; + virtual cxxopts::Options& Options() override { return m_Options; } + +private: + cxxopts::Options m_Options{"attach", "Add a sponsor process to a running zen service"}; + uint16_t m_Port; + int m_OwnerPid; }; class DownCommand : public ZenCmdBase diff --git a/src/zen/zen.cpp b/src/zen/zen.cpp index 204a91f74..f1cfe9796 100644 --- a/src/zen/zen.cpp +++ b/src/zen/zen.cpp @@ -216,6 +216,7 @@ main(int argc, char** argv) StatusCommand StatusCmd; TopCommand TopCmd; UpCommand UpCmd; + AttachCommand AttachCmd; VersionCommand VersionCmd; #if ZEN_WITH_TESTS RunTestsCommand RunTestsCmd; @@ -263,6 +264,7 @@ main(int argc, char** argv) {"status", &StatusCmd, "Show zen status"}, {"top", &TopCmd, "Monitor zen server activity"}, {"up", &UpCmd, "Bring zen server up"}, + {"attach", &AttachCmd, "Add a sponsor process to a running zen service"}, {"version", &VersionCmd, "Get zen server version"}, #if ZEN_WITH_TESTS {"runtests", &RunTestsCmd, "Run zen tests"}, diff --git a/src/zenserver/config.cpp b/src/zenserver/config.cpp index 2d286b02a..1f5a3eb21 100644 --- a/src/zenserver/config.cpp +++ b/src/zenserver/config.cpp @@ -10,6 +10,7 @@ #include <zencore/iobuffer.h> #include <zencore/string.h> #include <zenhttp/zenhttp.h> +#include <zenutil/basicfile.h> ZEN_THIRD_PARTY_INCLUDES_START #include <fmt/format.h> @@ -136,15 +137,15 @@ ParseBucketConfigs(std::span<std::string> Buckets) } static std::string -MakeSafePath(const std::string& Path) +MakeSafePath(const std::string_view Path) { #if ZEN_PLATFORM_WINDOWS if (Path.empty()) { - return Path; + return std::string(Path); } - std::string FixedPath = Path; + std::string FixedPath(Path); std::replace(FixedPath.begin(), FixedPath.end(), '/', '\\'); if (!FixedPath.starts_with("\\\\?\\")) { @@ -152,7 +153,7 @@ MakeSafePath(const std::string& Path) } return FixedPath; #else - return Path; + return std::string(Path); #endif }; @@ -768,7 +769,10 @@ private: } // namespace LuaConfig void -ParseConfigFile(const std::filesystem::path& Path, ZenServerOptions& ServerOptions, const cxxopts::ParseResult& CmdLineResult) +ParseConfigFile(const std::filesystem::path& Path, + ZenServerOptions& ServerOptions, + const cxxopts::ParseResult& CmdLineResult, + std::string_view OutputConfigFile) { using namespace std::literals; @@ -923,6 +927,16 @@ ParseConfigFile(const std::filesystem::path& Path, ZenServerOptions& ServerOptio { LuaOptions.Touch("server.objectstore.buckets"sv); } + + if (!OutputConfigFile.empty()) + { + std::filesystem::path WritePath(MakeSafePath(OutputConfigFile)); + zen::ExtendableStringBuilder<512> ConfigStringBuilder; + LuaOptions.Print(ConfigStringBuilder, CmdLineResult); + zen::BasicFile Output; + Output.Open(WritePath, zen::BasicFile::Mode::kTruncate); + Output.Write(ConfigStringBuilder.Data(), ConfigStringBuilder.Size(), 0); + } } void @@ -943,6 +957,7 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions) std::string ContentDir; std::string AbsLogFile; std::string ConfigFile; + std::string OutputConfigFile; cxxopts::Options options("zenserver", "Zen Server"); options.add_options()("dedicated", @@ -956,6 +971,7 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions) options.add_options()("content-dir", "Frontend content directory", cxxopts::value<std::string>(ContentDir)); options.add_options()("abslog", "Path to log file", cxxopts::value<std::string>(AbsLogFile)); 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()("no-sentry", "Disable Sentry crash handler", cxxopts::value<bool>(ServerOptions.NoSentry)->default_value("false")); @@ -1380,11 +1396,11 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions) if (!ServerOptions.ConfigFile.empty()) { - ParseConfigFile(ServerOptions.ConfigFile, ServerOptions, result); + ParseConfigFile(ServerOptions.ConfigFile, ServerOptions, result, OutputConfigFile); } else { - ParseConfigFile(ServerOptions.DataDir / "zen_cfg.lua", ServerOptions, result); + ParseConfigFile(ServerOptions.DataDir / "zen_cfg.lua", ServerOptions, result, OutputConfigFile); } ValidateOptions(ServerOptions); |