aboutsummaryrefslogtreecommitdiff
path: root/src/zenutil/include
diff options
context:
space:
mode:
authorLiam Mitchell <[email protected]>2026-03-09 18:25:30 -0700
committerLiam Mitchell <[email protected]>2026-03-09 18:25:30 -0700
commit57c1683b2935c834250b73eb506319ed67946160 (patch)
tree1fc8f237010b26e65659b731fe6f6eae30422f5c /src/zenutil/include
parentAllow external OidcToken executable to be specified unless disabled via comma... (diff)
parentreduce lock time for project store gc precache and gc validate (#750) (diff)
downloadzen-57c1683b2935c834250b73eb506319ed67946160.tar.xz
zen-57c1683b2935c834250b73eb506319ed67946160.zip
Merge branch 'main' into lm/oidctoken-exe-path
Diffstat (limited to 'src/zenutil/include')
-rw-r--r--src/zenutil/include/zenutil/commandlineoptions.h13
-rw-r--r--src/zenutil/include/zenutil/consul.h47
-rw-r--r--src/zenutil/include/zenutil/logging/rotatingfilesink.h3
-rw-r--r--src/zenutil/include/zenutil/zenserverprocess.h35
4 files changed, 92 insertions, 6 deletions
diff --git a/src/zenutil/include/zenutil/commandlineoptions.h b/src/zenutil/include/zenutil/commandlineoptions.h
index d6a171242..01cceedb1 100644
--- a/src/zenutil/include/zenutil/commandlineoptions.h
+++ b/src/zenutil/include/zenutil/commandlineoptions.h
@@ -22,6 +22,19 @@ std::vector<char*> StripCommandlineQuotes(std::vector<std::string>& InOutArgs)
std::filesystem::path StringToPath(const std::string_view& Path);
std::string_view RemoveQuotes(const std::string_view& Arg);
+class CommandLineConverter
+{
+public:
+ CommandLineConverter(int& argc, char**& argv);
+
+ int ArgC = 0;
+ char** ArgV = nullptr;
+
+private:
+ std::vector<std::string> Args;
+ std::vector<char*> RawArgs;
+};
+
void commandlineoptions_forcelink(); // internal
} // namespace zen
diff --git a/src/zenutil/include/zenutil/consul.h b/src/zenutil/include/zenutil/consul.h
new file mode 100644
index 000000000..08871fa66
--- /dev/null
+++ b/src/zenutil/include/zenutil/consul.h
@@ -0,0 +1,47 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zenbase/zenbase.h>
+#include <zenhttp/httpclient.h>
+
+#include <string>
+#include <string_view>
+
+namespace zen::consul {
+
+class ConsulClient
+{
+public:
+ ConsulClient(std::string_view BaseUri);
+ ~ConsulClient();
+
+ ConsulClient(const ConsulClient&) = delete;
+ ConsulClient& operator=(const ConsulClient&) = delete;
+
+ void SetKeyValue(std::string_view Key, std::string_view Value);
+ std::string GetKeyValue(std::string_view Key);
+ void DeleteKey(std::string_view Key);
+
+private:
+ HttpClient m_HttpClient;
+};
+
+class ConsulProcess
+{
+public:
+ ConsulProcess();
+ ~ConsulProcess();
+
+ ConsulProcess(const ConsulProcess&) = delete;
+ ConsulProcess& operator=(const ConsulProcess&) = delete;
+
+ void SpawnConsulAgent();
+ void StopConsulAgent();
+
+private:
+ struct Impl;
+ std::unique_ptr<Impl> m_Impl;
+};
+
+} // namespace zen::consul
diff --git a/src/zenutil/include/zenutil/logging/rotatingfilesink.h b/src/zenutil/include/zenutil/logging/rotatingfilesink.h
index 4d10f3794..8901b7779 100644
--- a/src/zenutil/include/zenutil/logging/rotatingfilesink.h
+++ b/src/zenutil/include/zenutil/logging/rotatingfilesink.h
@@ -11,6 +11,7 @@ ZEN_THIRD_PARTY_INCLUDES_START
#include <spdlog/sinks/sink.h>
ZEN_THIRD_PARTY_INCLUDES_END
+#include <atomic>
#include <filesystem>
namespace zen::logging {
@@ -248,7 +249,7 @@ private:
const std::size_t m_MaxSize;
const std::size_t m_MaxFiles;
BasicFile m_CurrentFile;
- bool m_NeedFlush = false;
+ std::atomic<bool> m_NeedFlush = false;
};
} // namespace zen::logging
diff --git a/src/zenutil/include/zenutil/zenserverprocess.h b/src/zenutil/include/zenutil/zenserverprocess.h
index 0da63285b..d0402640b 100644
--- a/src/zenutil/include/zenutil/zenserverprocess.h
+++ b/src/zenutil/include/zenutil/zenserverprocess.h
@@ -34,8 +34,10 @@ public:
void Initialize(std::filesystem::path ProgramBaseDir);
void InitializeForTest(std::filesystem::path ProgramBaseDir, std::filesystem::path TestBaseDir, std::string_view ServerClass = "");
+ void InitializeForHub(std::filesystem::path ProgramBaseDir, std::filesystem::path TestBaseDir, std::string_view ServerClass = "");
std::filesystem::path CreateNewTestDir();
+ std::filesystem::path CreateChildDir(std::string_view ChildName);
std::filesystem::path ProgramBaseDir() const { return m_ProgramBaseDir; }
std::filesystem::path GetTestRootDir(std::string_view Path);
inline bool IsInitialized() const { return m_IsInitialized; }
@@ -43,11 +45,18 @@ public:
inline std::string_view GetServerClass() const { return m_ServerClass; }
inline uint16_t GetNewPortNumber() { return m_NextPortNumber.fetch_add(1); }
+ // The defaults will work for a single root process only. For hierarchical
+ // setups (e.g., hub managing storage servers), we need to be able to
+ // allocate distinct child IDs and ports to avoid overlap/conflicts.
+ static void SetBaseChildId(int InitialValue);
+ void SetNextPortNumber(uint16_t NewValue) { m_NextPortNumber = NewValue; }
+
private:
std::filesystem::path m_ProgramBaseDir;
- std::filesystem::path m_TestBaseDir;
+ std::filesystem::path m_ChildProcessBaseDir;
bool m_IsInitialized = false;
bool m_IsTestInstance = false;
+ bool m_IsHubInstance = false;
std::string m_ServerClass;
std::atomic_uint16_t m_NextPortNumber{20000};
};
@@ -60,10 +69,19 @@ private:
Especially useful for automated testing but can also be used for
management tools.
+ This is also used by zenserver in hub mode, for managing storage
+ server instances.
+
*/
struct ZenServerInstance
{
- ZenServerInstance(ZenServerEnvironment& TestEnvironment);
+ enum class ServerMode
+ {
+ kStorageServer, // default
+ kHubServer,
+ };
+
+ ZenServerInstance(ZenServerEnvironment& TestEnvironment, ServerMode Mode = ServerMode::kStorageServer);
~ZenServerInstance();
int Shutdown();
@@ -72,6 +90,7 @@ struct ZenServerInstance
[[nodiscard]] bool WaitUntilReady(int Timeout);
[[nodiscard]] bool WaitUntilExited(int Timeout, std::error_code& OutEc);
void EnableTermination() { m_Terminate = true; }
+ void EnableShutdownOnDestroy() { m_ShutdownOnDestroy = true; }
void DisableShutdownOnDestroy() { m_ShutdownOnDestroy = false; }
void Detach();
inline int GetPid() const { return m_Process.Pid(); }
@@ -81,7 +100,11 @@ struct ZenServerInstance
bool Terminate();
std::string GetLogOutput() const;
- void SetTestDir(std::filesystem::path TestDir);
+ inline ServerMode GetServerMode() const { return m_ServerMode; }
+
+ inline void SetServerExecutablePath(std::filesystem::path ExecutablePath) { m_ServerExecutablePath = ExecutablePath; }
+
+ void SetDataDir(std::filesystem::path TestDir);
inline void SpawnServer(std::string_view AdditionalServerArgs = std::string_view())
{
@@ -117,11 +140,13 @@ private:
std::unique_ptr<NamedEvent> m_ShutdownEvent;
bool m_Terminate = false;
bool m_ShutdownOnDestroy = true;
- std::filesystem::path m_TestDir;
- uint16_t m_BasePort = 0;
+ std::filesystem::path m_DataDir;
+ uint16_t m_BasePort = 0;
+ ServerMode m_ServerMode = ServerMode::kStorageServer;
std::optional<int> m_OwnerPid;
std::string m_Name;
std::filesystem::path m_OutputCapturePath;
+ std::filesystem::path m_ServerExecutablePath;
void CreateShutdownEvent(int BasePort);
void SpawnServer(int BasePort, std::string_view AdditionalServerArgs, int WaitTimeoutMs);