mirror of
https://github.com/Icinga/icinga2.git
synced 2025-09-24 10:17:59 +02:00
parent
a65f2d6b41
commit
9c4f26bd60
@ -7,6 +7,7 @@
|
||||
#include "base/logger.hpp"
|
||||
#include "base/application.hpp"
|
||||
#include "base/scriptglobal.hpp"
|
||||
#include "config/commitcontext.hpp"
|
||||
#include "config/configcompiler.hpp"
|
||||
#include "config/configcompilercontext.hpp"
|
||||
#include "config/configitembuilder.hpp"
|
||||
@ -240,6 +241,7 @@ bool DaemonUtility::LoadConfigFiles(const std::vector<std::string>& configs,
|
||||
std::vector<ConfigItem::Ptr>& newItems,
|
||||
const String& objectsFile, const String& varsfile)
|
||||
{
|
||||
CommitContext cc;
|
||||
ActivationScope ascope;
|
||||
|
||||
if (!DaemonUtility::ValidateConfigFiles(configs, objectsFile)) {
|
||||
@ -254,7 +256,7 @@ bool DaemonUtility::LoadConfigFiles(const std::vector<std::string>& 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) && cc.RunOnConfigCommitted();
|
||||
|
||||
if (!result) {
|
||||
ConfigCompilerContext::GetInstance()->CancelObjectsFile();
|
||||
|
@ -22,6 +22,7 @@ set(config_SOURCES
|
||||
i2-config.hpp
|
||||
activationcontext.cpp activationcontext.hpp
|
||||
applyrule.cpp applyrule-targeted.cpp applyrule.hpp
|
||||
commitcontext.cpp commitcontext.hpp
|
||||
configcompiler.cpp configcompiler.hpp
|
||||
configcompilercontext.cpp configcompilercontext.hpp
|
||||
configfragment.hpp
|
||||
|
7
lib/config/commitcontext.cpp
Normal file
7
lib/config/commitcontext.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
/* Icinga 2 | (c) 2019 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#include "config/commitcontext.hpp"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
thread_local CommitContext* CommitContext::m_Current = nullptr;
|
86
lib/config/commitcontext.hpp
Normal file
86
lib/config/commitcontext.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
/* Icinga 2 | (c) 2019 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#ifndef COMMITCONTEXT_H
|
||||
#define COMMITCONTEXT_H
|
||||
|
||||
#include "base/debug.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include "base/logger.hpp"
|
||||
#include "base/scriptframe.hpp"
|
||||
#include "config/expression.hpp"
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
class CommitContext
|
||||
{
|
||||
public:
|
||||
static inline
|
||||
CommitContext* GetCurrent()
|
||||
{
|
||||
return m_Current;
|
||||
}
|
||||
|
||||
inline CommitContext() : m_Started(false)
|
||||
{
|
||||
VERIFY(!m_Current);
|
||||
|
||||
m_Current = this;
|
||||
}
|
||||
|
||||
CommitContext(const CommitContext&) = delete;
|
||||
CommitContext(CommitContext&&) = delete;
|
||||
CommitContext& operator=(const CommitContext&) = delete;
|
||||
CommitContext& operator=(CommitContext&&) = delete;
|
||||
|
||||
inline ~CommitContext()
|
||||
{
|
||||
VERIFY(m_Current);
|
||||
|
||||
m_Current = nullptr;
|
||||
}
|
||||
|
||||
inline void RegisterOnConfigCommitted(std::shared_ptr<Expression> expr)
|
||||
{
|
||||
m_OnConfigCommitted.emplace_back(std::move(expr));
|
||||
}
|
||||
|
||||
inline bool RunOnConfigCommitted()
|
||||
{
|
||||
m_Started = true;
|
||||
|
||||
for (auto& expr : m_OnConfigCommitted) {
|
||||
if (!expr)
|
||||
return false;
|
||||
|
||||
try {
|
||||
ScriptFrame frame(false);
|
||||
expr->Evaluate(frame);
|
||||
} catch (const std::exception& ex) {
|
||||
Log(LogCritical, "config", DiagnosticInformation(ex));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool HasStarted()
|
||||
{
|
||||
return m_Started;
|
||||
}
|
||||
|
||||
private:
|
||||
static thread_local CommitContext* m_Current;
|
||||
|
||||
std::vector<std::shared_ptr<Expression>> m_OnConfigCommitted;
|
||||
bool m_Started;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* COMMITCONTEXT_H */
|
@ -156,6 +156,7 @@ template return T_TEMPLATE;
|
||||
include return T_INCLUDE;
|
||||
include_recursive return T_INCLUDE_RECURSIVE;
|
||||
include_zones return T_INCLUDE_ZONES;
|
||||
on_config_committed return T_ON_CONFIG_COMMITTED;
|
||||
library return T_LIBRARY;
|
||||
null return T_NULL;
|
||||
true { yylval->boolean = 1; return T_BOOLEAN; }
|
||||
|
@ -140,6 +140,7 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
|
||||
%token T_INCLUDE "include (T_INCLUDE)"
|
||||
%token T_INCLUDE_RECURSIVE "include_recursive (T_INCLUDE_RECURSIVE)"
|
||||
%token T_INCLUDE_ZONES "include_zones (T_INCLUDE_ZONES)"
|
||||
%token T_ON_CONFIG_COMMITTED "on_config_committed (T_ON_CONFIG_COMMITTED)"
|
||||
%token T_LIBRARY "library (T_LIBRARY)"
|
||||
%token T_APPLY "apply (T_APPLY)"
|
||||
%token T_TO "to (T_TO)"
|
||||
@ -195,6 +196,7 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
|
||||
|
||||
%right T_FOLLOWS
|
||||
%right T_INCLUDE T_INCLUDE_RECURSIVE T_INCLUDE_ZONES T_OBJECT T_TEMPLATE T_APPLY T_IMPORT T_ASSIGN T_IGNORE T_WHERE
|
||||
%right T_ON_CONFIG_COMMITTED
|
||||
%right T_FUNCTION T_FOR
|
||||
%left T_SET T_SET_ADD T_SET_SUBTRACT T_SET_MULTIPLY T_SET_DIVIDE T_SET_MODULO T_SET_XOR T_SET_BINARY_AND T_SET_BINARY_OR
|
||||
%right '?' ':'
|
||||
@ -563,6 +565,10 @@ lterm: T_LIBRARY rterm
|
||||
|
||||
$$ = MakeLiteralRaw();
|
||||
}
|
||||
| T_ON_CONFIG_COMMITTED rterm
|
||||
{
|
||||
$$ = new OnConfigCommittedExpression(std::shared_ptr<Expression>($2), @$);
|
||||
}
|
||||
| T_RETURN optional_rterm
|
||||
{
|
||||
UseFlowControl(context, FlowControlReturn, @$);
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#include "config/expression.hpp"
|
||||
#include "config/commitcontext.hpp"
|
||||
#include "config/configitem.hpp"
|
||||
#include "config/configcompiler.hpp"
|
||||
#include "config/vmops.hpp"
|
||||
@ -1046,6 +1047,22 @@ ExpressionResult IncludeExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dh
|
||||
return res;
|
||||
}
|
||||
|
||||
ExpressionResult OnConfigCommittedExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
|
||||
{
|
||||
if (frame.Sandboxed)
|
||||
BOOST_THROW_EXCEPTION(ScriptError("on_config_committed is not allowed in sandbox mode.", m_DebugInfo));
|
||||
|
||||
auto cc (CommitContext::GetCurrent());
|
||||
|
||||
if (!cc || cc->HasStarted()) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("on_config_committed is not allowed after the config has been committed.", m_DebugInfo));
|
||||
}
|
||||
|
||||
cc->RegisterOnConfigCommitted(m_Expr);
|
||||
|
||||
return Empty;
|
||||
}
|
||||
|
||||
ExpressionResult BreakpointExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
|
||||
{
|
||||
ScriptBreakpoint(frame, nullptr, GetDebugInfo());
|
||||
|
@ -955,6 +955,20 @@ private:
|
||||
String m_Package;
|
||||
};
|
||||
|
||||
class OnConfigCommittedExpression final : public DebuggableExpression
|
||||
{
|
||||
public:
|
||||
OnConfigCommittedExpression(std::shared_ptr<Expression> expr, const DebugInfo& debugInfo = DebugInfo())
|
||||
: DebuggableExpression(debugInfo), m_Expr(std::move(expr))
|
||||
{ }
|
||||
|
||||
protected:
|
||||
ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Expression> m_Expr;
|
||||
};
|
||||
|
||||
class BreakpointExpression final : public DebuggableExpression
|
||||
{
|
||||
public:
|
||||
|
Loading…
x
Reference in New Issue
Block a user