Skip to content

Commit c54e042

Browse files
CrunsherMichael Friedrich
authored and
Michael Friedrich
committed
Add activation priorities for config object types
This patch ensures that specific configuration types are pre-activated and post-activated. In general, logging is first, then common configuration objects like host/service, downtimes, etc. In the end, all features are activated after to ensure that notifications are only sent once downtimes are applied. A similar thing happens for starting with checks too early. The ApiListener feature runs first to allow cluster connections at first glance. fixes #6057 fixes #6231
1 parent 69f339d commit c54e042

25 files changed

+92
-8
lines changed

lib/base/filelogger.ti

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace icinga
2626

2727
class FileLogger : StreamLogger
2828
{
29+
activation_priority -100;
30+
2931
[config, required] String path;
3032
};
3133

lib/base/sysloglogger.ti

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace icinga
2626

2727
class SyslogLogger : Logger
2828
{
29+
activation_priority -100;
30+
2931
[config] String facility {
3032
default {{{ return "LOG_USER"; }}}
3133
};

lib/base/type.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,11 @@ std::vector<String> Type::GetLoadDependencies() const
154154
return std::vector<String>();
155155
}
156156

157+
int Type::GetActivationPriority() const
158+
{
159+
return 0;
160+
}
161+
157162
void Type::RegisterAttributeHandler(int fieldId, const AttributeHandler& callback)
158163
{
159164
throw std::runtime_error("Invalid field ID.");

lib/base/type.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class Type : public Object
103103
Value GetField(int id) const override;
104104

105105
virtual std::vector<String> GetLoadDependencies() const;
106+
virtual int GetActivationPriority() const;
106107

107108
typedef std::function<void (const Object::Ptr&, const Value&)> AttributeHandler;
108109
virtual void RegisterAttributeHandler(int fieldId, const AttributeHandler& callback);

lib/checker/checkercomponent.ti

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace icinga
2626

2727
class CheckerComponent : ConfigObject
2828
{
29+
activation_priority 100;
30+
2931
[config] int concurrent_checks {
3032
get {{{
3133
return Application::GetMaxConcurrentChecks();

lib/compat/checkresultreader.ti

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ namespace icinga
2727

2828
class CheckResultReader : ConfigObject
2929
{
30+
activation_priority 100;
31+
3032
[config] String spool_dir {
3133
default {{{ return Application::GetLocalStateDir() + "/lib/icinga2/spool/checkresults/"; }}}
3234
};

lib/compat/compatlogger.ti

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ namespace icinga
2727

2828
class CompatLogger : ConfigObject
2929
{
30+
activation_priority 100;
31+
3032
[config] String log_dir {
3133
default {{{ return Application::GetLocalStateDir() + "/log/icinga2/compat"; }}}
3234
};

lib/compat/externalcommandlistener.ti

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ namespace icinga
2727

2828
class ExternalCommandListener : ConfigObject
2929
{
30+
activation_priority 100;
31+
3032
[config] String command_path {
3133
default {{{ return Application::GetRunDir() + "/icinga2/cmd/icinga2.cmd"; }}}
3234
};

lib/compat/statusdatawriter.ti

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ namespace icinga
2727

2828
class StatusDataWriter : ConfigObject
2929
{
30+
activation_priority 100;
31+
3032
[config] String status_path {
3133
default {{{ return Application::GetLocalStateDir() + "/cache/icinga2/status.dat"; }}}
3234
};

lib/config/configitem.cpp

+24-7
Original file line numberDiff line numberDiff line change
@@ -602,18 +602,35 @@ bool ConfigItem::ActivateItems(WorkQueue& upq, const std::vector<ConfigItem::Ptr
602602
if (!silent)
603603
Log(LogInformation, "ConfigItem", "Triggering Start signal for config items");
604604

605-
for (const ConfigItem::Ptr& item : newItems) {
606-
if (!item->m_Object)
607-
continue;
605+
/* Activate objects in priority order. */
606+
std::vector<Type::Ptr> types = Type::GetAllTypes();
608607

609-
ConfigObject::Ptr object = item->m_Object;
608+
std::sort(types.begin(), types.end(), [](const Type::Ptr& a, const Type::Ptr& b) {
609+
if (a->GetActivationPriority() < b->GetActivationPriority())
610+
return true;
611+
return false;
612+
});
613+
614+
for (const Type::Ptr& type : types) {
615+
for (const ConfigItem::Ptr& item : newItems) {
616+
if (!item->m_Object)
617+
continue;
618+
619+
ConfigObject::Ptr object = item->m_Object;
620+
Type::Ptr objectType = object->GetReflectionType();
621+
622+
if (objectType != type)
623+
continue;
610624

611625
#ifdef I2_DEBUG
612-
Log(LogDebug, "ConfigItem")
613-
<< "Activating object '" << object->GetName() << "' of type '" << object->GetReflectionType()->GetName() << "'";
626+
Log(LogDebug, "ConfigItem")
627+
<< "Activating object '" << object->GetName() << "' of type '"
628+
<< objectType->GetName() << "' with priority '"
629+
<< objectType->GetActivationPriority();
614630
#endif /* I2_DEBUG */
615631

616-
object->Activate(runtimeCreated);
632+
object->Activate(runtimeCreated);
633+
}
617634
}
618635

619636
upq.Join();

lib/db_ido_mysql/idomysqlconnection.ti

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace icinga
2626

2727
class IdoMysqlConnection : DbConnection
2828
{
29+
activation_priority 100;
30+
2931
[config] String host {
3032
default {{{ return "localhost"; }}}
3133
};

lib/db_ido_pgsql/idopgsqlconnection.ti

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace icinga
2626

2727
class IdoPgsqlConnection : DbConnection
2828
{
29+
activation_priority 100;
30+
2931
[config] String host {
3032
default {{{ return "localhost"; }}}
3133
};

lib/livestatus/livestatuslistener.ti

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace icinga
2626
{
2727

2828
class LivestatusListener : ConfigObject {
29+
activation_priority 100;
30+
2931
[config] String socket_type {
3032
default {{{ return "unix"; }}}
3133
};

lib/notification/notificationcomponent.ti

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace icinga
2626

2727
class NotificationComponent : ConfigObject
2828
{
29+
activation_priority 100;
30+
2931
[config] bool enable_ha (EnableHA) {
3032
default {{{ return true; }}}
3133
};

lib/perfdata/elasticsearchwriter.ti

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ namespace icinga
77

88
class ElasticsearchWriter : ConfigObject
99
{
10+
activation_priority 100;
11+
1012
[config, required] String host {
1113
default {{{ return "127.0.0.1"; }}}
1214
};

lib/perfdata/gelfwriter.ti

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace icinga
2626

2727
class GelfWriter : ConfigObject
2828
{
29+
activation_priority 100;
30+
2931
[config] String host {
3032
default {{{ return "127.0.0.1"; }}}
3133
};

lib/perfdata/graphitewriter.ti

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace icinga
2626

2727
class GraphiteWriter : ConfigObject
2828
{
29+
activation_priority 100;
30+
2931
[config] String host {
3032
default {{{ return "127.0.0.1"; }}}
3133
};

lib/perfdata/influxdbwriter.ti

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace icinga
2626

2727
class InfluxdbWriter : ConfigObject
2828
{
29+
activation_priority 100;
30+
2931
[config, required] String host {
3032
default {{{ return "127.0.0.1"; }}}
3133
};

lib/perfdata/opentsdbwriter.ti

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace icinga
2626

2727
class OpenTsdbWriter : ConfigObject
2828
{
29+
activation_priority 100;
30+
2931
[config] String host {
3032
default {{{ return "127.0.0.1"; }}}
3133
};

lib/perfdata/perfdatawriter.ti

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ namespace icinga
2727

2828
class PerfdataWriter : ConfigObject
2929
{
30+
activation_priority 100;
31+
3032
[config] String host_perfdata_path {
3133
default {{{ return Application::GetLocalStateDir() + "/spool/icinga2/perfdata/host-perfdata"; }}}
3234
};

lib/remote/apilistener.ti

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ namespace icinga
2828

2929
class ApiListener : ConfigObject
3030
{
31+
activation_priority 50;
32+
3133
[config, deprecated] String cert_path;
3234
[config, deprecated] String key_path;
3335
[config, deprecated] String ca_path;

tools/mkclass/class_lexer.ll

+2
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ class { return T_CLASS; }
135135
namespace { return T_NAMESPACE; }
136136
code { return T_CODE; }
137137
load_after { return T_LOAD_AFTER; }
138+
activation_priority { return T_ACTIVATION_PRIORITY; }
138139
library { return T_LIBRARY; }
139140
abstract { yylval->num = TAAbstract; return T_CLASS_ATTRIBUTE; }
140141
vararg_constructor { yylval->num = TAVarArgConstructor; return T_CLASS_ATTRIBUTE; }
@@ -164,6 +165,7 @@ navigate { yylval->num = FTNavigate; return T_FIELD_ACCESSOR_TYPE; }
164165
\"[^\"]+\" { yylval->text = strdup(yytext + 1); yylval->text[strlen(yylval->text) - 1] = '\0'; return T_STRING; }
165166
\<[^ \>]*\> { yylval->text = strdup(yytext + 1); yylval->text[strlen(yylval->text) - 1] = '\0'; return T_ANGLE_STRING; }
166167
[a-zA-Z_][:a-zA-Z0-9\-_]* { yylval->text = strdup(yytext); return T_IDENTIFIER; }
168+
-?[0-9]+(\.[0-9]+)? { yylval->num = strtod(yytext, NULL); return T_NUMBER; }
167169
168170
. return yytext[0];
169171

tools/mkclass/class_parser.yy

+12
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ using namespace icinga;
6161
%token T_CLASS "class (T_CLASS)"
6262
%token T_CODE "code (T_CODE)"
6363
%token T_LOAD_AFTER "load_after (T_LOAD_AFTER)"
64+
%token T_ACTIVATION_PRIORITY "activation_priority (T_ACTIVATION_PRIORITY)"
6465
%token T_LIBRARY "library (T_LIBRARY)"
6566
%token T_NAMESPACE "namespace (T_NAMESPACE)"
6667
%token T_VALIDATOR "validator (T_VALIDATOR)"
@@ -77,6 +78,7 @@ using namespace icinga;
7778
%token T_SET "set (T_SET)"
7879
%token T_DEFAULT "default (T_DEFAULT)"
7980
%token T_FIELD_ACCESSOR_TYPE "field_accessor_type (T_FIELD_ACCESSOR_TYPE)"
81+
%token T_NUMBER "number (T_NUMBER)"
8082
%type <text> T_IDENTIFIER
8183
%type <text> T_STRING
8284
%type <text> T_ANGLE_STRING
@@ -106,6 +108,7 @@ using namespace icinga;
106108
%type <rule> validator_rule
107109
%type <rules> validator_rules
108110
%type <validator> validator
111+
%type <num> T_NUMBER
109112

110113
%{
111114

@@ -250,6 +253,8 @@ class: class_attribute_list T_CLASS T_IDENTIFIER inherits_specifier type_base_sp
250253
for (const Field& field : *$7) {
251254
if (field.Attributes & FALoadDependency) {
252255
$$->LoadDependencies.push_back(field.Name);
256+
} else if (field.Attributes & FAActivationPriority) {
257+
$$->ActivationPriority = field.Priority;
253258
} else
254259
$$->Fields.push_back(field);
255260
}
@@ -380,6 +385,13 @@ class_field: field_attribute_list field_type identifier alternative_name_specifi
380385
std::free($2);
381386
$$ = field;
382387
}
388+
| T_ACTIVATION_PRIORITY T_NUMBER ';'
389+
{
390+
auto *field = new Field();
391+
field->Attributes = FAActivationPriority;
392+
field->Priority = $2;
393+
$$ = field;
394+
}
383395
;
384396

385397
alternative_name_specifier: /* empty */

tools/mkclass/classcompiler.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,14 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
408408
m_Impl << "\t" << "return deps;" << std::endl
409409
<< "}" << std::endl << std::endl;
410410

411+
/* GetActivationPriority */
412+
m_Header << "\t" << "int GetActivationPriority() const override;" << std::endl;
413+
414+
m_Impl << "int TypeImpl<" << klass.Name << ">::GetActivationPriority() const" << std::endl
415+
<< "{" << std::endl
416+
<< "\t" << "return " << klass.ActivationPriority << ";" << std::endl
417+
<< "}" << std::endl << std::endl;
418+
411419
/* RegisterAttributeHandler */
412420
m_Header << "public:" << std::endl
413421
<< "\t" << "void RegisterAttributeHandler(int fieldId, const Type::AttributeHandler& callback) override;" << std::endl;

tools/mkclass/classcompiler.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ enum FieldAttribute
7676
FANoUserView = 2048,
7777
FADeprecated = 4096,
7878
FAGetVirtual = 8192,
79-
FASetVirtual = 16384
79+
FASetVirtual = 16384,
80+
FAActivationPriority = 32768
8081
};
8182

8283
struct FieldType
@@ -122,6 +123,7 @@ struct Field
122123
std::string NavigationName;
123124
std::string NavigateAccessor;
124125
bool PureNavigateAccessor{false};
126+
int Priority{0};
125127

126128
inline std::string GetFriendlyName() const
127129
{
@@ -167,6 +169,7 @@ struct Klass
167169
int Attributes;
168170
std::vector<Field> Fields;
169171
std::vector<std::string> LoadDependencies;
172+
int ActivationPriority{0};
170173
};
171174

172175
enum RuleAttribute

0 commit comments

Comments
 (0)