diff options
| author | Stefan Boberg <[email protected]> | 2021-10-21 14:09:50 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-10-21 14:10:50 +0200 |
| commit | 2c33581be75f855d9a83dabfeba5663e69cc8afa (patch) | |
| tree | b01839a9baffafb6eec394293d6ef1a9c1934e3d | |
| parent | zenserver: don't try to delete the logs directory when wiping state (diff) | |
| download | zen-2c33581be75f855d9a83dabfeba5663e69cc8afa.tar.xz zen-2c33581be75f855d9a83dabfeba5663e69cc8afa.zip | |
zenserver: Tweaked state initialization so we know when we're running for the first time and don't need to log about missing manifests
| -rw-r--r-- | zenserver/config.h | 1 | ||||
| -rw-r--r-- | zenserver/zenserver.cpp | 178 |
2 files changed, 107 insertions, 72 deletions
diff --git a/zenserver/config.h b/zenserver/config.h index d68549616..2a5a17fb9 100644 --- a/zenserver/config.h +++ b/zenserver/config.h @@ -65,6 +65,7 @@ struct ZenServiceConfig { bool StructuredCacheEnabled = true; bool ShouldCrash = false; // Option for testing crash handling + bool IsFirstRun = false; #if ZEN_ENABLE_MESH bool MeshEnabled = false; // Experimental p2p mesh discovery #endif 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 |