aboutsummaryrefslogtreecommitdiff
path: root/zenserver/zenserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zenserver/zenserver.cpp')
-rw-r--r--zenserver/zenserver.cpp178
1 files changed, 106 insertions, 72 deletions
diff --git a/zenserver/zenserver.cpp b/zenserver/zenserver.cpp
index d475ee70f..4cbb56915 100644
--- a/zenserver/zenserver.cpp
+++ b/zenserver/zenserver.cpp
@@ -113,6 +113,7 @@ ZEN_THIRD_PARTY_INCLUDES_END
namespace zen {
using namespace std::literals;
+using namespace fmt::literals;
class ZenServer : public IHttpStatusProvider
{
@@ -157,77 +158,7 @@ public:
throw std::runtime_error("Failed to create mutex '{}' - is another instance already running?"_format(MutexName).c_str());
}
- // Check root manifest to deal with schema versioning
-
- bool WipeState = false;
- std::string WipeReason = "Unspecified";
-
- std::filesystem::path ManifestPath = m_DataRoot / "root_manifest";
- FileContents ManifestData = zen::ReadFile(ManifestPath);
-
- if (ManifestData.ErrorCode)
- {
- WipeState = true;
- WipeReason = "No manifest present at '{}'"_format(ManifestPath);
- }
- else
- {
- IoBuffer Manifest = ManifestData.Flatten();
-
- if (CbValidateError ValidationResult = ValidateCompactBinary(Manifest, CbValidateMode::All);
- ValidationResult != CbValidateError::None)
- {
- ZEN_ERROR("Manifest validation failed: {}, state will be wiped", ValidationResult);
-
- WipeState = true;
- WipeReason = "Validation of manifest at '{}' failed: {}"_format(ManifestPath, ValidationResult);
- }
- else
- {
- m_RootManifest = LoadCompactBinaryObject(Manifest);
-
- const int32_t ManifestVersion = m_RootManifest["schema_version"].AsInt32(0);
-
- if (ManifestVersion != ZEN_SCHEMA_VERSION)
- {
- WipeState = true;
- WipeReason = "Manifest schema version: {}, differs from required: {}"_format(ManifestVersion, ZEN_SCHEMA_VERSION);
- }
- }
- }
-
- // Handle any state wipe
-
- if (WipeState)
- {
- ZEN_WARN("Wiping state at '{}' - reason: '{}'", m_DataRoot, WipeReason);
-
- std::error_code Ec;
- for (const std::filesystem::directory_entry& DirEntry : std::filesystem::directory_iterator{m_DataRoot, Ec})
- {
- if (DirEntry.is_directory() && (DirEntry.path().filename() != "logs"))
- {
- ZEN_INFO("Deleting '{}'", DirEntry.path());
-
- std::filesystem::remove_all(DirEntry.path(), Ec);
-
- if (Ec)
- {
- ZEN_WARN("Delete of '{}' returned error: '{}'", DirEntry.path(), Ec.message());
- }
- }
- }
-
- ZEN_INFO("Wiped all directories in data root");
-
- // Write new manifest
-
- CbObjectWriter Cbo;
- Cbo << "schema_version" << ZEN_SCHEMA_VERSION;
- m_RootManifest = Cbo.Save();
-
- WriteFile(ManifestPath, m_RootManifest.GetBuffer().AsIoBuffer());
- }
+ InitializeState(ServiceConfig);
// Ok so now we're configured, let's kick things off
@@ -319,6 +250,7 @@ public:
}
}
+ void InitializeState(ZenServiceConfig& ServiceConfig);
void InitializeStructuredCache(ZenServiceConfig& ServiceConfig);
#if ZEN_ENABLE_MESH
@@ -332,7 +264,7 @@ public:
void Run()
{
// This is disabled for now, awaiting better scheduling
- //
+ //
// Scrub();
if (m_ProcessMonitor.IsActive())
@@ -543,6 +475,101 @@ private:
};
void
+ZenServer::InitializeState(ZenServiceConfig& ServiceConfig)
+{
+ // Check root manifest to deal with schema versioning
+
+ bool WipeState = false;
+ std::string WipeReason = "Unspecified";
+
+ bool UpdateManifest = false;
+ std::filesystem::path ManifestPath = m_DataRoot / "root_manifest";
+ FileContents ManifestData = zen::ReadFile(ManifestPath);
+
+ if (ManifestData.ErrorCode)
+ {
+ if (ServiceConfig.IsFirstRun)
+ {
+ ZEN_INFO("Initializing state at '{}'", m_DataRoot);
+
+ UpdateManifest = true;
+ }
+ else
+ {
+ WipeState = true;
+ WipeReason = "No manifest present at '{}'"_format(ManifestPath);
+ }
+ }
+ else
+ {
+ IoBuffer Manifest = ManifestData.Flatten();
+
+ if (CbValidateError ValidationResult = ValidateCompactBinary(Manifest, CbValidateMode::All);
+ ValidationResult != CbValidateError::None)
+ {
+ ZEN_ERROR("Manifest validation failed: {}, state will be wiped", ValidationResult);
+
+ WipeState = true;
+ WipeReason = "Validation of manifest at '{}' failed: {}"_format(ManifestPath, ValidationResult);
+ }
+ else
+ {
+ m_RootManifest = LoadCompactBinaryObject(Manifest);
+
+ const int32_t ManifestVersion = m_RootManifest["schema_version"].AsInt32(0);
+
+ if (ManifestVersion != ZEN_SCHEMA_VERSION)
+ {
+ WipeState = true;
+ WipeReason = "Manifest schema version: {}, differs from required: {}"_format(ManifestVersion, ZEN_SCHEMA_VERSION);
+ }
+ }
+ }
+
+ // Handle any state wipe
+
+ if (WipeState)
+ {
+ ZEN_WARN("Wiping state at '{}' - reason: '{}'", m_DataRoot, WipeReason);
+
+ std::error_code Ec;
+ for (const std::filesystem::directory_entry& DirEntry : std::filesystem::directory_iterator{m_DataRoot, Ec})
+ {
+ if (DirEntry.is_directory() && (DirEntry.path().filename() != "logs"))
+ {
+ ZEN_INFO("Deleting '{}'", DirEntry.path());
+
+ std::filesystem::remove_all(DirEntry.path(), Ec);
+
+ if (Ec)
+ {
+ ZEN_WARN("Delete of '{}' returned error: '{}'", DirEntry.path(), Ec.message());
+ }
+ }
+ }
+
+ ZEN_INFO("Wiped all directories in data root");
+
+ UpdateManifest = true;
+ }
+
+ if (UpdateManifest)
+ {
+ // Write new manifest
+
+ const DateTime Now = DateTime::Now();
+
+ CbObjectWriter Cbo;
+ Cbo << "schema_version" << ZEN_SCHEMA_VERSION << "created" << Now << "updated" << Now << "state_id" << Oid::NewOid();
+ Cbo << m_RootManifest["id"];
+
+ m_RootManifest = Cbo.Save();
+
+ WriteFile(ManifestPath, m_RootManifest.GetBuffer().AsIoBuffer());
+ }
+}
+
+void
ZenServer::InitializeStructuredCache(ZenServiceConfig& ServiceConfig)
{
using namespace std::literals;
@@ -776,6 +803,13 @@ main(int argc, char* argv[])
ZenServerOptions GlobalOptions;
ZenServiceConfig ServiceConfig;
ParseGlobalCliOptions(argc, argv, GlobalOptions, ServiceConfig);
+
+ if (!std::filesystem::exists(GlobalOptions.DataDir))
+ {
+ ServiceConfig.IsFirstRun = true;
+ std::filesystem::create_directories(GlobalOptions.DataDir);
+ }
+
InitializeLogging(GlobalOptions);
#if ZEN_PLATFORM_WINDOWS