Initialize namespaces without using `overrideFrozen`

This commit adds a new initialization priority `FreezeNamespaces` that is run
last and moves all calls to `Namespace::Freeze()` there. This allows all other
initialization functions to still update namespaces without the use of the
`overrideFrozen` flag.

It also moves the initialization of `System.Platform*` and `System.Build*` to
an initialize function so that these can also be set without setting
`overrideFrozen`.

This is preparation for a following commit that will make the frozen flag in
namespaces finial, no longer allowing it to be overriden (freezing the
namespace will disable locking, so performing further updates would be unsafe).
This commit is contained in:
Julian Brost 2023-01-09 17:09:46 +01:00
parent a0286e9c64
commit 0503ca1379
12 changed files with 102 additions and 98 deletions

View File

@ -280,17 +280,6 @@ static int Main()
#endif /* RLIMIT_STACK */
}
/* Calculate additional global constants. */
ScriptGlobal::Set("System.PlatformKernel", Utility::GetPlatformKernel(), true);
ScriptGlobal::Set("System.PlatformKernelVersion", Utility::GetPlatformKernelVersion(), true);
ScriptGlobal::Set("System.PlatformName", Utility::GetPlatformName(), true);
ScriptGlobal::Set("System.PlatformVersion", Utility::GetPlatformVersion(), true);
ScriptGlobal::Set("System.PlatformArchitecture", Utility::GetPlatformArchitecture(), true);
ScriptGlobal::Set("System.BuildHostName", ICINGA_BUILD_HOST_NAME, true);
ScriptGlobal::Set("System.BuildCompilerName", ICINGA_BUILD_COMPILER_NAME, true);
ScriptGlobal::Set("System.BuildCompilerVersion", ICINGA_BUILD_COMPILER_VERSION, true);
if (!autocomplete)
Application::SetResourceLimits();

View File

@ -25,6 +25,7 @@ enum class InitializePriority {
RegisterTypes,
EvaluateConfigFragments,
Default,
FreezeNamespaces,
};
#define I2_TOKENPASTE(x, y) x ## y

View File

