]> granicus.if.org Git - icinga2/commitdiff
Add activation priorities for config object types 6270/head
authorJean Flach <jean-marcel.flach@icinga.com>
Thu, 26 Apr 2018 13:53:11 +0000 (15:53 +0200)
committerMichael Friedrich <michael.friedrich@icinga.com>
Fri, 4 May 2018 09:25:47 +0000 (11:25 +0200)
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

25 files changed:
lib/base/filelogger.ti
lib/base/sysloglogger.ti
lib/base/type.cpp
lib/base/type.hpp
lib/checker/checkercomponent.ti
lib/compat/checkresultreader.ti
lib/compat/compatlogger.ti
lib/compat/externalcommandlistener.ti
lib/compat/statusdatawriter.ti
lib/config/configitem.cpp
lib/db_ido_mysql/idomysqlconnection.ti
lib/db_ido_pgsql/idopgsqlconnection.ti
lib/livestatus/livestatuslistener.ti
lib/notification/notificationcomponent.ti
lib/perfdata/elasticsearchwriter.ti
lib/perfdata/gelfwriter.ti
lib/perfdata/graphitewriter.ti
lib/perfdata/influxdbwriter.ti
lib/perfdata/opentsdbwriter.ti
lib/perfdata/perfdatawriter.ti
lib/remote/apilistener.ti
tools/mkclass/class_lexer.ll
tools/mkclass/class_parser.yy
tools/mkclass/classcompiler.cpp
tools/mkclass/classcompiler.hpp

index daaad69707fe906f6cba02715cda64cf27fa0b42..f19b7c9d65067fb7a1c9e5988dfccc080e97d6fe 100644 (file)
@@ -26,6 +26,8 @@ namespace icinga
 
 class FileLogger : StreamLogger
 {
+       activation_priority -100;
+
        [config, required] String path;
 };
 
index ee639c25bfcb49aad9866cd84ba39f8abd590734..9ca92d637d612de72f3bf20f045ed0c8de3ce0a9 100644 (file)
@@ -26,6 +26,8 @@ namespace icinga
 
 class SyslogLogger : Logger
 {
+       activation_priority -100;
+
        [config] String facility {
                default {{{ return "LOG_USER"; }}}
        };
index 19f1bb5d943e2c02cb1e30eff21c95f7260dac6e..138269a87ec602a840c9f232b8ea9c09e9d3e4cc 100644 (file)
@@ -154,6 +154,11 @@ std::vector<String> Type::GetLoadDependencies() const
        return std::vector<String>();
 }
 
