Merge pull request #9648 from Icinga/frozen-namespace-config-validation

Fix config sync after freezing namespaces
This commit is contained in:
Alexander Aleksandrovič Klimov 2023-02-01 17:07:57 +01:00 committed by GitHub
commit 4e021e0105
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 17 additions and 11 deletions

View File

@ -427,8 +427,13 @@ static int Main()
std::unique_ptr<SetExpression> setExpr{new SetExpression(std::move(expr), OpSetLiteral, MakeLiteral(value))};
setExpr->SetOverrideFrozen();
ScriptFrame frame(true);
setExpr->Evaluate(frame);
try {
ScriptFrame frame(true);
setExpr->Evaluate(frame);
} catch (const ScriptError& e) {
Log(LogCritical, "icinga-app") << "cannot set '" << key << "': " << e.what();
return EXIT_FAILURE;
}
}
}

View File

@ -11,7 +11,7 @@ using namespace icinga;
boost::thread_specific_ptr<std::stack<ScriptFrame *> > ScriptFrame::m_ScriptFrames;
static Namespace::Ptr l_SystemNS, l_StatsNS, l_InternalNS;
static Namespace::Ptr l_SystemNS, l_StatsNS;
/* Ensure that this gets called with highest priority
* and wins against other static initializers in lib/icinga, etc.
@ -36,14 +36,12 @@ INITIALIZE_ONCE_WITH_PRIORITY([]() {
l_StatsNS = new Namespace(true);
globalNS->Set("StatsFunctions", l_StatsNS, true);
l_InternalNS = new Namespace(true);
globalNS->Set("Internal", l_InternalNS, true);
globalNS->Set("Internal", new Namespace(true), true);
}, InitializePriority::CreateNamespaces);
INITIALIZE_ONCE_WITH_PRIORITY([]() {
l_SystemNS->Freeze();
l_StatsNS->Freeze();
l_InternalNS->Freeze();
}, InitializePriority::FreezeNamespaces);
ScriptFrame::ScriptFrame(bool allocLocals)

View File

@ -111,6 +111,9 @@ bool DaemonUtility::ValidateConfigFiles(const std::vector<std::string>& configs,
Namespace::Ptr systemNS = ScriptGlobal::Get("System");
VERIFY(systemNS);
Namespace::Ptr internalNS = ScriptGlobal::Get("Internal");
VERIFY(internalNS);
if (!objectsFile.IsEmpty())
ConfigCompilerContext::GetInstance()->OpenObjectsFile(objectsFile);
@ -134,7 +137,7 @@ bool DaemonUtility::ValidateConfigFiles(const std::vector<std::string>& configs,
success = true;
/* Only load zone directory if we're not in staging validation. */
if (!systemNS->Contains("ZonesStageVarDir")) {
if (!internalNS->Contains("ZonesStageVarDir")) {
String zonesEtcDir = Configuration::ZonesDir;
if (!zonesEtcDir.IsEmpty() && Utility::PathExists(zonesEtcDir)) {
std::set<String> zoneEtcDirs;
@ -177,8 +180,8 @@ bool DaemonUtility::ValidateConfigFiles(const std::vector<std::string>& configs,
String zonesVarDir = Configuration::DataDir + "/api/zones";
/* Cluster config sync stage validation needs this. */
if (systemNS->Contains("ZonesStageVarDir")) {
zonesVarDir = systemNS->Get("ZonesStageVarDir");
if (internalNS->Contains("ZonesStageVarDir")) {
zonesVarDir = internalNS->Get("ZonesStageVarDir");
Log(LogNotice, "DaemonUtility")
<< "Overriding zones var directory with '" << zonesVarDir << "' for cluster config sync staging.";

View File

@ -554,7 +554,7 @@ void ApiListener::HandleConfigUpdate(const MessageOrigin::Ptr& origin, const Dic
}
/**
* Spawns a new validation process with 'System.ZonesStageVarDir' set to override the config validation zone dirs with
* Spawns a new validation process with 'Internal.ZonesStageVarDir' set to override the config validation zone dirs with
* our current stage. Then waits for the validation result and if it was successful, the configuration is copied from
* stage to production and a restart is triggered. On validation failure, there is no restart and this is logged.
*
@ -584,7 +584,7 @@ void ApiListener::TryActivateZonesStage(const std::vector<String>& relativePaths
// Set the ZonesStageDir. This creates our own local chroot without any additional automated zone includes.
args->Add("--define");
args->Add("System.ZonesStageVarDir=" + GetApiZonesStageDir());
args->Add("Internal.ZonesStageVarDir=" + GetApiZonesStageDir());
Process::Ptr process = new Process(Process::PrepareCommand(args));
process->SetTimeout(Application::GetReloadTimeout());