@ -40,11 +40,11 @@ std::mutex Logger::m_UpdateMinLogSeverityMutex;
Atomic<LogSeverity> Logger::m_MinLogSeverity (LogDebug);
INITIALIZE_ONCE([]() {
ScriptGlobal::Set("System.LogDebug", LogDebug, true);
ScriptGlobal::Set("System.LogNotice", LogNotice, true);
ScriptGlobal::Set("System.LogInformation", LogInformation, true);
ScriptGlobal::Set("System.LogWarning", LogWarning, true);
ScriptGlobal::Set("System.LogCritical", LogCritical, true);
ScriptGlobal::Set("System.LogDebug", LogDebug);
ScriptGlobal::Set("System.LogNotice", LogNotice);
ScriptGlobal::Set("System.LogInformation", LogInformation);
ScriptGlobal::Set("System.LogWarning", LogWarning);
ScriptGlobal::Set("System.LogCritical", LogCritical);
});
/**

View File

@ -5,12 +5,13 @@
#include "base/namespace.hpp"
#include "base/exception.hpp"
#include "base/configuration.hpp"
#include "base/utility.hpp"
using namespace icinga;
boost::thread_specific_ptr<std::stack<ScriptFrame *> > ScriptFrame::m_ScriptFrames;
static Namespace::Ptr l_InternalNS;
static Namespace::Ptr l_SystemNS, l_TypesNS, l_StatsNS, l_InternalNS;
/* Ensure that this gets called with highest priority
* and wins against other static initializers in lib/icinga, etc.
@ -19,27 +20,35 @@ static Namespace::Ptr l_InternalNS;
INITIALIZE_ONCE_WITH_PRIORITY([]() {
Namespace::Ptr globalNS = ScriptGlobal::GetGlobals();
Namespace::Ptr systemNS = new Namespace(true);
systemNS->Freeze();
globalNS->SetAttribute("System", new ConstEmbeddedNamespaceValue(systemNS));
l_SystemNS = new Namespace(true);
l_SystemNS->Set("PlatformKernel", Utility::GetPlatformKernel());
l_SystemNS->Set("PlatformKernelVersion", Utility::GetPlatformKernelVersion());
l_SystemNS->Set("PlatformName", Utility::GetPlatformName());
l_SystemNS->Set("PlatformVersion", Utility::GetPlatformVersion());
l_SystemNS->Set("PlatformArchitecture", Utility::GetPlatformArchitecture());
l_SystemNS->Set("BuildHostName", ICINGA_BUILD_HOST_NAME);
l_SystemNS->Set("BuildCompilerName", ICINGA_BUILD_COMPILER_NAME);
l_SystemNS->Set("BuildCompilerVersion", ICINGA_BUILD_COMPILER_VERSION);
globalNS->SetAttribute("System", new ConstEmbeddedNamespaceValue(l_SystemNS));
systemNS->SetAttribute("Configuration", new EmbeddedNamespaceValue(new Configuration()));
l_SystemNS->SetAttribute("Configuration", new EmbeddedNamespaceValue(new Configuration()));
Namespace::Ptr typesNS = new Namespace(true);
typesNS->Freeze();
globalNS->SetAttribute("Types", new ConstEmbeddedNamespaceValue(typesNS));
l_TypesNS = new Namespace(true);
globalNS->SetAttribute("Types", new ConstEmbeddedNamespaceValue(l_TypesNS));
Namespace::Ptr statsNS = new Namespace(true);
statsNS->Freeze();
globalNS->SetAttribute("StatsFunctions", new ConstEmbeddedNamespaceValue(statsNS));
l_StatsNS = new Namespace(true);
globalNS->SetAttribute("StatsFunctions", new ConstEmbeddedNamespaceValue(l_StatsNS));
l_InternalNS = new Namespace(true);
globalNS->SetAttribute("Internal", new ConstEmbeddedNamespaceValue(l_InternalNS));
}, InitializePriority::CreateNamespaces);
INITIALIZE_ONCE([]() {
INITIALIZE_ONCE_WITH_PRIORITY([]() {
l_SystemNS->Freeze();
l_TypesNS->Freeze();
l_StatsNS->Freeze();
l_InternalNS->Freeze();
});
}, InitializePriority::FreezeNamespaces);
ScriptFrame::ScriptFrame(bool allocLocals)
: Locals(allocLocals ? new Dictionary() : nullptr), Self(ScriptGlobal::GetGlobals()), Sandboxed(false), Depth(0)

View File

@ -71,11 +71,11 @@ enum MatchType
void ScriptUtils::StaticInitialize()
{
ScriptGlobal::Set("System.MatchAll", MatchAll, true);
ScriptGlobal::Set("System.MatchAny", MatchAny, true);
ScriptGlobal::Set("System.MatchAll", MatchAll);
ScriptGlobal::Set("System.MatchAny", MatchAny);
ScriptGlobal::Set("System.GlobFile", GlobFile, true);
ScriptGlobal::Set("System.GlobDirectory", GlobDirectory, true);
ScriptGlobal::Set("System.GlobFile", GlobFile);
ScriptGlobal::Set("System.GlobDirectory", GlobDirectory);
}
String ScriptUtils::CastString(const Value& value)

View File

@ -19,26 +19,26 @@ std::map<String, int> SyslogHelper::m_FacilityMap;
void SyslogHelper::StaticInitialize()
{
ScriptGlobal::Set("System.FacilityAuth", "LOG_AUTH", true);
ScriptGlobal::Set("System.FacilityAuthPriv", "LOG_AUTHPRIV", true);
ScriptGlobal::Set("System.FacilityCron", "LOG_CRON", true);
ScriptGlobal::Set("System.FacilityDaemon", "LOG_DAEMON", true);
ScriptGlobal::Set("System.FacilityFtp", "LOG_FTP", true);
ScriptGlobal::Set("System.FacilityKern", "LOG_KERN", true);
ScriptGlobal::Set("System.FacilityLocal0", "LOG_LOCAL0", true);
ScriptGlobal::Set("System.FacilityLocal1", "LOG_LOCAL1", true);
ScriptGlobal::Set("System.FacilityLocal2", "LOG_LOCAL2", true);
ScriptGlobal::Set("System.FacilityLocal3", "LOG_LOCAL3", true);
ScriptGlobal::Set("System.FacilityLocal4", "LOG_LOCAL4", true);
ScriptGlobal::Set("System.FacilityLocal5", "LOG_LOCAL5", true);
ScriptGlobal::Set("System.FacilityLocal6", "LOG_LOCAL6", true);
ScriptGlobal::Set("System.FacilityLocal7", "LOG_LOCAL7", true);
ScriptGlobal::Set("System.FacilityLpr", "LOG_LPR", true);
ScriptGlobal::Set("System.FacilityMail", "LOG_MAIL", true);
ScriptGlobal::Set("System.FacilityNews", "LOG_NEWS", true);
ScriptGlobal::Set("System.FacilitySyslog", "LOG_SYSLOG", true);
ScriptGlobal::Set("System.FacilityUser", "LOG_USER", true);
ScriptGlobal::Set("System.FacilityUucp", "LOG_UUCP", true);
ScriptGlobal::Set("System.FacilityAuth", "LOG_AUTH");
ScriptGlobal::Set("System.FacilityAuthPriv", "LOG_AUTHPRIV");
ScriptGlobal::Set("System.FacilityCron", "LOG_CRON");
ScriptGlobal::Set("System.FacilityDaemon", "LOG_DAEMON");
ScriptGlobal::Set("System.FacilityFtp", "LOG_FTP");
ScriptGlobal::Set("System.FacilityKern", "LOG_KERN");
ScriptGlobal::Set("System.FacilityLocal0", "LOG_LOCAL0");
ScriptGlobal::Set("System.FacilityLocal1", "LOG_LOCAL1");
ScriptGlobal::Set("System.FacilityLocal2", "LOG_LOCAL2");
ScriptGlobal::Set("System.FacilityLocal3", "LOG_LOCAL3");
ScriptGlobal::Set("System.FacilityLocal4", "LOG_LOCAL4");
ScriptGlobal::Set("System.FacilityLocal5", "LOG_LOCAL5");
ScriptGlobal::Set("System.FacilityLocal6", "LOG_LOCAL6");
ScriptGlobal::Set("System.FacilityLocal7", "LOG_LOCAL7");
ScriptGlobal::Set("System.FacilityLpr", "LOG_LPR");
ScriptGlobal::Set("System.FacilityMail", "LOG_MAIL");
ScriptGlobal::Set("System.FacilityNews", "LOG_NEWS");
ScriptGlobal::Set("System.FacilitySyslog", "LOG_SYSLOG");
ScriptGlobal::Set("System.FacilityUser", "LOG_USER");
ScriptGlobal::Set("System.FacilityUucp", "LOG_UUCP");
m_FacilityMap["LOG_AUTH"] = LOG_AUTH;
m_FacilityMap["LOG_AUTHPRIV"] = LOG_AUTHPRIV;

View File

@ -24,7 +24,7 @@ String Type::ToString() const
void Type::Register(const Type::Ptr& type)
{
ScriptGlobal::Set("Types." + type->GetName(), type, true);
ScriptGlobal::Set("Types." + type->GetName(), type);
}
Type::Ptr Type::GetByName(const String& name)

View File

@ -12,22 +12,22 @@ std::map<String, int> DbQuery::m_CategoryFilterMap;
void DbQuery::StaticInitialize()
{
ScriptGlobal::Set("Icinga.DbCatConfig", DbCatConfig, true);
ScriptGlobal::Set("Icinga.DbCatState", DbCatState, true);
ScriptGlobal::Set("Icinga.DbCatAcknowledgement", DbCatAcknowledgement, true);
ScriptGlobal::Set("Icinga.DbCatComment", DbCatComment, true);
ScriptGlobal::Set("Icinga.DbCatDowntime", DbCatDowntime, true);
ScriptGlobal::Set("Icinga.DbCatEventHandler", DbCatEventHandler, true);
ScriptGlobal::Set("Icinga.DbCatExternalCommand", DbCatExternalCommand, true);
ScriptGlobal::Set("Icinga.DbCatFlapping", DbCatFlapping, true);
ScriptGlobal::Set("Icinga.DbCatCheck", DbCatCheck, true);
ScriptGlobal::Set("Icinga.DbCatLog", DbCatLog, true);
ScriptGlobal::Set("Icinga.DbCatNotification", DbCatNotification, true);
ScriptGlobal::Set("Icinga.DbCatProgramStatus", DbCatProgramStatus, true);
ScriptGlobal::Set("Icinga.DbCatRetention", DbCatRetention, true);
ScriptGlobal::Set("Icinga.DbCatStateHistory", DbCatStateHistory, true);
ScriptGlobal::Set("Icinga.DbCatConfig", DbCatConfig);
ScriptGlobal::Set("Icinga.DbCatState", DbCatState);
ScriptGlobal::Set("Icinga.DbCatAcknowledgement", DbCatAcknowledgement);
ScriptGlobal::Set("Icinga.DbCatComment", DbCatComment);
ScriptGlobal::Set("Icinga.DbCatDowntime", DbCatDowntime);
ScriptGlobal::Set("Icinga.DbCatEventHandler", DbCatEventHandler);
ScriptGlobal::Set("Icinga.DbCatExternalCommand", DbCatExternalCommand);
ScriptGlobal::Set("Icinga.DbCatFlapping", DbCatFlapping);
ScriptGlobal::Set("Icinga.DbCatCheck", DbCatCheck);
ScriptGlobal::Set("Icinga.DbCatLog", DbCatLog);
ScriptGlobal::Set("Icinga.DbCatNotification", DbCatNotification);
ScriptGlobal::Set("Icinga.DbCatProgramStatus", DbCatProgramStatus);
ScriptGlobal::Set("Icinga.DbCatRetention", DbCatRetention);
ScriptGlobal::Set("Icinga.DbCatStateHistory", DbCatStateHistory);
ScriptGlobal::Set("Icinga.DbCatEverything", DbCatEverything, true);
ScriptGlobal::Set("Icinga.DbCatEverything", DbCatEverything);
m_CategoryFilterMap["DbCatConfig"] = DbCatConfig;
m_CategoryFilterMap["DbCatState"] = DbCatState;

View File

@ -9,13 +9,13 @@ using namespace icinga;
REGISTER_TYPE(CheckResult);
INITIALIZE_ONCE([]() {
ScriptGlobal::Set("Icinga.ServiceOK", ServiceOK, true);
ScriptGlobal::Set("Icinga.ServiceWarning", ServiceWarning, true);
ScriptGlobal::Set("Icinga.ServiceCritical", ServiceCritical, true);
ScriptGlobal::Set("Icinga.ServiceUnknown", ServiceUnknown, true);
ScriptGlobal::Set("Icinga.ServiceOK", ServiceOK);
ScriptGlobal::Set("Icinga.ServiceWarning", ServiceWarning);
ScriptGlobal::Set("Icinga.ServiceCritical", ServiceCritical);
ScriptGlobal::Set("Icinga.ServiceUnknown", ServiceUnknown);
ScriptGlobal::Set("Icinga.HostUp", HostUp, true);
ScriptGlobal::Set("Icinga.HostDown", HostDown, true);
ScriptGlobal::Set("Icinga.HostUp", HostUp);
ScriptGlobal::Set("Icinga.HostDown", HostDown);
})
double CheckResult::CalculateExecutionTime() const

View File

@ -31,9 +31,9 @@ INITIALIZE_ONCE(&Downtime::StaticInitialize);
void Downtime::StaticInitialize()
{
ScriptGlobal::Set("Icinga.DowntimeNoChildren", "DowntimeNoChildren", true);
ScriptGlobal::Set("Icinga.DowntimeTriggeredChildren", "DowntimeTriggeredChildren", true);
ScriptGlobal::Set("Icinga.DowntimeNonTriggeredChildren", "DowntimeNonTriggeredChildren", true);
ScriptGlobal::Set("Icinga.DowntimeNoChildren", "DowntimeNoChildren");
ScriptGlobal::Set("Icinga.DowntimeTriggeredChildren", "DowntimeTriggeredChildren");
ScriptGlobal::Set("Icinga.DowntimeNonTriggeredChildren", "DowntimeNonTriggeredChildren");
}
String DowntimeNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const

View File

@ -28,6 +28,8 @@ REGISTER_TYPE(IcingaApplication);
/* Ensure that the priority is lower than the basic System namespace initialization in scriptframe.cpp. */
INITIALIZE_ONCE_WITH_PRIORITY(&IcingaApplication::StaticInitialize, InitializePriority::InitIcingaApplication);
static Namespace::Ptr l_IcingaNS;
void IcingaApplication::StaticInitialize()
{
/* Pre-fill global constants, can be overridden with user input later in icinga-app/icinga.cpp. */
@ -52,17 +54,20 @@ void IcingaApplication::StaticInitialize()
/* Ensure that the System namespace is already initialized. Otherwise this is a programming error. */
VERIFY(systemNS);
systemNS->Set("ApplicationType", "IcingaApplication", true);
systemNS->Set("ApplicationVersion", Application::GetAppVersion(), true);
systemNS->Set("ApplicationType", "IcingaApplication");
systemNS->Set("ApplicationVersion", Application::GetAppVersion());
Namespace::Ptr globalNS = ScriptGlobal::GetGlobals();
VERIFY(globalNS);
Namespace::Ptr icingaNS = new Namespace(true);
icingaNS->Freeze();
globalNS->SetAttribute("Icinga", new ConstEmbeddedNamespaceValue(icingaNS));
l_IcingaNS = new Namespace(true);
globalNS->SetAttribute("Icinga", new ConstEmbeddedNamespaceValue(l_IcingaNS));
}
INITIALIZE_ONCE_WITH_PRIORITY([]() {
l_IcingaNS->Freeze();
}, InitializePriority::FreezeNamespaces);
REGISTER_STATSFUNCTION(IcingaApplication, &IcingaApplication::StatsFunc);
void IcingaApplication::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata)