+int Type::GetActivationPriority() const
+{
+       return 0;
+}
+
 void Type::RegisterAttributeHandler(int fieldId, const AttributeHandler& callback)
 {
        throw std::runtime_error("Invalid field ID.");
index 10b8524fe448bff12264d2232ddc35446d7309b2..ef8ce6d231abbada0f6ea165037f2bdd2765a2d2 100644 (file)
@@ -103,6 +103,7 @@ public:
        Value GetField(int id) const override;
 
        virtual std::vector<String> GetLoadDependencies() const;
+       virtual int GetActivationPriority() const;
 
        typedef std::function<void (const Object::Ptr&, const Value&)> AttributeHandler;
        virtual void RegisterAttributeHandler(int fieldId, const AttributeHandler& callback);
index 119e44252559ab326679e48104128f3b59bce21c..8d74f1216be662ed23e2ba12c017e6c9d3fc4fc2 100644 (file)
@@ -26,6 +26,8 @@ namespace icinga
 
 class CheckerComponent : ConfigObject
 {
+       activation_priority 100;
+
        [config] int concurrent_checks {
                get {{{
                        return Application::GetMaxConcurrentChecks();
index 96143bc990f3c794198c3000b7131c087665313a..18b3d0ac4e7f55c23e630ea26c8efcbe82dbf2b9 100644 (file)
@@ -27,6 +27,8 @@ namespace icinga
 
 class CheckResultReader : ConfigObject
 {
+       activation_priority 100;
+
        [config] String spool_dir {
                default {{{ return Application::GetLocalStateDir() + "/lib/icinga2/spool/checkresults/"; }}}
        };
index c62471a07c6f794814d2e76569cf221e0f5a4518..322236cd848ff2a921e442c2f9b1e895fcafc64a 100644 (file)
@@ -27,6 +27,8 @@ namespace icinga
 
 class CompatLogger : ConfigObject
 {
+       activation_priority 100;
+
        [config] String log_dir {
                default {{{ return Application::GetLocalStateDir() + "/log/icinga2/compat"; }}}
        };
index fe4c433a0bc196aeb23d6cf48562b13a229f6787..baffb7f5111b19323c6c19e61d92bac4dc530637 100644 (file)
@@ -27,6 +27,8 @@ namespace icinga
 
 class ExternalCommandListener : ConfigObject
 {
+       activation_priority 100;
+
        [config] String command_path {
                default {{{ return Application::GetRunDir() + "/icinga2/cmd/icinga2.cmd"; }}}
        };
index f2d3d579ad78ed145632a6638e1f84ae94fe236e..5ac2969a914df976c7219daae0224a79968096f6 100644 (file)
@@ -27,6 +27,8 @@ namespace icinga
 
 class StatusDataWriter : ConfigObject
 {
+       activation_priority 100;
+
        [config] String status_path {
                default {{{ return Application::GetLocalStateDir() + "/cache/icinga2/status.dat"; }}}
        };
index 289bca67f21cd7cb9eef451696df72d616c14b3a..c790f8794eb3a8b54c782b3c0111d14820da34c6 100644 (file)
@@ -602,18 +602,35 @@ bool ConfigItem::ActivateItems(WorkQueue& upq, const std::vector<ConfigItem::Ptr
        if (!silent)
                Log(LogInformation, "ConfigItem", "Triggering Start signal for config items");
 
-       for (const ConfigItem::Ptr& item : newItems) {
-               if (!item->m_Object)
-                       continue;
+       /* Activate objects in priority order. */
+       std::vector<Type::Ptr> types = Type::GetAllTypes();
 
-               ConfigObject::Ptr object = item->m_Object;
+       std::sort(types.begin(), types.end(), [](const Type::Ptr& a, const Type::Ptr& b) {
+               if (a->GetActivationPriority() < b->GetActivationPriority())
+                       return true;
+               return false;
+       });
+
+       for (const Type::Ptr& type : types) {
+               for (const ConfigItem::Ptr& item : newItems) {
+                       if (!item->m_Object)
+                               continue;
+
+                       ConfigObject::Ptr object = item->m_Object;
+                       Type::Ptr objectType = object->GetReflectionType();
+
+                       if (objectType != type)
+                               continue;
 
 #ifdef I2_DEBUG
-               Log(LogDebug, "ConfigItem")
-                       << "Activating object '" << object->GetName() << "' of type '" << object->GetReflectionType()->GetName() << "'";
+                       Log(LogDebug, "ConfigItem")
+                               << "Activating object '" << object->GetName() << "' of type '"
+                               << objectType->GetName() << "' with priority '"
+                               << objectType->GetActivationPriority();
 #endif /* I2_DEBUG */
 
-               object->Activate(runtimeCreated);
+                       object->Activate(runtimeCreated);
+               }
        }
 
        upq.Join();
index c3449093554f5f9caa9ebde2a567fc75497cb432..8a70d5668ec3a245c1f86aafa7915c8a8ea31e18 100644 (file)
@@ -26,6 +26,8 @@ namespace icinga
 
 class IdoMysqlConnection : DbConnection
 {
+       activation_priority 100;
+
        [config] String host {
                default {{{ return "localhost"; }}}
        };
index a4657c0b1ee39544f40769bdc3f873615c8a3e65..ef7cf6ccb2af32be22df0b14e82ae237606eb6e0 100644 (file)
@@ -26,6 +26,8 @@ namespace icinga
 
 class IdoPgsqlConnection : DbConnection
 {
+       activation_priority 100;
+
        [config] String host {
                default {{{ return "localhost"; }}}
        };
index 576c04bfa4b5cadc68fc53f33f0bbfda0885e609..0742a6fb53898544632ce58f3d1580ea1110fdde 100644 (file)
@@ -26,6 +26,8 @@ namespace icinga
 {
 
 class LivestatusListener : ConfigObject {
+       activation_priority 100;
+
        [config] String socket_type {
                default {{{ return "unix"; }}}
        };
index 00852e6105e2343ff2dda6afb8f4f8cd95b08ee9..547528d1e5d2d9584ca1f93651beb5310fed6f20 100644 (file)
@@ -26,6 +26,8 @@ namespace icinga
 
 class NotificationComponent : ConfigObject
 {
+       activation_priority 100;
+
        [config] bool enable_ha (EnableHA) {
                default {{{ return true; }}}
        };
index 6961b426409b4fa78e6910475878fe346fbc1cd7..2bbdd9d6a0ca367d866a2ea38d892ff8ef1978b9 100644 (file)
@@ -7,6 +7,8 @@ namespace icinga
 
 class ElasticsearchWriter : ConfigObject
 {
+       activation_priority 100;
+
        [config, required] String host {
                default {{{ return "127.0.0.1"; }}}
        };
index 522d527e98b99401290c354611a4c0cde1d7985f..facc94a6da63ecbfee531b6f59518b8fd4b72d11 100644 (file)
@@ -26,6 +26,8 @@ namespace icinga
 
 class GelfWriter : ConfigObject
 {
+       activation_priority 100;
+
        [config] String host {
                default {{{ return "127.0.0.1"; }}}
        };
index 9b1fc2529d2974df40938b50ada55755a4bd72d2..ca04959f53aa380f6213fd3079a4d97211e5a1bc 100644 (file)
@@ -26,6 +26,8 @@ namespace icinga
 
 class GraphiteWriter : ConfigObject
 {
+       activation_priority 100;
+
        [config] String host {
                default {{{ return "127.0.0.1"; }}}
        };
index f2906614f9101f211396eb71c2e2774a8d03b348..5ff11675485a35a399a3da7f958d544b63c542a0 100644 (file)
@@ -26,6 +26,8 @@ namespace icinga
 
 class InfluxdbWriter : ConfigObject
 {
+       activation_priority 100;
+
        [config, required] String host {
                default {{{ return "127.0.0.1"; }}}
        };
index 7e2844ead7037ec7ccd513df07050787830bd531..ea9455b9e25dfc653e1ca94415dc0db063f37239 100644 (file)
@@ -26,6 +26,8 @@ namespace icinga
 
 class OpenTsdbWriter : ConfigObject
 {
+       activation_priority 100;
+
        [config] String host {
                default {{{ return "127.0.0.1"; }}}
        };
index 769a04431c88313adb0550b6d502914b6aa9521e..c0988f339f38b417a11274a4fd37c413f77807c0 100644 (file)
@@ -27,6 +27,8 @@ namespace icinga
 
 class PerfdataWriter : ConfigObject
 {
+       activation_priority 100;
+
        [config] String host_perfdata_path {
                default {{{ return Application::GetLocalStateDir() + "/spool/icinga2/perfdata/host-perfdata"; }}}
        };
index e072fcd20ce61fbbbe904f511e2969a46d4737f6..e04fa01859e257b063e6cdcec511ea45b31e4bb4 100644 (file)
@@ -28,6 +28,8 @@ namespace icinga
 
 class ApiListener : ConfigObject
 {
+       activation_priority 50;
+
        [config, deprecated] String cert_path;
        [config, deprecated] String key_path;
        [config, deprecated] String ca_path;
index 939a950b8d184ec3d799695649853fc3eddc32b9..19c75b6267ff8002b60918e9d4f3b60f1cbc8f4c 100644 (file)
@@ -135,6 +135,7 @@ class                               { return T_CLASS; }
 namespace                      { return T_NAMESPACE; }
 code                           { return T_CODE; }
 load_after                     { return T_LOAD_AFTER; }
+activation_priority    { return T_ACTIVATION_PRIORITY; }
 library                                { return T_LIBRARY; }
 abstract                       { yylval->num = TAAbstract; return T_CLASS_ATTRIBUTE; }
 vararg_constructor             { yylval->num = TAVarArgConstructor; return T_CLASS_ATTRIBUTE; }
@@ -164,6 +165,7 @@ navigate                    { yylval->num = FTNavigate; return T_FIELD_ACCESSOR_TYPE; }
 \"[^\"]+\"                     { yylval->text = strdup(yytext + 1); yylval->text[strlen(yylval->text) - 1] = '\0'; return T_STRING; }
 \<[^ \>]*\>                    { yylval->text = strdup(yytext + 1); yylval->text[strlen(yylval->text) - 1] = '\0'; return T_ANGLE_STRING; }
 [a-zA-Z_][:a-zA-Z0-9\-_]*      { yylval->text = strdup(yytext); return T_IDENTIFIER; }
+-?[0-9]+(\.[0-9]+)?            { yylval->num = strtod(yytext, NULL); return T_NUMBER; }
 
 .                              return yytext[0];
 
index 2165549eb882b5bbdcd858ae246bbf6fc980af1e..8f14ffc9de055b554b77a653dc3e8b09d86b0077 100644 (file)
@@ -61,6 +61,7 @@ using namespace icinga;
 %token T_CLASS "class (T_CLASS)"
 %token T_CODE "code (T_CODE)"
 %token T_LOAD_AFTER "load_after (T_LOAD_AFTER)"
+%token T_ACTIVATION_PRIORITY "activation_priority (T_ACTIVATION_PRIORITY)"
 %token T_LIBRARY "library (T_LIBRARY)"
 %token T_NAMESPACE "namespace (T_NAMESPACE)"
 %token T_VALIDATOR "validator (T_VALIDATOR)"
@@ -77,6 +78,7 @@ using namespace icinga;
 %token T_SET "set (T_SET)"
 %token T_DEFAULT "default (T_DEFAULT)"
 %token T_FIELD_ACCESSOR_TYPE "field_accessor_type (T_FIELD_ACCESSOR_TYPE)"
+%token T_NUMBER "number (T_NUMBER)"
 %type <text> T_IDENTIFIER
 %type <text> T_STRING
 %type <text> T_ANGLE_STRING
@@ -106,6 +108,7 @@ using namespace icinga;
 %type <rule> validator_rule
 %type <rules> validator_rules
 %type <validator> validator
+%type <num> T_NUMBER
 
 %{
 
@@ -250,6 +253,8 @@ class: class_attribute_list T_CLASS T_IDENTIFIER inherits_specifier type_base_sp
                for (const Field& field : *$7) {
                        if (field.Attributes & FALoadDependency) {
                                $$->LoadDependencies.push_back(field.Name);
+                       } else if (field.Attributes & FAActivationPriority) {
+                               $$->ActivationPriority = field.Priority;
                        } else
                                $$->Fields.push_back(field);
                }
@@ -380,6 +385,13 @@ class_field: field_attribute_list field_type identifier alternative_name_specifi
                std::free($2);
                $$ = field;
        }
+       | T_ACTIVATION_PRIORITY T_NUMBER ';'
+       {
+               auto *field = new Field();
+               field->Attributes = FAActivationPriority;
+               field->Priority = $2;
+               $$ = field;
+       }
        ;
 
 alternative_name_specifier: /* empty */
index 1899e6d296ecdd52f25063754f4489d9c6470159..374c54d1cb856ce34a20b6dafb23511a5be9e727 100644 (file)
@@ -408,6 +408,14 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
        m_Impl << "\t" << "return deps;" << std::endl
                << "}" << std::endl << std::endl;
 
+       /* GetActivationPriority */
+       m_Header << "\t" << "int GetActivationPriority() const override;" << std::endl;
+
+       m_Impl << "int TypeImpl<" << klass.Name << ">::GetActivationPriority() const" << std::endl
+               << "{" << std::endl
+               << "\t" << "return " << klass.ActivationPriority << ";" << std::endl
+               << "}" << std::endl << std::endl;
+
        /* RegisterAttributeHandler */
        m_Header << "public:" << std::endl
                        << "\t" << "void RegisterAttributeHandler(int fieldId, const Type::AttributeHandler& callback) override;" << std::endl;
index 3f0e7d4ea912766aa6720979b0227b09331856fe..e2124645d9d3796bc5ea1b7a2b1281559e71286f 100644 (file)
@@ -76,7 +76,8 @@ enum FieldAttribute
        FANoUserView = 2048,
        FADeprecated = 4096,
        FAGetVirtual = 8192,
-       FASetVirtual = 16384
+       FASetVirtual = 16384,
+       FAActivationPriority = 32768
 };
 
 struct FieldType
@@ -122,6 +123,7 @@ struct Field
        std::string NavigationName;
        std::string NavigateAccessor;
        bool PureNavigateAccessor{false};
+       int Priority{0};
 
        inline std::string GetFriendlyName() const
        {
@@ -167,6 +169,7 @@ struct Klass
        int Attributes;
        std::vector<Field> Fields;
        std::vector<std::string> LoadDependencies;
+       int ActivationPriority{0};
 };
 
 enum RuleAttribute