From 9c00ae53b386dfd1939ddbe845acaed41d1a23d3 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 6 Aug 2020 16:56:13 +0200 Subject: [PATCH 1/4] modified-attributes.conf: store attributes to modify in Internal.modified_attributes --- lib/base/scriptframe.cpp | 4 +++- lib/icinga/icingaapplication.cpp | 14 +++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/base/scriptframe.cpp b/lib/base/scriptframe.cpp index 7a7f44c5f..6fb0a6ca4 100644 --- a/lib/base/scriptframe.cpp +++ b/lib/base/scriptframe.cpp @@ -36,7 +36,9 @@ INITIALIZE_ONCE_WITH_PRIORITY([]() { l_StatsNS = new Namespace(true); globalNS->Set("StatsFunctions", l_StatsNS, true); - globalNS->Set("Internal", new Namespace(), true); + Namespace::Ptr intNS = new Namespace(); + intNS->Set("modified_attributes", new Dictionary(), true); + globalNS->Set("Internal", intNS, true); }, InitializePriority::CreateNamespaces); INITIALIZE_ONCE_WITH_PRIORITY([]() { diff --git a/lib/icinga/icingaapplication.cpp b/lib/icinga/icingaapplication.cpp index 94ae0ede7..14194166f 100644 --- a/lib/icinga/icingaapplication.cpp +++ b/lib/icinga/icingaapplication.cpp @@ -135,15 +135,11 @@ static void PersistModAttrHelper(AtomicFile& fp, ConfigObject::Ptr& previousObje ConfigWriter::EmitRaw(fp, "\n}\n\n"); } - ConfigWriter::EmitRaw(fp, "var obj = "); - - Array::Ptr args1 = new Array({ - object->GetReflectionType()->GetName(), - object->GetName() - }); - ConfigWriter::EmitFunctionCall(fp, "get_object", args1); - - ConfigWriter::EmitRaw(fp, "\nif (obj) {\n"); + ConfigWriter::EmitRaw(fp, "Internal.modified_attributes["); + ConfigWriter::EmitValue(fp, 0, object->GetReflectionType()->GetName()); + ConfigWriter::EmitRaw(fp, "]["); + ConfigWriter::EmitValue(fp, 0, object->GetName()); + ConfigWriter::EmitRaw(fp, "] = obj => {\n"); } ConfigWriter::EmitRaw(fp, "\tobj."); From 22640444dd8674c77ba8a35862b8e33bb340b06f Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 6 Aug 2020 17:13:41 +0200 Subject: [PATCH 2/4] Load modified-attributes.conf before committing config items refs #5235 --- lib/cli/daemonutility.cpp | 2 +- lib/config/configitem.cpp | 19 ++++++++++++++++++- lib/config/configitem.hpp | 3 ++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/cli/daemonutility.cpp b/lib/cli/daemonutility.cpp index 5e250d22c..6067e1ec8 100644 --- a/lib/cli/daemonutility.cpp +++ b/lib/cli/daemonutility.cpp @@ -254,7 +254,7 @@ bool DaemonUtility::LoadConfigFiles(const std::vector& configs, WorkQueue upq(25000, Configuration::Concurrency); upq.SetName("DaemonUtility::LoadConfigFiles"); - bool result = ConfigItem::CommitItems(ascope.GetContext(), upq, newItems); + bool result = ConfigItem::CommitItems(ascope.GetContext(), upq, newItems, false, true); if (!result) { ConfigCompilerContext::GetInstance()->CancelObjectsFile(); diff --git a/lib/config/configitem.cpp b/lib/config/configitem.cpp index 5dce19eda..43eb44816 100644 --- a/lib/config/configitem.cpp +++ b/lib/config/configitem.cpp @@ -592,11 +592,28 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue return true; } -bool ConfigItem::CommitItems(const ActivationContext::Ptr& context, WorkQueue& upq, std::vector& newItems, bool silent) +bool ConfigItem::CommitItems(const ActivationContext::Ptr& context, WorkQueue& upq, std::vector& newItems, + bool silent, bool withModAttrs) { if (!silent) Log(LogInformation, "ConfigItem", "Committing config item(s)."); + if (withModAttrs) { + /* restore modified attributes */ + if (Utility::PathExists(Configuration::ModAttrPath)) { + std::unique_ptr expression = ConfigCompiler::CompileFile(Configuration::ModAttrPath); + + if (expression) { + try { + ScriptFrame frame(true); + expression->Evaluate(frame); + } catch (const std::exception& ex) { + Log(LogCritical, "config", DiagnosticInformation(ex)); + } + } + } + } + if (!CommitNewItems(context, upq, newItems)) { upq.ReportExceptions("config"); diff --git a/lib/config/configitem.hpp b/lib/config/configitem.hpp index 007a3c08a..f075bc980 100644 --- a/lib/config/configitem.hpp +++ b/lib/config/configitem.hpp @@ -52,7 +52,8 @@ public: static ConfigItem::Ptr GetByTypeAndName(const Type::Ptr& type, const String& name); - static bool CommitItems(const ActivationContext::Ptr& context, WorkQueue& upq, std::vector& newItems, bool silent = false); + static bool CommitItems(const ActivationContext::Ptr& context, WorkQueue& upq, std::vector& newItems, + bool silent = false, bool withModAttrs = false); static bool ActivateItems(const std::vector& newItems, bool runtimeCreated = false, bool mainConfigActivation = false, bool withModAttrs = false, const Value& cookie = Empty); From deda50fefe91d90298805919169e3b679fbe5b7d Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 6 Aug 2020 17:56:53 +0200 Subject: [PATCH 3/4] ConfigItem#Commit(): consume Internal.modified_attributes refs #5235 --- lib/config/configitem.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/config/configitem.cpp b/lib/config/configitem.cpp index 43eb44816..1054a7ca8 100644 --- a/lib/config/configitem.cpp +++ b/lib/config/configitem.cpp @@ -191,6 +191,20 @@ ConfigObject::Ptr ConfigItem::Commit(bool discard) m_Scope->CopyTo(frame.Locals); try { m_Expression->Evaluate(frame, &debugHints); + + Dictionary::Ptr allMods (Namespace::Ptr(ScriptGlobal::Get("Internal"))->Get("modified_attributes")); + Dictionary::Ptr typeMods (allMods->Get(type->GetName())); + + if (typeMods) { + Function::Ptr objMods (typeMods->Get(m_Name)); + + if (objMods) { + objMods->Invoke({dobj}); + + ObjectLock oLock(typeMods); + typeMods->Remove(m_Name); + } + } } catch (const std::exception& ex) { if (m_IgnoreOnError) { Log(LogNotice, "ConfigObject") From 48cfffaba9dadb972c6c5a49a981ec715c432ed8 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 6 Aug 2020 17:57:30 +0200 Subject: [PATCH 4/4] Load modified-attributes.conf twice only during migration refs #5235 --- lib/config/configitem.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/config/configitem.cpp b/lib/config/configitem.cpp index 1054a7ca8..606d0c629 100644 --- a/lib/config/configitem.cpp +++ b/lib/config/configitem.cpp @@ -678,7 +678,9 @@ bool ConfigItem::ActivateItems(const std::vector& newItems, boo if (withModAttrs) { /* restore modified attributes */ - if (Utility::PathExists(Configuration::ModAttrPath)) { + if (Utility::PathExists(Configuration::ModAttrPath) && + !Dictionary::Ptr(Namespace::Ptr(ScriptGlobal::Get("Internal"))->Get("modified_attributes"))->GetLength() + ) { std::unique_ptr expression = ConfigCompiler::CompileFile(Configuration::ModAttrPath); if (expression) {