View File

@ -63,22 +63,22 @@ Dictionary::Ptr NotificationNameComposer::ParseName(const String& name) const
void Notification::StaticInitialize()
{
ScriptGlobal::Set("Icinga.OK", "OK", true);
ScriptGlobal::Set("Icinga.Warning", "Warning", true);
ScriptGlobal::Set("Icinga.Critical", "Critical", true);
ScriptGlobal::Set("Icinga.Unknown", "Unknown", true);
ScriptGlobal::Set("Icinga.Up", "Up", true);
ScriptGlobal::Set("Icinga.Down", "Down", true);
ScriptGlobal::Set("Icinga.OK", "OK");
ScriptGlobal::Set("Icinga.Warning", "Warning");
ScriptGlobal::Set("Icinga.Critical", "Critical");
ScriptGlobal::Set("Icinga.Unknown", "Unknown");
ScriptGlobal::Set("Icinga.Up", "Up");
ScriptGlobal::Set("Icinga.Down", "Down");
ScriptGlobal::Set("Icinga.DowntimeStart", "DowntimeStart", true);
ScriptGlobal::Set("Icinga.DowntimeEnd", "DowntimeEnd", true);
ScriptGlobal::Set("Icinga.DowntimeRemoved", "DowntimeRemoved", true);
ScriptGlobal::Set("Icinga.Custom", "Custom", true);
ScriptGlobal::Set("Icinga.Acknowledgement", "Acknowledgement", true);
ScriptGlobal::Set("Icinga.Problem", "Problem", true);
ScriptGlobal::Set("Icinga.Recovery", "Recovery", true);
ScriptGlobal::Set("Icinga.FlappingStart", "FlappingStart", true);
ScriptGlobal::Set("Icinga.FlappingEnd", "FlappingEnd", true);
ScriptGlobal::Set("Icinga.DowntimeStart", "DowntimeStart");
ScriptGlobal::Set("Icinga.DowntimeEnd", "DowntimeEnd");
ScriptGlobal::Set("Icinga.DowntimeRemoved", "DowntimeRemoved");
ScriptGlobal::Set("Icinga.Custom", "Custom");
ScriptGlobal::Set("Icinga.Acknowledgement", "Acknowledgement");
ScriptGlobal::Set("Icinga.Problem", "Problem");
ScriptGlobal::Set("Icinga.Recovery", "Recovery");
ScriptGlobal::Set("Icinga.FlappingStart", "FlappingStart");
ScriptGlobal::Set("Icinga.FlappingEnd", "FlappingEnd");
m_StateFilterMap["OK"] = StateFilterOK;
m_StateFilterMap["Warning"] = StateFilterWarning;